<commit_before>// Copyright (c) 2012, Ilya Arefiev <arefiev.id@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the
//    distribution.
//  * Neither the name of the author nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include    <iostream>

#include    "libqtlogger_common.h"
#include    "libqtlogger.h"

QtLogger::QtLogger()
    : currentLevel( LL_DEBUG )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif

    ll_string[ LL_EROR      ].sprintf( "ERROR" );
    ll_string[ LL_WARNING   ].sprintf( "WARN " );
    ll_string[ LL_LOG       ].sprintf( "LOG  " );
    ll_string[ LL_DEBUG     ].sprintf( "DEBUG" );

    ll_string[ LL_STUB      ].sprintf( "     " );

    this->start();
}

QtLogger::~QtLogger()
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif

    mqMutex.lock();
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " messageQueue size: "
            << messageQueue.size()
            << std::endl;
#endif
    messageQueue.clear();
    shutdown = true;

    mqWait.wakeAll();
    mqMutex.unlock();

    this->wait();

    while ( !writersList.isEmpty() )
    {
        delete( writersList.front() );
        writersList.pop_front();
    }
}

QtLogger& QtLogger::getInstance()
{
    static QtLogger _instance;

    return _instance;
}

void QtLogger::foo( void* bar )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif
}

QString QtLogger::describeLogLevel(QtLogger::LOG_LEVEL level)
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " level: "
            << level
            << " ("
            << ll_string[((level>=0 && level<=LL_STUB)?level:LL_STUB)].toStdString()
            << ")"
            << std::endl;
#endif

    return ll_string[ ((level>=0 && level<=LL_STUB) ? level : LL_STUB) ];
}

/**
 *
 */
void QtLogger::run()
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " start"
            << std::endl;
#endif

    QString message;

    while ( !shutdown )
    {
#if ENABLE_LOGGER_LOGGING
        std::clog << FUNCTION_NAME
                << " waiting"
                << std::endl;
#endif
        mqMutex.lock();
        mqWait.wait( &mqMutex );
#if ENABLE_LOGGER_LOGGING
        std::clog << FUNCTION_NAME
                << " woken"
                << std::endl;
#endif
        if ( !messageQueue.isEmpty() )
        {
            message = messageQueue.dequeue();
        }
#if ENABLE_LOGGER_LOGGING
        else
        {
            std::clog << FUNCTION_NAME
                    << " queue already empty"
                    << std::endl;
        }
#endif
        mqMutex.unlock();

        while ( !message.isEmpty() )
        {
#if ENABLE_LOGGER_LOGGING
            std::clog << FUNCTION_NAME
                    << " pass message \""
                    << message.toStdString()
                    << "\" to writers"
                    << std::endl;
#endif

            wlMutex.lock();
            if ( !writersList.isEmpty() )
            {
                QListIterator<LogWriterInterface*> iter( writersList );
                while ( iter.hasNext() )
                {
                    LogWriterInterface* writer = iter.next();
                    bool status = writer->writeLog( message );

#if ENABLE_LOGGER_LOGGING
                    std::clog << FUNCTION_NAME
                            << QString().sprintf( " writer @ %p returned %c",
                                                  writer,
                                                  (status?'t':'F')
                                                ).toStdString()
                            << std::endl;
#endif
                }
            }
            wlMutex.unlock();

            mqMutex.lock();
            if ( !messageQueue.isEmpty() )
            {
                message = messageQueue.dequeue();
            }
            else
            {
                message.clear();
            }
            mqMutex.unlock();
        }
    }

#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " end"
            << std::endl;
#endif

    this->quit();
}

bool QtLogger::addWriter( LogWriterInterface* writer )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " writer: "
            << (writer?(QString().sprintf( "%p", writer ).toStdString()):"(null)")
            << std::endl;
#endif

    if ( !writer )
    {
#if ENABLE_LOGGER_LOGGING
        std::cerr << FUNCTION_NAME
                << " NULL writer"
                << std::endl;
#endif
        return false;
    }

   wlMutex.lock();
   writersList.append( writer );

#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " wl.size: "
            << writersList.size()
            << std::endl;
#endif
    wlMutex.unlock();

    return true;
}

/**
 *
 */
void QtLogger::log(LOG_LEVEL level, QString message)
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " lvl: " << ll_string[ (level>=LL_STUB || level<0)?LL_STUB:level ].toStdString()
            << " msg: \"" << message.toStdString() << "\""
            << std::endl;
#endif

    if ( level >= LL_STUB ||
         level < 0
    ) {
#if ENABLE_LOGGER_LOGGING
        std::cerr << FUNCTION_NAME
                << "incorrect log level"
                << std::endl;
#endif
        return;
    }

    if ( level > currentLevel )
    {
#if ENABLE_LOGGER_LOGGING
        std::clog << FUNCTION_NAME
                << " log message rejected: currentLevel: "
                << ll_string[ currentLevel ].toStdString()
                << std::endl;
#endif
        return;
    }

    mqMutex.lock();
    messageQueue.enqueue( message );

#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " message queue size: "
            << messageQueue.size()
            << std::endl;
#endif

    mqWait.wakeAll();
    mqMutex.unlock();

    return;
}
<commit_msg>allow logger thread to cleanup messageQueue on destruction<commit_after>// Copyright (c) 2012, Ilya Arefiev <arefiev.id@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the
//    distribution.
//  * Neither the name of the author nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include    <iostream>

#include    "libqtlogger_common.h"
#include    "libqtlogger.h"

QtLogger::QtLogger()
    : currentLevel( LL_DEBUG )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif

    ll_string[ LL_EROR      ].sprintf( "ERROR" );
    ll_string[ LL_WARNING   ].sprintf( "WARN " );
    ll_string[ LL_LOG       ].sprintf( "LOG  " );
    ll_string[ LL_DEBUG     ].sprintf( "DEBUG" );

    ll_string[ LL_STUB      ].sprintf( "     " );

    this->start();
}

QtLogger::~QtLogger()
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif

    mqMutex.lock();
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " messageQueue size: "
            << messageQueue.size()
            << std::endl;
#endif
    shutdown = true;

    mqWait.wakeAll();
    mqMutex.unlock();

    this->wait();

    while ( !writersList.isEmpty() )
    {
        delete( writersList.front() );
        writersList.pop_front();
    }
}

QtLogger& QtLogger::getInstance()
{
    static QtLogger _instance;

    return _instance;
}

void QtLogger::foo( void* bar )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif
}

QString QtLogger::describeLogLevel(QtLogger::LOG_LEVEL level)
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " level: "
            << level
            << " ("
            << ll_string[((level>=0 && level<=LL_STUB)?level:LL_STUB)].toStdString()
            << ")"
            << std::endl;
#endif

    return ll_string[ ((level>=0 && level<=LL_STUB) ? level : LL_STUB) ];
}

/**
 *
 */
void QtLogger::run()
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " start"
            << std::endl;
#endif

    QString message;

    while ( !shutdown )
    {
#if ENABLE_LOGGER_LOGGING
        std::clog << FUNCTION_NAME
                << " waiting"
                << std::endl;
#endif
        mqMutex.lock();
        mqWait.wait( &mqMutex );
#if ENABLE_LOGGER_LOGGING
        std::clog << FUNCTION_NAME
                << " woken"
                << std::endl;
#endif
        if ( !messageQueue.isEmpty() )
        {
            message = messageQueue.dequeue();
        }
#if ENABLE_LOGGER_LOGGING
        else
        {
            std::clog << FUNCTION_NAME
                    << " queue already empty"
                    << std::endl;
        }
#endif
        mqMutex.unlock();

        while ( !message.isEmpty() )
        {
#if ENABLE_LOGGER_LOGGING
            std::clog << FUNCTION_NAME
                    << " pass message \""
                    << message.toStdString()
                    << "\" to writers"
                    << std::endl;
#endif

            wlMutex.lock();
            if ( !writersList.isEmpty() )
            {
                QListIterator<LogWriterInterface*> iter( writersList );
                while ( iter.hasNext() )
                {
                    LogWriterInterface* writer = iter.next();
                    bool status = writer->writeLog( message );

#if ENABLE_LOGGER_LOGGING
                    std::clog << FUNCTION_NAME
                            << QString().sprintf( " writer @ %p returned %c",
                                                  writer,
                                                  (status?'t':'F')
                                                ).toStdString()
                            << std::endl;
#endif
                }
            }
            wlMutex.unlock();

            mqMutex.lock();
            if ( !messageQueue.isEmpty() )
            {
                message = messageQueue.dequeue();
            }
            else
            {
                message.clear();
            }
            mqMutex.unlock();
        }
    }

#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " end"
            << std::endl;
#endif

    this->quit();
}

bool QtLogger::addWriter( LogWriterInterface* writer )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " writer: "
            << (writer?(QString().sprintf( "%p", writer ).toStdString()):"(null)")
            << std::endl;
#endif

    if ( !writer )
    {
#if ENABLE_LOGGER_LOGGING
        std::cerr << FUNCTION_NAME
                << " NULL writer"
                << std::endl;
#endif
        return false;
    }

   wlMutex.lock();
   writersList.append( writer );

#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " wl.size: "
            << writersList.size()
            << std::endl;
#endif
    wlMutex.unlock();

    return true;
}

/**
 *
 */
void QtLogger::log(LOG_LEVEL level, QString message)
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " lvl: " << ll_string[ (level>=LL_STUB || level<0)?LL_STUB:level ].toStdString()
            << " msg: \"" << message.toStdString() << "\""
            << std::endl;
#endif

    if ( level >= LL_STUB ||
         level < 0
    ) {
#if ENABLE_LOGGER_LOGGING
        std::cerr << FUNCTION_NAME
                << "incorrect log level"
                << std::endl;
#endif
        return;
    }

    if ( level > currentLevel )
    {
#if ENABLE_LOGGER_LOGGING
        std::clog << FUNCTION_NAME
                << " log message rejected: currentLevel: "
                << ll_string[ currentLevel ].toStdString()
                << std::endl;
#endif
        return;
    }

    mqMutex.lock();
    messageQueue.enqueue( message );

#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " message queue size: "
            << messageQueue.size()
            << std::endl;
#endif

    mqWait.wakeAll();
    mqMutex.unlock();

    return;
}
<|endoftext|>


<commit_before>#include "simulation/SerialSimulation.hpp"
//#include <omp.h>

namespace Simulation
{

    SerialSimulation::SerialSimulation(const Initialization::SimulationPlan & in, const vector<std::shared_ptr<Solver::ISolver>> & solvers)
            : AbstractSimulation(in,solvers)
    {
    }

    SerialSimulation::~SerialSimulation()
    {
    }

    void SerialSimulation::simulate()
    {
        bool_type running;  //MF only set, not used
        size_type iterationCount = 0;
        const vector<shared_ptr<Solver::ISolver>>& solver = getSolver();
        std::vector<size_type> numSteps(solver.size(),15);
        size_type tmpStepCount;
        double s (0.0) , e (0.0);
        //s = omp_get_wtime();
        while (running && getMaxIterations() > ++iterationCount)
        {
            running = false;
            for (size_type i = 0; i < solver.size(); ++i)
            {
                if((tmpStepCount = solver[i]->solve(numSteps[i])) == std::numeric_limits<size_type>::max())
                {
                    LOGGER_WRITE("Abort simulation at " + to_string(solver[i]->getCurrentTime()) , Util::LC_SOLVER, Util::LL_ERROR);
                    return;
                }
                if(tmpStepCount < numSteps[i])
                    --numSteps[i];
                else
                    ++numSteps[i];
                //LOGGER_WRITE("(" + to_string(i) + ") numSteps: " + to_string(numSteps[i]),Util::LC_SOLVER, Util::LL_ERROR);
                if (solver[i]->getCurrentTime() < getSimulationEndTime())
                    running = true;
                else
                    LOGGER_WRITE("(" + to_string(i) + ") Stopping at " + to_string(solver[i]->getCurrentTime()), Util::LC_SOLVER,Util::LL_DEBUG);
            }
        }
        //e = omp_get_wtime();
        LOGGER_WRITE("thread 0 time: " + to_string(e - s), Util::LC_SOLVER, Util::LL_INFO);
    }

    string_type SerialSimulation::getSimulationType() const
    {
        return "serial";
    }

} /* namespace Simulation */
<commit_msg>Make the boolean variable a bool<commit_after>#include "simulation/SerialSimulation.hpp"
//#include <omp.h>

namespace Simulation
{

    SerialSimulation::SerialSimulation(const Initialization::SimulationPlan & in, const vector<std::shared_ptr<Solver::ISolver>> & solvers)
            : AbstractSimulation(in,solvers)
    {
    }

    SerialSimulation::~SerialSimulation()
    {
    }

    void SerialSimulation::simulate()
    {
        bool running;
        size_type iterationCount = 0;
        const vector<shared_ptr<Solver::ISolver>>& solver = getSolver();
        std::vector<size_type> numSteps(solver.size(),15);
        size_type tmpStepCount;
        double s (0.0) , e (0.0);
        //s = omp_get_wtime();
        while (running && getMaxIterations() > ++iterationCount)
        {
            running = false;
            for (size_type i = 0; i < solver.size(); ++i)
            {
                if((tmpStepCount = solver[i]->solve(numSteps[i])) == std::numeric_limits<size_type>::max())
                {
                    LOGGER_WRITE("Abort simulation at " + to_string(solver[i]->getCurrentTime()) , Util::LC_SOLVER, Util::LL_ERROR);
                    return;
                }
                if(tmpStepCount < numSteps[i])
                    --numSteps[i];
                else
                    ++numSteps[i];
                //LOGGER_WRITE("(" + to_string(i) + ") numSteps: " + to_string(numSteps[i]),Util::LC_SOLVER, Util::LL_ERROR);
                if (solver[i]->getCurrentTime() < getSimulationEndTime())
                    running = true;
                else
                    LOGGER_WRITE("(" + to_string(i) + ") Stopping at " + to_string(solver[i]->getCurrentTime()), Util::LC_SOLVER,Util::LL_DEBUG);
            }
        }
        //e = omp_get_wtime();
        LOGGER_WRITE("thread 0 time: " + to_string(e - s), Util::LC_SOLVER, Util::LL_INFO);
    }

    string_type SerialSimulation::getSimulationType() const
    {
        return "serial";
    }

} /* namespace Simulation */
<|endoftext|>


<commit_before>#include <bits/stdc++.h>

#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(x) (x).begin(),(x).end()

using namespace std;

const vector<int> const_num = {5, 3, 2, 1};

int N;
vector<int> v;
string res;

vector<int> memo;
vector<string> memor;
map<vector<int>,int> se;

void dfs(int s, int c) {
  if (c + 1 < (int)v.size()) return;
  if (c < 0) return;
  if (c == 0 && (int)v.size() == 1) {
    int num = v[0];
    if (0 <= num && num <= N && memo[num] == -1) {
      memo[num] = s;
      memor[num] = res;
    }
    return;
  }
  if (se[v] >= c) return;
  se[v] = c;
  auto const_process = [](int s, int c, char n, string& res, vector<int>& v){
    res.push_back(n);
    dfs(s, c);
    v.pop_back();
    res.pop_back();
  };
  for (int i : const_num) {
    v.push_back(i);
    const_process(s, c - i, '0' + i, res, v);
  }
  if (1 <= (int)v.size()) {
    int num = v.back();
    v.push_back(num);
    const_process(s, c - 1, 'd', res, v);
  }
  auto binary_pop = [](vector<int>& v) -> tuple<int, int> {
    int lhs = v[v.size() - 2];
    int rhs = v[v.size() - 1];
    v.pop_back();
    v.pop_back();
    return make_tuple(lhs, rhs);
  };
  auto binary_process = [](int s, int c, int n, char op, string& res, vector<int>& v){
    v.push_back(n);
    res.push_back(op);
    dfs(s, c);
  };
  auto binary_push = [](int lhs, int rhs, string& res, vector<int>& v){
    v.pop_back();
    v.push_back(lhs);
    v.push_back(rhs);
    res.pop_back();
  };
  if (2 <= (int)v.size()) {
    int lhs = 0, rhs = 0;
    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, lhs + rhs, '+', res, v);
    binary_push(lhs, rhs, res, v);

    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, lhs * rhs > 3e4 ? 0 : lhs * rhs, '*', res, v);
    binary_push(lhs, rhs, res, v);

    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, lhs - rhs, '-', res, v);
    binary_push(lhs, rhs, res, v);

    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, rhs == 0 ? 0 : lhs / rhs, '/', res, v);
    binary_push(lhs, rhs, res, v);
    /*
    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, rhs == 0 ? 0 : lhs % rhs, '%', res, v);
    binary_push(lhs, rhs, res, v);
    */
  }
}

int main() {
  N = 100000;
  memo.assign(N+1, -1);
  memor.resize(N+1);
  int depth = 0;
  for (int n = 1; n <= N; ++n) {
    while (memo[n] == -1) {
      if (n > 100 && depth == memo[n-1] + 2) {
        memo[n] = memo[n-1] + 2;
        memor[n] = memor[n-1] + "1+";
      }
      else if (n > 100 && depth == memo[n-2] + 3) {
        memo[n] = memo[n-2] + 3;
        memor[n] = memor[n-2] + "2+";
      }
      else if (n > 100 && depth == memo[n+1] + 2) {
        memo[n] = memo[n+1] + 2;
        memor[n] = memor[n+1] + "1-";
      }
      else if (n > 100 && depth == memo[n+2] + 3) {
        memo[n] = memo[n+2] + 3;
        memor[n] = memor[n+2] + "2-";
      }
      else {
        if (depth == 22) break;
        cerr << "DEPTH : " << depth << endl;
        v.clear();
        res.clear();
        dfs(depth, depth);
        ++depth;
      }
    }
    cout << n << "\t";
    if (memo[n] == -1) {
      cout << "NULL" << endl;
    }
    else {
      cout << memo[n] << "\t";
      cout << memor[n] << endl;
    }
  }
  return 0;
}
<commit_msg>bug fix<commit_after>#include <bits/stdc++.h>

#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(x) (x).begin(),(x).end()

using namespace std;

const vector<int> const_num = {5, 3, 2, 1};

int N;
vector<int> v;
string res;

vector<int> memo;
vector<string> memor;
map<vector<int>,int> se;

void dfs(int s, int c) {
  if (c + 1 < (int)v.size()) return;
  if (c < 0) return;
  if (c == 0 && (int)v.size() == 1) {
    int num = v[0];
    if (0 <= num && num <= N && memo[num] == -1) {
      memo[num] = s;
      memor[num] = res;
    }
    return;
  }
  if (se[v] >= c) return;
  se[v] = c;
  auto const_process = [](int s, int c, char n, string& res, vector<int>& v){
    res.push_back(n);
    dfs(s, c);
    v.pop_back();
    res.pop_back();
  };
  for (int i : const_num) {
    v.push_back(i);
    const_process(s, c - i, '0' + i, res, v);
  }
  if (1 <= (int)v.size()) {
    int num = v.back();
    v.push_back(num);
    const_process(s, c - 1, 'd', res, v);
  }
  auto binary_pop = [](vector<int>& v) -> tuple<int, int> {
    int lhs = v[v.size() - 2];
    int rhs = v[v.size() - 1];
    v.pop_back();
    v.pop_back();
    return make_tuple(lhs, rhs);
  };
  auto binary_process = [](int s, int c, int n, char op, string& res, vector<int>& v){
    v.push_back(n);
    res.push_back(op);
    dfs(s, c);
  };
  auto binary_push = [](int lhs, int rhs, string& res, vector<int>& v){
    v.pop_back();
    v.push_back(lhs);
    v.push_back(rhs);
    res.pop_back();
  };
  if (2 <= (int)v.size()) {
    int lhs = 0, rhs = 0;
    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, lhs + rhs, '+', res, v);
    binary_push(lhs, rhs, res, v);

    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, abs((long long)lhs * rhs) > 1e9 ? 0 : lhs * rhs, '*', res, v);
    binary_push(lhs, rhs, res, v);

    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, lhs - rhs, '-', res, v);
    binary_push(lhs, rhs, res, v);

    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, rhs == 0 ? 0 : lhs / rhs, '/', res, v);
    binary_push(lhs, rhs, res, v);
    /*
    tie(lhs, rhs) = binary_pop(v);
    binary_process(s, c - 1, rhs == 0 ? 0 : lhs % rhs, '%', res, v);
    binary_push(lhs, rhs, res, v);
    */
  }
}

int main() {
  N = 1000;
  memo.assign(N+1, -1);
  memor.resize(N+1);
  int depth = 0;
  for (int n = 1; n <= N; ++n) {
    while (memo[n] == -1) {
      if (n > 100 && depth == memo[n-1] + 2) {
        memo[n] = memo[n-1] + 2;
        memor[n] = memor[n-1] + "1+";
      }
      else if (n > 100 && depth == memo[n-2] + 3) {
        memo[n] = memo[n-2] + 3;
        memor[n] = memor[n-2] + "2+";
      }
      else if (n > 100 && depth == memo[n+1] + 2) {
        memo[n] = memo[n+1] + 2;
        memor[n] = memor[n+1] + "1-";
      }
      else if (n > 100 && depth == memo[n+2] + 3) {
        memo[n] = memo[n+2] + 3;
        memor[n] = memor[n+2] + "2-";
      }
      else {
        if (depth == 23) break;
        cerr << "DEPTH : " << depth << endl;
        v.clear();
        res.clear();
        dfs(depth, depth);
        ++depth;
      }
    }
    cout << n << "\t";
    if (memo[n] == -1) {
      cout << "NULL" << endl;
    }
    else {
      cout << memo[n] << "\t";
      cout << memor[n] << endl;
    }
  }
  return 0;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

#include "Transform.h"
#include "ControlFlow.h"

namespace {

using RegMap = transform::RegMap;

void remap_debug(DexDebugInstruction& dbgop, const RegMap& reg_map) {
  switch (dbgop.opcode()) {
  case DBG_START_LOCAL:
  case DBG_START_LOCAL_EXTENDED:
  case DBG_END_LOCAL:
  case DBG_RESTART_LOCAL: {
    auto it = reg_map.find(dbgop.uvalue());
    if (it == reg_map.end()) return;
    dbgop.set_uvalue(it->second);
    break;
  }
  default:
    break;
  }
}

void remap_dest(IRInstruction* inst, const RegMap& reg_map) {
  if (!inst->dests_size()) return;
  auto it = reg_map.find(inst->dest());
  if (it == reg_map.end()) return;
  inst->set_dest(it->second);
}

void remap_srcs(IRInstruction* inst, const RegMap& reg_map) {
  for (unsigned i = 0; i < inst->srcs_size(); i++) {
    auto it = reg_map.find(inst->src(i));
    if (it == reg_map.end()) continue;
    inst->set_src(i, it->second);
  }
}

} // anonymous namespace

namespace transform {

void remap_registers(IRInstruction* insn, const RegMap& reg_map) {
  remap_dest(insn, reg_map);
  remap_srcs(insn, reg_map);

  if (opcode::has_range(insn->opcode())) {
    auto it = reg_map.find(insn->range_base());
    if (it != reg_map.end()) {
      insn->set_range_base(it->second);
    }
  }
}

void remap_registers(MethodItemEntry& mei, const RegMap& reg_map) {
  switch (mei.type) {
  case MFLOW_OPCODE:
    remap_registers(mei.insn, reg_map);
    break;
  case MFLOW_DEBUG:
    remap_debug(*mei.dbgop, reg_map);
    break;
  default:
    break;
  }
}

void remap_registers(IRCode* code, const RegMap& reg_map) {
  for (auto& mei : *code) {
    remap_registers(mei, reg_map);
  }
}

static size_t remove_block(IRCode* code, Block* b) {
  size_t insns_removed{0};
  for (auto& mei : InstructionIterable(b)) {
    code->remove_opcode(mei.insn);
    ++insns_removed;
  }
  return insns_removed;
}

void visit(Block* b, std::unordered_set<Block*>& visited) {
  if (visited.find(b) != visited.end()) {
    return;
  }
  visited.emplace(b);
  for (auto& s : b->succs()) {
    visit(s, visited);
  }
}

void remove_succ_edges(Block* b, ControlFlowGraph* cfg) {
  std::vector<std::pair<Block*, Block*>> remove_edges;
  for (auto& s : b->succs()) {
    remove_edges.emplace_back(b, s);
  }
  for (auto& p : remove_edges) {
    cfg->remove_all_edges(p.first, p.second);
  }
}

size_t remove_unreachable_blocks(IRCode* code) {
  auto& cfg = code->cfg();
  auto& blocks = cfg.blocks();
  size_t insns_removed{0};

  // remove unreachable blocks
  std::unordered_set<Block*> visited;
  visit(blocks.at(0), visited);
  for (size_t i = 1; i < blocks.size(); ++i) {
    auto& b = blocks.at(i);
    if (visited.find(b) != visited.end()) {
      continue;
    }
    // Remove all successor edges. Note that we don't need to try and remove
    // predecessors since by definition, unreachable blocks have no preds
    remove_succ_edges(b, &cfg);
    insns_removed += remove_block(code, b);
  }

  return insns_removed;
}

MethodItemEntry* find_active_catch(IRCode* code, FatMethod::iterator pos) {
  while (++pos != code->end() && pos->type != MFLOW_TRY)
    ;
  return pos != code->end() && pos->tentry->type == TRY_END
             ? pos->tentry->catch_start
             : nullptr;
}

// delete old_block and reroute its predecessors to new_block
//
// if new_block is null, just delete old_block and don't reroute
void replace_block(IRCode* code, Block* old_block, Block* new_block) {
  const ControlFlowGraph& cfg = code->cfg();
  std::vector<MethodItemEntry*> will_move;
  if (new_block != nullptr) {
    // make a copy of the targets we're going to move
    for (MethodItemEntry& mie : *old_block) {
      if (mie.type == MFLOW_TARGET) {
        will_move.push_back(new MethodItemEntry(mie.target));
      }
    }
  }

  // delete old_block
  for (auto it = old_block->begin(); it != old_block->end(); it++) {
    switch (it->type) {
    case MFLOW_OPCODE:
      code->remove_opcode(it);
      break;
    case MFLOW_TARGET:
      it->type = MFLOW_FALLTHROUGH;
      it->throwing_mie = nullptr;
      if (new_block == nullptr) {
        delete it->target;
      } // else, new_block takes ownership of the targets
      break;
    default:
      break;
    }
  }

  if (new_block != nullptr) {
    for (auto mie : will_move) {
      // insert the branch target at the beginning of new_block
      // and make sure `m_begin` and `m_end`s point to the right places
      Block* before = cfg.find_block_that_ends_here(new_block->m_begin);
      new_block->m_begin = code->insert_before(new_block->begin(), *mie);
      if (before != nullptr) {
        before->m_end = new_block->m_begin;
      }
    }
  }
}

} // namespace transform
<commit_msg>make transform::visit non-recursive<commit_after>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

#include "Transform.h"

#include <stack>

#include "ControlFlow.h"

namespace {

using RegMap = transform::RegMap;

void remap_debug(DexDebugInstruction& dbgop, const RegMap& reg_map) {
  switch (dbgop.opcode()) {
  case DBG_START_LOCAL:
  case DBG_START_LOCAL_EXTENDED:
  case DBG_END_LOCAL:
  case DBG_RESTART_LOCAL: {
    auto it = reg_map.find(dbgop.uvalue());
    if (it == reg_map.end()) return;
    dbgop.set_uvalue(it->second);
    break;
  }
  default:
    break;
  }
}

void remap_dest(IRInstruction* inst, const RegMap& reg_map) {
  if (!inst->dests_size()) return;
  auto it = reg_map.find(inst->dest());
  if (it == reg_map.end()) return;
  inst->set_dest(it->second);
}

void remap_srcs(IRInstruction* inst, const RegMap& reg_map) {
  for (unsigned i = 0; i < inst->srcs_size(); i++) {
    auto it = reg_map.find(inst->src(i));
    if (it == reg_map.end()) continue;
    inst->set_src(i, it->second);
  }
}

} // anonymous namespace

namespace transform {

void remap_registers(IRInstruction* insn, const RegMap& reg_map) {
  remap_dest(insn, reg_map);
  remap_srcs(insn, reg_map);

  if (opcode::has_range(insn->opcode())) {
    auto it = reg_map.find(insn->range_base());
    if (it != reg_map.end()) {
      insn->set_range_base(it->second);
    }
  }
}

void remap_registers(MethodItemEntry& mei, const RegMap& reg_map) {
  switch (mei.type) {
  case MFLOW_OPCODE:
    remap_registers(mei.insn, reg_map);
    break;
  case MFLOW_DEBUG:
    remap_debug(*mei.dbgop, reg_map);
    break;
  default:
    break;
  }
}

void remap_registers(IRCode* code, const RegMap& reg_map) {
  for (auto& mei : *code) {
    remap_registers(mei, reg_map);
  }
}

static size_t remove_block(IRCode* code, Block* b) {
  size_t insns_removed{0};
  for (auto& mei : InstructionIterable(b)) {
    code->remove_opcode(mei.insn);
    ++insns_removed;
  }
  return insns_removed;
}

void visit(Block* start, std::unordered_set<Block*>& visited) {
  std::stack<Block*> to_visit;
  to_visit.push(start);
  while (!to_visit.empty()) {
    Block* b = to_visit.top();
    to_visit.pop();

    if (visited.find(b) != visited.end()) {
      continue;
    }
    visited.emplace(b);

    for (auto& s : b->succs()) {
      to_visit.push(s);
    }
  }
}

void remove_succ_edges(Block* b, ControlFlowGraph* cfg) {
  std::vector<std::pair<Block*, Block*>> remove_edges;
  for (auto& s : b->succs()) {
    remove_edges.emplace_back(b, s);
  }
  for (auto& p : remove_edges) {
    cfg->remove_all_edges(p.first, p.second);
  }
}

size_t remove_unreachable_blocks(IRCode* code) {
  auto& cfg = code->cfg();
  auto& blocks = cfg.blocks();
  size_t insns_removed{0};

  // remove unreachable blocks
  std::unordered_set<Block*> visited;
  visit(blocks.at(0), visited);
  for (size_t i = 1; i < blocks.size(); ++i) {
    auto& b = blocks.at(i);
    if (visited.find(b) != visited.end()) {
      continue;
    }
    // Remove all successor edges. Note that we don't need to try and remove
    // predecessors since by definition, unreachable blocks have no preds
    remove_succ_edges(b, &cfg);
    insns_removed += remove_block(code, b);
  }

  return insns_removed;
}

MethodItemEntry* find_active_catch(IRCode* code, FatMethod::iterator pos) {
  while (++pos != code->end() && pos->type != MFLOW_TRY)
    ;
  return pos != code->end() && pos->tentry->type == TRY_END
             ? pos->tentry->catch_start
             : nullptr;
}

// delete old_block and reroute its predecessors to new_block
//
// if new_block is null, just delete old_block and don't reroute
void replace_block(IRCode* code, Block* old_block, Block* new_block) {
  const ControlFlowGraph& cfg = code->cfg();
  std::vector<MethodItemEntry*> will_move;
  if (new_block != nullptr) {
    // make a copy of the targets we're going to move
    for (MethodItemEntry& mie : *old_block) {
      if (mie.type == MFLOW_TARGET) {
        will_move.push_back(new MethodItemEntry(mie.target));
      }
    }
  }

  // delete old_block
  for (auto it = old_block->begin(); it != old_block->end(); it++) {
    switch (it->type) {
    case MFLOW_OPCODE:
      code->remove_opcode(it);
      break;
    case MFLOW_TARGET:
      it->type = MFLOW_FALLTHROUGH;
      it->throwing_mie = nullptr;
      if (new_block == nullptr) {
        delete it->target;
      } // else, new_block takes ownership of the targets
      break;
    default:
      break;
    }
  }

  if (new_block != nullptr) {
    for (auto mie : will_move) {
      // insert the branch target at the beginning of new_block
      // and make sure `m_begin` and `m_end`s point to the right places
      Block* before = cfg.find_block_that_ends_here(new_block->m_begin);
      new_block->m_begin = code->insert_before(new_block->begin(), *mie);
      if (before != nullptr) {
        before->m_end = new_block->m_begin;
      }
    }
  }
}

} // namespace transform
<|endoftext|>


<commit_before>#include <iostream>
#include "TinyCL.hpp"

int main()
{
	// GPUのデバイスを取得する
	auto device = tcl::information.GetGPU();

	// ソースコードのコンパイル
	tcl::CLSource source("test.cl", "test", tcl::SourceType::Text);

	// カーネル実行クラスの生成
	tcl::CLExecute exec(source, device);

	// デバイスに渡すための配列を初期化
	const size_t N = 10;
	std::vector<float> input(N);
	for (int i = 0; i < N; ++i)
		input[i] = i;

	// デバイス側のメモリを確保
	tcl::CLReadWriteBuffer x(exec, input);

	// 並列実行したいカーネル（GPUクラスタ）の数を設定する
	// 1次元配列で，0からスタートし，N個の長さを持っていて，それをN個ごとに区切る
	auto settings = tcl::CLWorkGroupSettings(1, { 0 }, { N }, { N }).Optimize(device);

	// 引数を設定する
	exec.SetArg(x);

	// 設定を渡して実行
	exec.Run(settings);

	// デバイスのメモリから，配列へ読み出す
	x.Read(input);

	// かくにん
	for (int i = 0; i < N; ++i)
		std::cout << i << "," << input[i] << std::endl;

	// TODO: 速度を取ってみたい

	char a;
	std::cin >> a;
}
<commit_msg>サンプルコードを短くする<commit_after>#include <iostream>
#include "TinyCL.hpp"

int main()
{
	// GPUのデバイスを取得する
	auto device = tcl::information.GetGPU();

	// ソースコードのコンパイル
	tcl::CLSource source("test.cl", "test", tcl::SourceType::Text);

	// カーネル実行クラスの生成
	tcl::CLExecute exec(source, device);

	// デバイスに渡すための配列を初期化
	const size_t N = 10;
	std::vector<float> input(N);
	for (int i = 0; i < N; ++i)
		input[i] = i;

	// デバイス側のメモリを確保
	tcl::CLReadWriteBuffer x(exec, input);

	// 並列実行したいカーネル（GPUクラスタ）の数を設定する
	// 1次元配列で，0からスタートし，N個の長さを持っていて，それをN個ごとに区切る
	auto settings = tcl::CLWorkGroupSettings(1, { 0 }, { N }, { N }).Optimize(device);

	// 引数を設定して実行
	exec.SetArg(x).Run(settings);

	// デバイスのメモリから，配列へ読み出す
	x.Read(input);

	// 中身が正しいかどうか確認する
	for (int i = 0; i < N; ++i)
		std::cout << i << "," << input[i] << std::endl;

	// TODO: 速度を取ってみたい

	char a;
	std::cin >> a;
}
<|endoftext|>


<commit_before>// ========================================================================== //
// This file is part of DO++, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2013 David Ok <david.ok8@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 <DO/Features.hpp>
#include <DO/Graphics.hpp>
#include <DO/ImageProcessing.hpp>

using namespace DO;
using namespace std;

const bool draw_feature_center_only = false;
const Rgb8& c = Cyan8;

void check_affine_adaptation(const Image<unsigned char>& image,
                             const OERegion& f)
{
  int w = image.width();
  int h = image.height();
  display(image);
  f.draw(Blue8);

  Image<float> flt_image(image.convert<float>());

  float r = 100;
  float patchSz = 2*r;
  Image<float> patch(w, h);
  patch.array().fill(0.f);

  OERegion rg(f);
  rg.center().fill(patchSz/2.f);
  rg.orientation() = 0.f;
  rg.shape_matrix() = Matrix2f::Identity()*4.f / (r*r);

  Matrix3d A(f.affinity().cast<double>());
  cout << "A=\n" << A << endl;

  for (int y = 0; y < patchSz; ++y)
  {
    float v = 2*(y-r)/r;
    for (int x = 0; x < patchSz; ++x)
    {
      float u = 2*(x-r)/r;
      Point3d pp(u, v, 1.);
      pp = A*pp;

      Point2d p;
      p << pp(0), pp(1);

      if (p.x() < 0 || p.x() >= w || p.y() < 0 || p.y() >= h)
        continue;

      patch(x,y) = static_cast<float>(interpolate(flt_image, p));
    }
  }

  Window w1 = active_window();
  Window w2 = create_window(static_cast<int>(patchSz),
                            static_cast<int>(patchSz));
  set_active_window(w2);
  set_antialiasing();
  display(patch);
  rg.draw(Blue8);
  millisleep(1000);
  close_window(w2);

  millisleep(40);
  set_active_window(w1);
}

void read_features(const Image<unsigned char>& image,
                   const string& filepath)
{
  cout << "Reading DoG features... " << endl;
  vector<OERegion> features;
  DescriptorMatrix<float> descriptors;

  cout << "Reading keypoints..." << endl;
  read_keypoints(features, descriptors, filepath);

  for (int i = 0; i < 10; ++i)
    check_affine_adaptation(image, features[i]);

  string ext = filepath.substr(filepath.find_last_of("."), filepath.size());
  string name = filepath.substr(0, filepath.find_last_of("."));
  string copy_filepath = name + "_copy" + ext;
  write_keypoints(features, descriptors, name + "_copy" + ext);

  vector<OERegion> features2;
  DescriptorMatrix<float> descriptors2;
  cout << "Checking written file..." << endl;
  read_keypoints(features2, descriptors2, copy_filepath);

  cout << "Printing the 10 first keypoints..." << endl;
  for(size_t i = 0; i < 10; ++i)
    cout << features[i] << endl;

  // Draw features.
  cout << "Drawing features... ";
  display(image);
  draw_oe_regions(features, Red8);
  cout << "done!" << endl;
  millisleep(1000);
}

GRAPHICS_MAIN_SIMPLE()
{
  Image<unsigned char> I;
  load(I, src_path("obama_2.jpg"));

  set_active_window(create_window(I.width(), I.height()));
  set_antialiasing(active_window());
  read_features(I, src_path("test.dogkey"));
  read_features(I, src_path("test.haraffkey"));
  read_features(I, src_path("test.mserkey"));

  return 0;
}<commit_msg>MAINT: remove unused variable.<commit_after>// ========================================================================== //
// This file is part of DO++, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2013 David Ok <david.ok8@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 <DO/Features.hpp>
#include <DO/Graphics.hpp>
#include <DO/ImageProcessing.hpp>

using namespace DO;
using namespace std;

const Rgb8& c = Cyan8;

void check_affine_adaptation(const Image<unsigned char>& image,
                             const OERegion& f)
{
  int w = image.width();
  int h = image.height();
  display(image);
  f.draw(Blue8);

  Image<float> flt_image(image.convert<float>());

  float r = 100;
  float patchSz = 2*r;
  Image<float> patch(w, h);
  patch.array().fill(0.f);

  OERegion rg(f);
  rg.center().fill(patchSz/2.f);
  rg.orientation() = 0.f;
  rg.shape_matrix() = Matrix2f::Identity()*4.f / (r*r);

  Matrix3d A(f.affinity().cast<double>());
  cout << "A=\n" << A << endl;

  for (int y = 0; y < patchSz; ++y)
  {
    float v = 2*(y-r)/r;
    for (int x = 0; x < patchSz; ++x)
    {
      float u = 2*(x-r)/r;
      Point3d pp(u, v, 1.);
      pp = A*pp;

      Point2d p;
      p << pp(0), pp(1);

      if (p.x() < 0 || p.x() >= w || p.y() < 0 || p.y() >= h)
        continue;

      patch(x,y) = static_cast<float>(interpolate(flt_image, p));
    }
  }

  Window w1 = active_window();
  Window w2 = create_window(static_cast<int>(patchSz),
                            static_cast<int>(patchSz));
  set_active_window(w2);
  set_antialiasing();
  display(patch);
  rg.draw(Blue8);
  millisleep(1000);
  close_window(w2);

  millisleep(40);
  set_active_window(w1);
}

void read_features(const Image<unsigned char>& image,
                   const string& filepath)
{
  cout << "Reading DoG features... " << endl;
  vector<OERegion> features;
  DescriptorMatrix<float> descriptors;

  cout << "Reading keypoints..." << endl;
  read_keypoints(features, descriptors, filepath);

  for (int i = 0; i < 10; ++i)
    check_affine_adaptation(image, features[i]);

  string ext = filepath.substr(filepath.find_last_of("."), filepath.size());
  string name = filepath.substr(0, filepath.find_last_of("."));
  string copy_filepath = name + "_copy" + ext;
  write_keypoints(features, descriptors, name + "_copy" + ext);

  vector<OERegion> features2;
  DescriptorMatrix<float> descriptors2;
  cout << "Checking written file..." << endl;
  read_keypoints(features2, descriptors2, copy_filepath);

  cout << "Printing the 10 first keypoints..." << endl;
  for(size_t i = 0; i < 10; ++i)
    cout << features[i] << endl;

  // Draw features.
  cout << "Drawing features... ";
  display(image);
  draw_oe_regions(features, Red8);
  cout << "done!" << endl;
  millisleep(1000);
}

GRAPHICS_MAIN_SIMPLE()
{
  Image<unsigned char> I;
  load(I, src_path("obama_2.jpg"));

  set_active_window(create_window(I.width(), I.height()));
  set_antialiasing(active_window());
  read_features(I, src_path("test.dogkey"));
  read_features(I, src_path("test.haraffkey"));
  read_features(I, src_path("test.mserkey"));

  return 0;
}<|endoftext|>


<commit_before>#include "mex.h"
#include "opencv_matlab_interop.h"

#define PRINT_INPUTS

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    ASSERT_NUM_LHS_ARGS_EQ(1);
    ASSERT_NUM_

}
<commit_msg>Prediction done, and apparently working. bam!<commit_after>#include "mex.h"
#include "opencv_matlab_interop.h"

#define PRINT_INPUTS

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    ASSERT_NUM_LHS_ARGS_EQUALS(1);
    ASSERT_NUM_RHS_ARGS_EQUALS(2);

    //retrieve the pointer to the random forest
    CvRTrees *forest = (CvRTrees *)unpack_pointer(prhs[0]);

    //get the data which we need to predict on into opencv format
    CvMat* dataMtx = matlab_matrix_to_opencv_matrix(prhs[1]);
    CvMat sample; //this is used to point to each row, one at a time

    int numSamples = dataMtx->rows;
    mexPrintf("predicting on %d samples\n", numSamples);

    mxArray* output = mxCreateDoubleMatrix(numSamples, 1, mxREAL);
    double *outputData = (double *)mxGetPr(output);

    //
    for (unsigned int i=0; i<numSamples; i++) {
        cvGetRow(dataMtx, &sample, i);
        outputData[i] = (double)forest->predict(&sample);
    }

    plhs[0] = output;
    cvReleaseMat(&dataMtx);
}
<|endoftext|>


<commit_before>#include "../SDP_Solver.hxx"

// Create and initialize an SDPSolver for the given SDP and
// SDP_Solver_Parameters
SDP_Solver::SDP_Solver(const std::vector<boost::filesystem::path> &sdp_files,
                       const SDP_Solver_Parameters &parameters)
    : sdp(sdp_files), parameters(parameters), x(sdp.schur_block_sizes),
      X(sdp.psd_matrix_block_sizes), y(sdp.dual_objective_b.Height(), 1),
      Y(X), primal_residues(X),
      // FIXME: Maybe we can use schur_block_sizes() instead of making a copy?
      dual_residues(x)
{
  X.set_zero();
  Y.set_zero();
  for(auto &b : x.blocks)
    {
      Zero(b);
    }
  Zero(y);

  // X = \Omega_p I
  X.add_diagonal(parameters.initial_matrix_scale_primal);
  // Y = \Omega_d I
  Y.add_diagonal(parameters.initial_matrix_scale_dual);
}
<commit_msg>Use sdp.schur_block_sizes to setup SDP::dual_residues<commit_after>#include "../SDP_Solver.hxx"

// Create and initialize an SDPSolver for the given SDP and
// SDP_Solver_Parameters
SDP_Solver::SDP_Solver(const std::vector<boost::filesystem::path> &sdp_files,
                       const SDP_Solver_Parameters &parameters)
    : sdp(sdp_files), parameters(parameters), x(sdp.schur_block_sizes),
      X(sdp.psd_matrix_block_sizes), y(sdp.dual_objective_b.Height(), 1), Y(X),
      primal_residues(X), dual_residues(sdp.schur_block_sizes)
{
  X.set_zero();
  Y.set_zero();
  for(auto &b : x.blocks)
    {
      Zero(b);
    }
  Zero(y);

  // X = \Omega_p I
  X.add_diagonal(parameters.initial_matrix_scale_primal);
  // Y = \Omega_d I
  Y.add_diagonal(parameters.initial_matrix_scale_dual);
}
<|endoftext|>


<commit_before>#include <hrl_phri_2011/pc_utils.h>

int main(int argc, char **argv)
{
    ros::init(argc, argv, "pub_head");
    if(argc < 2 || argc > 5) {
        printf("Usage pub_head bag_file [topic] [frame] [rate]\n");
        return 1;
    }

    // Load bag
    rosbag::Bag bag;
    bag.open(std::string(argv[1]), rosbag::bagmode::Read);
    rosbag::View view(bag, rosbag::TopicQuery("/stitched_head"));

    PCRGB::Ptr pc_head(new PCRGB());
    BOOST_FOREACH(rosbag::MessageInstance const m, view) {
        sensor_msgs::PointCloud2::Ptr pc2 = m.instantiate<sensor_msgs::PointCloud2>();
        pcl::fromROSMsg(*pc2, *pc_head);
        break;
    }
    if(argc >= 4)
        pc_head->header.frame_id = argv[3];
    if(argc == 2)
        pubLoop(*pc_head, "/stitched_head");
    else if(argc == 3)
        pubLoop(*pc_head, argv[2]);
    else if(argc == 5)
        pubLoop(*pc_head, argv[2], atof(argv[4]));

    return 0;
}
<commit_msg>Fixed pub_head problems.<commit_after>#include <hrl_phri_2011/pc_utils.h>

int main(int argc, char **argv)
{
    ros::init(argc, argv, "pub_head");
    if(argc < 2 || argc > 5) {
        printf("Usage pub_head bag_file [topic] [frame] [rate]\n");
        return 1;
    }

    // Load bag
    rosbag::Bag bag;
    bag.open(std::string(argv[1]), rosbag::bagmode::Read);
    rosbag::View view(bag);

    PCRGB::Ptr pc_head(new PCRGB());
    BOOST_FOREACH(rosbag::MessageInstance const m, view) {
        sensor_msgs::PointCloud2::Ptr pc2 = m.instantiate<sensor_msgs::PointCloud2>();
        pcl::fromROSMsg(*pc2, *pc_head);
        break;
    }
    if(argc == 2)
        pubLoop(*pc_head, "/stitched_head");
    else if(argc == 3)
        pubLoop(*pc_head, std::string(argv[2]));
    else if(argc == 4) {
        pc_head->header.frame_id = std::string(argv[3]);
        pubLoop(*pc_head, std::string(argv[2]));
    }
    else if(argc == 5) {
        pc_head->header.frame_id = std::string(argv[3]);
        pubLoop(*pc_head, std::string(argv[2]), atof(argv[4]));
    }

    return 0;
}
<|endoftext|>


<commit_before>/*
 * camera.cpp
 *
 *  Created on: 2016年11月28日
 *      Author: zhuqian
 */

#include "camera.h"
#include "film.h"
Camera::Camera(const Transform& c2w, Float shutterOpen, Float shutterEnd,
		Film * f, const Medium* medium) :
		film(f), cameraToWorld(c2w), shutterOpen(shutterOpen), shutterEnd(
				shutterEnd), medium(medium){

}

float Camera::GenerateRayDifferential(const CameraSample &sample,
		RayDifferential *rd) const {
	float wt = GenerateRay(sample, rd);
	//生成x偏移射线
	CameraSample sshift = sample;
	++sshift.pFilm.x;
	Ray rx;
	float wtx = GenerateRay(sshift, &rx);
	if (wtx == 0) {
		return 0;
	}
	rd->ox = rx.o;
	rd->dx = rx.d;
	//生成y偏移射线
	--sshift.pFilm.x;
	++sshift.pFilm.y;
	Ray ry;
	float wty = GenerateRay(sshift, &ry);
	if (wty == 0) {
		return 0;
	}
	rd->oy = ry.o;
	rd->dy = ry.d;
	//设置射线为微分射线
	rd->hasDifferential = true;
	rd->medium = medium;
	return wt;
}

Spectrum Camera::We(const Ray& ray, Point2f* rasterPos) const {
	Assert(false);
	LError<<"Camera::We is not implemented.";
	return 0;
}

void Camera::Pdf_We(const Ray& ray, Float* posPdf, Float* dirPdf) const {
	Assert(false);
	LError<<"Camera::Pdf_We is not implemented.";
}

Spectrum Camera::Sample_Wi(const Interaction& ref, const Point2f&sample, Vector3f* wi, Float* pdf, Point2f* rasterPos, VisibilityTester* tester) const {
	Assert(false);
	LError<<"Camera::Sample_Wi is not implemented.";
	return 0;
}

ProjectiveCamera::ProjectiveCamera(const Transform& c2w, const Transform& c2s,
		const Bound2f& screenWindow,Float shutterOpen, Float shutterEnd,
		Float lensr, Float focald,  Film * f, const Medium* medium):
		Camera(c2w, shutterOpen, shutterEnd, f, medium) {
	_cameraToScreen = c2s; //投影矩阵
	_lensRadius = lensr;
	_focalDistance = focald;
	//从底往上看1.把screen的原点挪到00位置,然后你懂得
	_screenToRaster = Scale(Float(film->fullResolution.x),
			Float(film->fullResolution.y), 1.f)
			* Scale(
					1.0f
							/ (screenWindow.maxPoint.x
									- screenWindow.minPoint.x),
					1.0f
							/ (screenWindow.minPoint.y
									- screenWindow.maxPoint.y), 1.0f)
			* Translate(
					Vector3f(-screenWindow.minPoint.x,
							-screenWindow.maxPoint.y, 0.0f));
	_rasterToScreen = Inverse(_screenToRaster);
	_rasterToCamera = Inverse(_cameraToScreen) * _rasterToScreen;

}

<commit_msg>修正相机中的float类型为Float类型<commit_after>/*
 * camera.cpp
 *
 *  Created on: 2016年11月28日
 *      Author: zhuqian
 */

#include "camera.h"
#include "film.h"
Camera::Camera(const Transform& c2w, Float shutterOpen, Float shutterEnd,
		Film * f, const Medium* medium) :
		film(f), cameraToWorld(c2w), shutterOpen(shutterOpen), shutterEnd(
				shutterEnd), medium(medium){

}

Float Camera::GenerateRayDifferential(const CameraSample &sample,
		RayDifferential *rd) const {
	Float wt = GenerateRay(sample, rd);
	//生成x偏移射线
	CameraSample sshift = sample;
	++sshift.pFilm.x;
	Ray rx;
	Float wtx = GenerateRay(sshift, &rx);
	if (wtx == 0) {
		return 0;
	}
	rd->ox = rx.o;
	rd->dx = rx.d;
	//生成y偏移射线
	--sshift.pFilm.x;
	++sshift.pFilm.y;
	Ray ry;
	Float wty = GenerateRay(sshift, &ry);
	if (wty == 0) {
		return 0;
	}
	rd->oy = ry.o;
	rd->dy = ry.d;
	//设置射线为微分射线
	rd->hasDifferential = true;
	rd->medium = medium;
	return wt;
}

Spectrum Camera::We(const Ray& ray, Point2f* rasterPos) const {
	Assert(false);
	LError<<"Camera::We is not implemented.";
	return 0;
}

void Camera::Pdf_We(const Ray& ray, Float* posPdf, Float* dirPdf) const {
	Assert(false);
	LError<<"Camera::Pdf_We is not implemented.";
}

Spectrum Camera::Sample_Wi(const Interaction& ref, const Point2f&sample, Vector3f* wi, Float* pdf, Point2f* rasterPos, VisibilityTester* tester) const {
	Assert(false);
	LError<<"Camera::Sample_Wi is not implemented.";
	return 0;
}

ProjectiveCamera::ProjectiveCamera(const Transform& c2w, const Transform& c2s,
		const Bound2f& screenWindow,Float shutterOpen, Float shutterEnd,
		Float lensr, Float focald,  Film * f, const Medium* medium):
		Camera(c2w, shutterOpen, shutterEnd, f, medium) {
	_cameraToScreen = c2s; //投影矩阵
	_lensRadius = lensr;
	_focalDistance = focald;
	//从底往上看1.把screen的原点挪到00位置,然后你懂得
	_screenToRaster = Scale(Float(film->fullResolution.x),
			Float(film->fullResolution.y), 1.f)
			* Scale(
					1.0f
							/ (screenWindow.maxPoint.x
									- screenWindow.minPoint.x),
					1.0f
							/ (screenWindow.minPoint.y
									- screenWindow.maxPoint.y), 1.0f)
			* Translate(
					Vector3f(-screenWindow.minPoint.x,
							-screenWindow.maxPoint.y, 0.0f));
	_rasterToScreen = Inverse(_screenToRaster);
	_rasterToCamera = Inverse(_cameraToScreen) * _rasterToScreen;

}

<|endoftext|>


<commit_before>/**
   @copyright (C) 2017 Melexis N.V.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/

#include <M5Stack.h>
#include <Wire.h>

#include "MLX90640_I2C_Driver.h"

void MLX90640_I2CInit()
{

}

//Read a number of words from startAddress. Store into Data array.
//Returns 0 if successful, -1 if error
int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data)
{

  //Caller passes number of 'unsigned ints to read', increase this to 'bytes to read'
  uint16_t bytesRemaining = nWordsRead * 2;

  //It doesn't look like sequential read works. Do we need to re-issue the address command each time?

  uint16_t dataSpot = 0; //Start at beginning of array

  //Setup a series of chunked I2C_BUFFER_LENGTH byte reads
  while (bytesRemaining > 0)
  {
    Wire.beginTransmission(_deviceAddress);
    Wire.write(startAddress >> 8); //MSB
    Wire.write(startAddress & 0xFF); //LSB
    if (Wire.endTransmission(false) != 7) //Do not release bus
    {
      Serial.println("No ack read");
      return (0); //Sensor did not ACK
    }

    uint16_t numberOfBytesToRead = bytesRemaining;
    if (numberOfBytesToRead > I2C_BUFFER_LENGTH) numberOfBytesToRead = I2C_BUFFER_LENGTH;

    Wire.requestFrom((uint8_t)_deviceAddress, numberOfBytesToRead);
    if (Wire.available())
    {
      for (uint16_t x = 0 ; x < numberOfBytesToRead / 2; x++)
      {
        //Store data into array
        data[dataSpot] = Wire.read() << 8; //MSB
        data[dataSpot] |= Wire.read(); //LSB

        dataSpot++;
      }
    }

    bytesRemaining -= numberOfBytesToRead;

    startAddress += numberOfBytesToRead / 2;
  }

  return (0); //Success
}

//Set I2C Freq, in kHz
//MLX90640_I2CFreqSet(1000) sets frequency to 1MHz
void MLX90640_I2CFreqSet(int freq)
{
  //i2c.frequency(1000 * freq);
  Wire.setClock((long)1000 * freq);
}

//Write two bytes to a two byte address
int MLX90640_I2CWrite(uint8_t _deviceAddress, unsigned int writeAddress, uint16_t data)
{
  Wire.beginTransmission((uint8_t)_deviceAddress);
  Wire.write(writeAddress >> 8); //MSB
  Wire.write(writeAddress & 0xFF); //LSB
  Wire.write(data >> 8); //MSB
  Wire.write(data & 0xFF); //LSB
  if (Wire.endTransmission() != 0)
  {
    //Sensor did not ACK
    Serial.println("Error: Sensor did not ack");
    return (-1);
  }

  uint16_t dataCheck;
  MLX90640_I2CRead(_deviceAddress, writeAddress, 1, &dataCheck);
  if (dataCheck != data)
  {
    //Serial.println("The write request didn't stick");
    return -2;
  }

  return (0); //Success
}
<commit_msg>Update MLX90640_I2C_Driver.cpp (#117)<commit_after>/**
   @copyright (C) 2017 Melexis N.V.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/

#include <M5Stack.h>
#include <Wire.h>

#include "MLX90640_I2C_Driver.h"

void MLX90640_I2CInit()
{

}

//Read a number of words from startAddress. Store into Data array.
//Returns 0 if successful, -1 if error
int MLX90640_I2CRead(uint8_t _deviceAddress, unsigned int startAddress, unsigned int nWordsRead, uint16_t *data)
{

  //Caller passes number of 'unsigned ints to read', increase this to 'bytes to read'
  uint16_t bytesRemaining = nWordsRead * 2;

  //It doesn't look like sequential read works. Do we need to re-issue the address command each time?

  uint16_t dataSpot = 0; //Start at beginning of array

  //Setup a series of chunked I2C_BUFFER_LENGTH byte reads
  while (bytesRemaining > 0)
  {
    Wire.beginTransmission(_deviceAddress);
    Wire.write(startAddress >> 8); //MSB
    Wire.write(startAddress & 0xFF); //LSB
    if (Wire.endTransmission(false) != 0) //Do not release bus
    {
      Serial.println("No ack read");
      return (0); //Sensor did not ACK
    }

    uint16_t numberOfBytesToRead = bytesRemaining;
    if (numberOfBytesToRead > I2C_BUFFER_LENGTH) numberOfBytesToRead = I2C_BUFFER_LENGTH;

    Wire.requestFrom((uint8_t)_deviceAddress, numberOfBytesToRead);
    if (Wire.available())
    {
      for (uint16_t x = 0 ; x < numberOfBytesToRead / 2; x++)
      {
        //Store data into array
        data[dataSpot] = Wire.read() << 8; //MSB
        data[dataSpot] |= Wire.read(); //LSB

        dataSpot++;
      }
    }

    bytesRemaining -= numberOfBytesToRead;

    startAddress += numberOfBytesToRead / 2;
  }

  return (0); //Success
}

//Set I2C Freq, in kHz
//MLX90640_I2CFreqSet(1000) sets frequency to 1MHz
void MLX90640_I2CFreqSet(int freq)
{
  //i2c.frequency(1000 * freq);
  Wire.setClock((long)1000 * freq);
}

//Write two bytes to a two byte address
int MLX90640_I2CWrite(uint8_t _deviceAddress, unsigned int writeAddress, uint16_t data)
{
  Wire.beginTransmission((uint8_t)_deviceAddress);
  Wire.write(writeAddress >> 8); //MSB
  Wire.write(writeAddress & 0xFF); //LSB
  Wire.write(data >> 8); //MSB
  Wire.write(data & 0xFF); //LSB
  if (Wire.endTransmission() != 0)
  {
    //Sensor did not ACK
    Serial.println("Error: Sensor did not ack");
    return (-1);
  }

  uint16_t dataCheck;
  MLX90640_I2CRead(_deviceAddress, writeAddress, 1, &dataCheck);
  if (dataCheck != data)
  {
    //Serial.println("The write request didn't stick");
    return -2;
  }

  return (0); //Success
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include "shape_datasource.hpp"
#include "shape_featureset.hpp"
#include "shape_index_featureset.hpp"

#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/version.hpp>
#include <boost/algorithm/string.hpp>
#pragma GCC diagnostic pop

// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/make_unique.hpp>
#include <mapnik/util/fs.hpp>
#include <mapnik/global.hpp>
#include <mapnik/util/utf_conv_win.hpp>
#include <mapnik/boolean.hpp>
#include <mapnik/util/conversions.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/timer.hpp>
#include <mapnik/value_types.hpp>

// stl
#include <fstream>
#include <sstream>
#include <stdexcept>

DATASOURCE_PLUGIN(shape_datasource)

using mapnik::String;
using mapnik::Double;
using mapnik::Integer;
using mapnik::Boolean;
using mapnik::datasource_exception;
using mapnik::filter_in_box;
using mapnik::filter_at_point;
using mapnik::attribute_descriptor;

shape_datasource::shape_datasource(parameters const& params)
    : datasource (params),
      type_(datasource::Vector),
      file_length_(0),
      indexed_(false),
      row_limit_(*params.get<mapnik::value_integer>("row_limit",0)),
      desc_(shape_datasource::name(), *params.get<std::string>("encoding","utf-8"))
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::init");
#endif
    boost::optional<std::string> file = params.get<std::string>("file");
    if (!file) throw datasource_exception("Shape Plugin: missing <file> parameter");

    boost::optional<std::string> base = params.get<std::string>("base");
    if (base)
        shape_name_ = *base + "/" + *file;
    else
        shape_name_ = *file;

    boost::algorithm::ireplace_last(shape_name_,".shp","");
    if (!mapnik::util::exists(shape_name_ + ".shp"))
    {
        throw datasource_exception("Shape Plugin: shapefile '" + shape_name_ + ".shp' does not exist");
    }
    if (mapnik::util::is_directory(shape_name_ + ".shp"))
    {
        throw datasource_exception("Shape Plugin: shapefile '" + shape_name_ + ".shp' appears to be a directory not a file");
    }
    if (!mapnik::util::exists(shape_name_ + ".dbf"))
    {
        throw datasource_exception("Shape Plugin: shapefile '" + shape_name_ + ".dbf' does not exist");
    }

    try
    {
#ifdef MAPNIK_STATS
        mapnik::progress_timer __stats2__(std::clog, "shape_datasource::init(get_column_description)");
#endif

        std::unique_ptr<shape_io> shape_ref = std::make_unique<shape_io>(shape_name_);
        init(*shape_ref);
        for (int i=0;i<shape_ref->dbf().num_fields();++i)
        {
            field_descriptor const& fd = shape_ref->dbf().descriptor(i);
            std::string fld_name=fd.name_;
            switch (fd.type_)
            {
            case 'C': // character
            case 'D': // date
                desc_.add_descriptor(attribute_descriptor(fld_name, String));
                break;
            case 'L': // logical
                desc_.add_descriptor(attribute_descriptor(fld_name, Boolean));
                break;
            case 'N': // numeric
            case 'O': // double
            case 'F': // float
            {
                if (fd.dec_>0)
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,Double,false,8));
                }
                else
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,Integer,false,4));
                }
                break;
            }
            default:
                // I - long
                // G - ole
                // + - autoincrement
                // @ - timestamp
                // B - binary
                // l - long
                // M - memo
                MAPNIK_LOG_ERROR(shape) << "shape_datasource: Unknown type=" << fd.type_;
                break;
            }
        }
    }
    catch (datasource_exception const& ex)
    {
        MAPNIK_LOG_ERROR(shape) << "Shape Plugin: error processing field attributes, " << ex.what();
        throw;
    }
    catch (const std::exception& ex)
    {
        MAPNIK_LOG_ERROR(shape) << "Shape Plugin: error processing field attributes, " << ex.what();
        throw;
    }
    catch (...) // exception: pipe_select_interrupter: Too many open files
    {
        MAPNIK_LOG_ERROR(shape) << "Shape Plugin: error processing field attributes";
        throw;
    }

}

void shape_datasource::init(shape_io& shape)
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::init");
#endif

    //first read header from *.shp
    shape_file::record_type header(100);
    shape.shp().read_record(header);

    int file_code = header.read_xdr_integer();
    if (file_code != 9994)
    {
        std::ostringstream s;
        s << "Shape Plugin: wrong file code " << file_code;
        throw datasource_exception(s.str());
    }
    header.skip(5 * 4);
    file_length_ = header.read_xdr_integer();
    int version = header.read_ndr_integer();

    if (version != 1000)
    {
        std::ostringstream s;
        s << "Shape Plugin: nvalid version number " << version;
        throw datasource_exception(s.str());
    }

    shape_type_ = static_cast<shape_io::shapeType>(header.read_ndr_integer());
    if (shape_type_ == shape_io::shape_multipatch)
        throw datasource_exception("Shape Plugin: shapefile multipatch type is not supported");

    const double lox = header.read_double();
    const double loy = header.read_double();
    const double hix = header.read_double();
    const double hiy = header.read_double();
    extent_.init(lox, loy, hix, hiy);

#ifdef MAPNIK_LOG
    const double zmin = header.read_double();
    const double zmax = header.read_double();
    const double mmin = header.read_double();
    const double mmax = header.read_double();

    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: Z min/max=" << zmin << "," << zmax;
    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: M min/max=" << mmin << "," << mmax;
#endif

    // check if we have an index file around
    indexed_ = shape.has_index();
    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: Extent=" << extent_;
    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: File length=" << file_length_;
    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: Shape type=" << shape_type_;
}

shape_datasource::~shape_datasource() {}

const char * shape_datasource::name()
{
    return "shape";
}

datasource::datasource_t shape_datasource::type() const
{
    return type_;
}

layer_descriptor shape_datasource::get_descriptor() const
{
    return desc_;
}

featureset_ptr shape_datasource::features(query const& q) const
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::features");
#endif

    filter_in_box filter(q.get_bbox());
    if (indexed_)
    {
        std::unique_ptr<shape_io> shape_ptr = std::make_unique<shape_io>(shape_name_);
        return featureset_ptr
            (new shape_index_featureset<filter_in_box>(filter,
                                                       std::move(shape_ptr),
                                                       q.property_names(),
                                                       desc_.get_encoding(),
                                                       shape_name_,
                                                       row_limit_));
    }
    else
    {
        return std::make_shared<shape_featureset<filter_in_box> >(filter,
                                                                  shape_name_,
                                                                  q.property_names(),
                                                                  desc_.get_encoding(),
                                                                  row_limit_);
    }
}

featureset_ptr shape_datasource::features_at_point(coord2d const& pt, double tol) const
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::features_at_point");
#endif

    filter_at_point filter(pt,tol);
    // collect all attribute names
    auto const& desc = desc_.get_descriptors();
    std::set<std::string> names;

    for (auto const& attr_info : desc)
    {
        names.insert(attr_info.get_name());
    }

    if (indexed_)
    {
        std::unique_ptr<shape_io> shape_ptr = std::make_unique<shape_io>(shape_name_);
        return featureset_ptr
            (new shape_index_featureset<filter_at_point>(filter,
                                                         std::move(shape_ptr),
                                                         names,
                                                         desc_.get_encoding(),
                                                         shape_name_,
                                                         row_limit_));
    }
    else
    {
        return std::make_shared<shape_featureset<filter_at_point> >(filter,
                                                                    shape_name_,
                                                                    names,
                                                                    desc_.get_encoding(),
                                                                    row_limit_);
    }
}

box2d<double> shape_datasource::envelope() const
{
    return extent_;
}

boost::optional<mapnik::datasource_geometry_t> shape_datasource::get_geometry_type() const
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::get_geometry_type");
#endif

    boost::optional<mapnik::datasource_geometry_t> result;
    switch (shape_type_)
    {
    case shape_io::shape_point:
    case shape_io::shape_pointm:
    case shape_io::shape_pointz:
    case shape_io::shape_multipoint:
    case shape_io::shape_multipointm:
    case shape_io::shape_multipointz:
    {
        result.reset(mapnik::datasource_geometry_t::Point);
        break;
    }
    case shape_io::shape_polyline:
    case shape_io::shape_polylinem:
    case shape_io::shape_polylinez:
    {
        result.reset(mapnik::datasource_geometry_t::LineString);
        break;
    }
    case shape_io::shape_polygon:
    case shape_io::shape_polygonm:
    case shape_io::shape_polygonz:
    {
        result.reset(mapnik::datasource_geometry_t::Polygon);
        break;
    }
    default:
        break;
    }
    return result;
}
<commit_msg>remove redundant unique_ptr usage for local variable<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include "shape_datasource.hpp"
#include "shape_featureset.hpp"
#include "shape_index_featureset.hpp"

#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/version.hpp>
#include <boost/algorithm/string.hpp>
#pragma GCC diagnostic pop

// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/make_unique.hpp>
#include <mapnik/util/fs.hpp>
#include <mapnik/global.hpp>
#include <mapnik/util/utf_conv_win.hpp>
#include <mapnik/boolean.hpp>
#include <mapnik/util/conversions.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/timer.hpp>
#include <mapnik/value_types.hpp>

// stl
#include <fstream>
#include <sstream>
#include <stdexcept>

DATASOURCE_PLUGIN(shape_datasource)

using mapnik::String;
using mapnik::Double;
using mapnik::Integer;
using mapnik::Boolean;
using mapnik::datasource_exception;
using mapnik::filter_in_box;
using mapnik::filter_at_point;
using mapnik::attribute_descriptor;

shape_datasource::shape_datasource(parameters const& params)
    : datasource (params),
      type_(datasource::Vector),
      file_length_(0),
      indexed_(false),
      row_limit_(*params.get<mapnik::value_integer>("row_limit",0)),
      desc_(shape_datasource::name(), *params.get<std::string>("encoding","utf-8"))
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::init");
#endif
    boost::optional<std::string> file = params.get<std::string>("file");
    if (!file) throw datasource_exception("Shape Plugin: missing <file> parameter");

    boost::optional<std::string> base = params.get<std::string>("base");
    if (base)
        shape_name_ = *base + "/" + *file;
    else
        shape_name_ = *file;

    boost::algorithm::ireplace_last(shape_name_,".shp","");
    if (!mapnik::util::exists(shape_name_ + ".shp"))
    {
        throw datasource_exception("Shape Plugin: shapefile '" + shape_name_ + ".shp' does not exist");
    }
    if (mapnik::util::is_directory(shape_name_ + ".shp"))
    {
        throw datasource_exception("Shape Plugin: shapefile '" + shape_name_ + ".shp' appears to be a directory not a file");
    }
    if (!mapnik::util::exists(shape_name_ + ".dbf"))
    {
        throw datasource_exception("Shape Plugin: shapefile '" + shape_name_ + ".dbf' does not exist");
    }

    try
    {
#ifdef MAPNIK_STATS
        mapnik::progress_timer __stats2__(std::clog, "shape_datasource::init(get_column_description)");
#endif

        shape_io shape(shape_name_);
        init(shape);
        for (int i = 0; i < shape.dbf().num_fields(); ++i)
        {
            field_descriptor const& fd = shape.dbf().descriptor(i);
            std::string fld_name=fd.name_;
            switch (fd.type_)
            {
            case 'C': // character
            case 'D': // date
                desc_.add_descriptor(attribute_descriptor(fld_name, String));
                break;
            case 'L': // logical
                desc_.add_descriptor(attribute_descriptor(fld_name, Boolean));
                break;
            case 'N': // numeric
            case 'O': // double
            case 'F': // float
            {
                if (fd.dec_>0)
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,Double,false,8));
                }
                else
                {
                    desc_.add_descriptor(attribute_descriptor(fld_name,Integer,false,4));
                }
                break;
            }
            default:
                // I - long
                // G - ole
                // + - autoincrement
                // @ - timestamp
                // B - binary
                // l - long
                // M - memo
                MAPNIK_LOG_ERROR(shape) << "shape_datasource: Unknown type=" << fd.type_;
                break;
            }
        }
    }
    catch (datasource_exception const& ex)
    {
        MAPNIK_LOG_ERROR(shape) << "Shape Plugin: error processing field attributes, " << ex.what();
        throw;
    }
    catch (const std::exception& ex)
    {
        MAPNIK_LOG_ERROR(shape) << "Shape Plugin: error processing field attributes, " << ex.what();
        throw;
    }
    catch (...) // exception: pipe_select_interrupter: Too many open files
    {
        MAPNIK_LOG_ERROR(shape) << "Shape Plugin: error processing field attributes";
        throw;
    }

}

void shape_datasource::init(shape_io& shape)
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::init");
#endif

    //first read header from *.shp
    shape_file::record_type header(100);
    shape.shp().read_record(header);

    int file_code = header.read_xdr_integer();
    if (file_code != 9994)
    {
        std::ostringstream s;
        s << "Shape Plugin: wrong file code " << file_code;
        throw datasource_exception(s.str());
    }
    header.skip(5 * 4);
    file_length_ = header.read_xdr_integer();
    int version = header.read_ndr_integer();

    if (version != 1000)
    {
        std::ostringstream s;
        s << "Shape Plugin: nvalid version number " << version;
        throw datasource_exception(s.str());
    }

    shape_type_ = static_cast<shape_io::shapeType>(header.read_ndr_integer());
    if (shape_type_ == shape_io::shape_multipatch)
        throw datasource_exception("Shape Plugin: shapefile multipatch type is not supported");

    const double lox = header.read_double();
    const double loy = header.read_double();
    const double hix = header.read_double();
    const double hiy = header.read_double();
    extent_.init(lox, loy, hix, hiy);

#ifdef MAPNIK_LOG
    const double zmin = header.read_double();
    const double zmax = header.read_double();
    const double mmin = header.read_double();
    const double mmax = header.read_double();

    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: Z min/max=" << zmin << "," << zmax;
    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: M min/max=" << mmin << "," << mmax;
#endif

    // check if we have an index file around
    indexed_ = shape.has_index();
    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: Extent=" << extent_;
    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: File length=" << file_length_;
    MAPNIK_LOG_DEBUG(shape) << "shape_datasource: Shape type=" << shape_type_;
}

shape_datasource::~shape_datasource() {}

const char * shape_datasource::name()
{
    return "shape";
}

datasource::datasource_t shape_datasource::type() const
{
    return type_;
}

layer_descriptor shape_datasource::get_descriptor() const
{
    return desc_;
}

featureset_ptr shape_datasource::features(query const& q) const
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::features");
#endif

    filter_in_box filter(q.get_bbox());
    if (indexed_)
    {
        std::unique_ptr<shape_io> shape_ptr = std::make_unique<shape_io>(shape_name_);
        return featureset_ptr
            (new shape_index_featureset<filter_in_box>(filter,
                                                       std::move(shape_ptr),
                                                       q.property_names(),
                                                       desc_.get_encoding(),
                                                       shape_name_,
                                                       row_limit_));
    }
    else
    {
        return std::make_shared<shape_featureset<filter_in_box> >(filter,
                                                                  shape_name_,
                                                                  q.property_names(),
                                                                  desc_.get_encoding(),
                                                                  row_limit_);
    }
}

featureset_ptr shape_datasource::features_at_point(coord2d const& pt, double tol) const
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::features_at_point");
#endif

    filter_at_point filter(pt,tol);
    // collect all attribute names
    auto const& desc = desc_.get_descriptors();
    std::set<std::string> names;

    for (auto const& attr_info : desc)
    {
        names.insert(attr_info.get_name());
    }

    if (indexed_)
    {
        std::unique_ptr<shape_io> shape_ptr = std::make_unique<shape_io>(shape_name_);
        return featureset_ptr
            (new shape_index_featureset<filter_at_point>(filter,
                                                         std::move(shape_ptr),
                                                         names,
                                                         desc_.get_encoding(),
                                                         shape_name_,
                                                         row_limit_));
    }
    else
    {
        return std::make_shared<shape_featureset<filter_at_point> >(filter,
                                                                    shape_name_,
                                                                    names,
                                                                    desc_.get_encoding(),
                                                                    row_limit_);
    }
}

box2d<double> shape_datasource::envelope() const
{
    return extent_;
}

boost::optional<mapnik::datasource_geometry_t> shape_datasource::get_geometry_type() const
{
#ifdef MAPNIK_STATS
    mapnik::progress_timer __stats__(std::clog, "shape_datasource::get_geometry_type");
#endif

    boost::optional<mapnik::datasource_geometry_t> result;
    switch (shape_type_)
    {
    case shape_io::shape_point:
    case shape_io::shape_pointm:
    case shape_io::shape_pointz:
    case shape_io::shape_multipoint:
    case shape_io::shape_multipointm:
    case shape_io::shape_multipointz:
    {
        result.reset(mapnik::datasource_geometry_t::Point);
        break;
    }
    case shape_io::shape_polyline:
    case shape_io::shape_polylinem:
    case shape_io::shape_polylinez:
    {
        result.reset(mapnik::datasource_geometry_t::LineString);
        break;
    }
    case shape_io::shape_polygon:
    case shape_io::shape_polygonm:
    case shape_io::shape_polygonz:
    {
        result.reset(mapnik::datasource_geometry_t::Polygon);
        break;
    }
    default:
        break;
    }
    return result;
}
<|endoftext|>


<commit_before>
#include "cssysdef.h"
#include "cloth.h"
#include "igeom/polymesh.h"
#include "csgeom/math2d.h"
#include "csgeom/math3d.h"
#include "csgeom/tesselat.h"
#include "csutil/bitarray.h"
#include "imesh/object.h"
#include "imesh/clothmesh.h"
#include "iutil/eventh.h"
#include "iutil/comp.h"
#include "igeom/objmodel.h"
#include "ivideo/vbufmgr.h"

/*
bool Cloth::AddConstraint( int v0, int v1 , Constraint** edge )
{
	if (v0==v1)
	{
		*edge=NULL;
		return false;
	};
	Constraint* first;
	Constraint* p;
	p=first=(Constraint*)Edges->GetFirstItem();
	do
	{
		if ((p->v0==v0) || (p->v0==v1))
		{
			if ((p->v1==v0) || (p->v1==v1))
			{
				*edge=p;
				return false;
			};
		};
		p=(Constraint*)Edges->GetNextItem();
	} while (p!=first);
	p=new Constraint( v0 , v1 );
	Edges->AddItem( (void*) p );
	*edge=p;
	return true;
};*/

bool Cloth::AddConstraint ( int v0 , int v1 , Constraint** edge )
{
	if (v0==v1)
	{
		*edge=NULL;
		return false;
	};
	Constraint* p;
	int size    = Edges->Length();
	for (int i=0; i < size ; i++ )
	{
		p = (Constraint*) Edges -> Get( i );
		if ((p->v0==v0) || (p->v0==v1))
		{
			if ((p->v1==v0) || (p->v1==v1))
			{
				*edge=p;
				return false;
			};
		};
	};
	p=new Constraint( v0 , v1 );
	Edges -> Push ( (void*) p );
	*edge = p;
	return true;
};

Cloth::Cloth( iClothFactoryState* mesh,
         csVector3&    Sh,
         csBox3&       box,
         csVector3     grav )
{
	shift       = &Sh;
	object_bbox = &box;
	gravity     = grav;
	printf( " CREATING the cloth... \n");
	uint i;
	vertices  = NULL;
	triangles = NULL;
	printf( " CREATING the clothA... \n");
	csVector3* verts          = mesh->GetVertices     ();
	printf( " CREATING the clothB... \n");
	nverts                    = mesh->GetVertexCount  ();
	csTriangle* tris          = mesh->GetTriangles    ();
	uint	tri_count         = mesh->GetTriangleCount();

	//for (i = 0; i < polycnt ; i++)	{ tri_count += polygons[i].num_vertices - 2; };
			printf( " CREATING the cloth2... \n");
	Edges            = new csBasicVector( nverts , 16 );
	nedges           = 0;
	vertices         = new csVector3[ nverts ];

	for (i = 0; i < nverts ; i++)
	{
		vertices[i].Set( verts[i].x , verts[i].y , verts[i].z );
	};

	ntris            = 2*tri_count;   //here we care about double-facing the mesh
	triangles        = new csTriangle   [ ntris ];
	//memcpy ( triangles , tris , sizeof(csTriangle)*ntris );
	//Triangle2EdgeRef = new Constraint**    [ tri_count ];    this will be needed
	                                                       //  when 2nd neighbours are
                                                           //  considered
	//int* vidx;
	printf( " CREATING the cloth3... \n");
	int index=0;
	int tri;
	int v;
	Constraint* a;
	Constraint* b;
	Constraint* c;
	bool isNew;

	for (i=0; i<tri_count; i++)
	{
		triangles[ 2*i ].a = tris[i].a;
		triangles[ 2*i ].b = tris[i].b;
		triangles[ 2*i ].c = tris[i].c;

		triangles[ 2*i + 1 ].a = tris[i].a;
		triangles[ 2*i + 1 ].b = tris[i].c;
		triangles[ 2*i + 1 ].c = tris[i].b;

		isNew = AddConstraint( tris[i].a , tris[i].b , &a );
		if (isNew) 	{ a -> L0 =( verts[ tris[i].a ] - verts[ tris[i].b ] ).Norm();  nedges++; };

		isNew = AddConstraint( tris[i].b , tris[i].c , &b );
		if (isNew) { b -> L0 = ( verts[ tris[i].b ] - verts[ tris[i].c ] ).Norm(); nedges++; };

		isNew = AddConstraint( tris[i].c , tris[i].a , &c );
		if (isNew) { c -> L0 = ( verts[ tris[i].c ] - verts[ tris[i].a ] ).Norm(); nedges++; };
	};
		printf( " CREATING the cloth4... \n");
	/*
	for (i = 0; i<count ; i ++)
	{
		vidx  = p.vertices;
		tri   = 0;
		isNew = AddEdgeConstraint( vidx[0] , vidx[1] , &a );
		if (isNew) { a -> L0 =( verts[ vidx[0] ] - verts[ vidx[1] ] ).Norm();  nedges++; };
		for (v = 2; v < p.num_vertices; v++ , tri++  ) //triangulation
		{
			isNew = AddEdgeConstraint( vidx[v-1] , vidx[v] , &b );
			if (isNew) { b -> L0 = ( verts[ vidx[v-1] ] - verts[ vidx[v] ] ).Norm(); nedges++; };
			isNew = AddEdgeConstraint( vidx[v] , vidx[0] , &c );
			if (isNew) { c -> L0 = ( verts[ vidx[v] ] - verts[ vidx[0] ] ).Norm(); nedges++; };

				       no need to consider 2nd neighbours or dynamic refinement yet
			Triangle2EdgeRef[ index + tri ] = new Constraint*[ 3 ];
			Triangle2EdgeRef[ index + tri ][0] = a;
			Triangle2EdgeRef[ index + tri ][1] = b;
			Triangle2EdgeRef[ index + tri ][2] = c;

			triangles[ index + tri ].a = vidx[0];
			triangles[ index + tri ].b = vidx[v-1];
			triangles[ index + tri ].c = vidx[v];
			a = c;
		};
		index += (p.num_vertices - 2);
	};*/

}; // END Cloth::Cloth

Cloth::~Cloth()
{
	if (vertices)        { delete[] vertices; };
	if (triangles)       { delete[] triangles; };
	Constraint* p;
	//p=(Constraint*)Edges->GetFirstItem();
	p=(Constraint*)Edges->Pop();
	do
	{
		//Edges->RemoveItem( (void*) p );
		delete p;
		p=(Constraint*)Edges->Pop();
	} while (p!=NULL);
	delete Edges;
};

<commit_msg>small fix<commit_after>
#include "cssysdef.h"
#include "cloth.h"
#include "igeom/polymesh.h"
#include "csgeom/math2d.h"
#include "csgeom/math3d.h"
#include "csgeom/tesselat.h"
#include "csutil/bitarray.h"
#include "imesh/object.h"
#include "imesh/clothmesh.h"
#include "iutil/eventh.h"
#include "iutil/comp.h"
#include "igeom/objmodel.h"
#include "ivideo/vbufmgr.h"

/*
bool Cloth::AddConstraint( int v0, int v1 , Constraint** edge )
{
	if (v0==v1)
	{
		*edge=NULL;
		return false;
	};
	Constraint* first;
	Constraint* p;
	p=first=(Constraint*)Edges->GetFirstItem();
	do
	{
		if ((p->v0==v0) || (p->v0==v1))
		{
			if ((p->v1==v0) || (p->v1==v1))
			{
				*edge=p;
				return false;
			};
		};
		p=(Constraint*)Edges->GetNextItem();
	} while (p!=first);
	p=new Constraint( v0 , v1 );
	Edges->AddItem( (void*) p );
	*edge=p;
	return true;
};*/

bool Cloth::AddConstraint ( int v0 , int v1 , Constraint** edge )
{
	if (v0==v1)
	{
		*edge=NULL;
		return false;
	};
	Constraint* p;
	int size    = Edges->Length();
	for (int i=0; i < size ; i++ )
	{
		p = (Constraint*) Edges -> Get( i );
		if ((p->v0==v0) || (p->v0==v1))
		{
			if ((p->v1==v0) || (p->v1==v1))
			{
				*edge=p;
				return false;
			};
		};
	};
	p=new Constraint( v0 , v1 );
	Edges -> Push ( (void*) p );
	*edge = p;
	return true;
};

Cloth::Cloth( iClothFactoryState* mesh,
         csVector3&    Sh,
         csBox3&       box,
         csVector3     grav )
{
	shift       = &Sh;
	object_bbox = &box;
	gravity     = grav;
	printf( " CREATING the cloth... \n");
	uint i;
	vertices  = NULL;
	triangles = NULL;
	printf( " CREATING the clothA... \n");
	csVector3* verts          = mesh->GetVertices     ();
	printf( " CREATING the clothB... \n");
	nverts                    = mesh->GetVertexCount  ();
	csTriangle* tris          = mesh->GetTriangles    ();
	uint	tri_count         = mesh->GetTriangleCount();

	//for (i = 0; i < polycnt ; i++)	{ tri_count += polygons[i].num_vertices - 2; };
			printf( " CREATING the cloth2... \n");
	Edges            = new csBasicVector( nverts , 16 );
	nedges           = 0;
	vertices         = new csVector3[ nverts ];

	for (i = 0; i < nverts ; i++)
	{
		vertices[i].Set( verts[i].x , verts[i].y , verts[i].z );
	};

	ntris            = 2*tri_count;   //here we care about double-facing the mesh
	triangles        = new csTriangle   [ ntris ];
	//memcpy ( triangles , tris , sizeof(csTriangle)*ntris );
	//Triangle2EdgeRef = new Constraint**    [ tri_count ];    this will be needed
	                                                       //  when 2nd neighbours are
                                                           //  considered
	//int* vidx;
	printf( " CREATING the cloth3... \n");
	int index=0;
	int tri;
	int v;
	Constraint* a;
	Constraint* b;
	Constraint* c;
	bool isNew;

	for (i=0; i<tri_count; i++)
	{
		triangles[ 2*i ].a = tris[i].a;
		triangles[ 2*i ].b = tris[i].b;
		triangles[ 2*i ].c = tris[i].c;

		triangles[ 2*i + 1 ].a = tris[i].a;
		triangles[ 2*i + 1 ].b = tris[i].c;
		triangles[ 2*i + 1 ].c = tris[i].b;

		isNew = AddConstraint( tris[i].a , tris[i].b , &a );
		if (isNew) 	{ a -> L0 =( verts[ tris[i].a ] - verts[ tris[i].b ] ).Norm();  nedges++; };

		isNew = AddConstraint( tris[i].b , tris[i].c , &b );
		if (isNew) { b -> L0 = ( verts[ tris[i].b ] - verts[ tris[i].c ] ).Norm(); nedges++; };

		isNew = AddConstraint( tris[i].c , tris[i].a , &c );
		if (isNew) { c -> L0 = ( verts[ tris[i].c ] - verts[ tris[i].a ] ).Norm(); nedges++; };
	};
		printf( " CREATING the cloth4... \n");
	/*
	for (i = 0; i<count ; i ++)
	{
		vidx  = p.vertices;
		tri   = 0;
		isNew = AddEdgeConstraint( vidx[0] , vidx[1] , &a );
		if (isNew) { a -> L0 =( verts[ vidx[0] ] - verts[ vidx[1] ] ).Norm();  nedges++; };
		for (v = 2; v < p.num_vertices; v++ , tri++  ) //triangulation
		{
			isNew = AddEdgeConstraint( vidx[v-1] , vidx[v] , &b );
			if (isNew) { b -> L0 = ( verts[ vidx[v-1] ] - verts[ vidx[v] ] ).Norm(); nedges++; };
			isNew = AddEdgeConstraint( vidx[v] , vidx[0] , &c );
			if (isNew) { c -> L0 = ( verts[ vidx[v] ] - verts[ vidx[0] ] ).Norm(); nedges++; };

				       no need to consider 2nd neighbours or dynamic refinement yet
			Triangle2EdgeRef[ index + tri ] = new Constraint*[ 3 ];
			Triangle2EdgeRef[ index + tri ][0] = a;
			Triangle2EdgeRef[ index + tri ][1] = b;
			Triangle2EdgeRef[ index + tri ][2] = c;

			triangles[ index + tri ].a = vidx[0];
			triangles[ index + tri ].b = vidx[v-1];
			triangles[ index + tri ].c = vidx[v];
			a = c;
		};
		index += (p.num_vertices - 2);
	};*/

}; // END Cloth::Cloth

Cloth::~Cloth()
{
	if (vertices)        { delete[] vertices; };
	if (triangles)       { delete[] triangles; };
	Constraint* p;
	//p=(Constraint*)Edges->GetFirstItem();
	p=(Constraint*)Edges->Pop();
	do
	{
		//Edges->RemoveItem( (void*) p );
		delete p;
		p=(Constraint*)Edges->Pop();
	} while (p!=NULL);
	delete Edges;
};

<|endoftext|>