<commit_before>#include "MerchantScoreManagerTestFixture.h"
#include "../recommend-manager/test_util.h"
#include <util/ustring/UString.h>

#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>

namespace bfs = boost::filesystem;

namespace
{
const char* TEST_DIR = "merchant_score_test";
const char* GROUP_DIR = "group";
const char* SCORE_FILE = "merchant_score.bin";

const char* MERCHANT_PROP = "Source";
const char* CATEGORY_PROP = "Category";

const izenelib::util::UString::EncodingType ENCODING_TYPE = izenelib::util::UString::UTF_8;

const float FLOAT_TOLERANCE = 0.00001;
}

namespace sf1r
{

/**
 * @param categoryStr a string containing a category path,
 * from root node to leaf node, each splitted by space.
 * For example, "node1 node2 node3".
 */
score_t& getCategoryScore(
    CategoryStrScore& categoryStrScore,
    const std::string& categoryStr)
{
    CategoryStrPath categoryPath;
    split_str_to_items(categoryStr, categoryPath);

    return categoryStrScore.categoryScoreMap[categoryPath];
}

MerchantScoreManagerTestFixture::MerchantScoreManagerTestFixture()
{
    bfs::path testDir = TEST_DIR;
    bfs::remove_all(testDir);
    bfs::create_directory(testDir);

    groupDir_ = (testDir / GROUP_DIR).string();
    bfs::create_directory(groupDir_);

    scoreFile_ = (testDir / SCORE_FILE).string();

    resetInstance();
}

void MerchantScoreManagerTestFixture::resetInstance()
{
    merchantScoreManager_.reset();
    merchantValueTable_.reset();
    categoryValueTable_.reset();

    merchantValueTable_.reset(new faceted::PropValueTable(groupDir_, MERCHANT_PROP));
    categoryValueTable_.reset(new faceted::PropValueTable(groupDir_, CATEGORY_PROP));
    merchantScoreManager_.reset(new MerchantScoreManager(merchantValueTable_.get(),
                                                         categoryValueTable_.get()));

    BOOST_CHECK(merchantValueTable_->open());
    BOOST_CHECK(categoryValueTable_->open());
    BOOST_CHECK(merchantScoreManager_->open(scoreFile_));
}

void MerchantScoreManagerTestFixture::checkEmptyScore()
{
    MerchantStrScoreMap strScoreMap;
    merchantScoreManager_->getAllStrScore(strScoreMap);
    BOOST_CHECK(strScoreMap.map.empty());

    checkNonExistingId_();
}

void MerchantScoreManagerTestFixture::setScore1()
{
    MerchantStrScoreMap strScoreMap;
    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;

    {
        CategoryStrScore& category = merchantMap["京东"];
        category.generalScore = 6;
        getCategoryScore(category, "手机数码 手机通讯 手机") = 9;
        getCategoryScore(category, "家用电器") = 8;
    }

    {
        CategoryStrScore& category = merchantMap["一号店"];
        category.generalScore = 7.7;
    }

    merchantScoreManager_->setScore(strScoreMap);
}

void MerchantScoreManagerTestFixture::checkScore1()
{
    checkAllScore1_();
    checkPartScore1_();
    checkIdScore1_();
}

void MerchantScoreManagerTestFixture::setScore2()
{
    MerchantStrScoreMap strScoreMap;
    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;

    {
        CategoryStrScore& category = merchantMap["京东"];
        category.generalScore = 5;
        getCategoryScore(category, "手机数码 手机通讯 手机") = 9.8;
        getCategoryScore(category, "手机数码 手机通讯") = 8.8;
        getCategoryScore(category, "手机数码") = 7.8;
        getCategoryScore(category, "服装服饰 男装") = 6;
    }

    {
        CategoryStrScore& category = merchantMap["一号店"];
        category.generalScore = 0;
        getCategoryScore(category, "食品") = 8;
    }

    {
        CategoryStrScore& category = merchantMap["卓越亚马逊"];
        getCategoryScore(category, "图书") = 9.5;
    }

    merchantScoreManager_->setScore(strScoreMap);
}

void MerchantScoreManagerTestFixture::checkScore2()
{
    checkAllScore2_();
    checkPartScore2_();
    checkIdScore2_();
}

merchant_id_t MerchantScoreManagerTestFixture::getMerchantId_(const std::string& merchant) const
{
    std::vector<izenelib::util::UString> path;
    izenelib::util::UString ustr(merchant, ENCODING_TYPE);
    path.push_back(ustr);

    return merchantValueTable_->propValueId(path);
}

category_id_t MerchantScoreManagerTestFixture::getCategoryId_(const std::string& category) const
{
    CategoryStrPath categoryPath;
    split_str_to_items(category, categoryPath);

    std::vector<izenelib::util::UString> ustrPath;
    for (CategoryStrPath::const_iterator it = categoryPath.begin();
         it != categoryPath.end(); ++it)
    {
        ustrPath.push_back(izenelib::util::UString(*it, ENCODING_TYPE));
    }

    return categoryValueTable_->propValueId(ustrPath);
}

category_id_t MerchantScoreManagerTestFixture::insertCategoryId_(const std::string& category) const
{
    CategoryStrPath categoryPath;
    split_str_to_items(category, categoryPath);

    std::vector<izenelib::util::UString> ustrPath;
    for (CategoryStrPath::const_iterator it = categoryPath.begin();
         it != categoryPath.end(); ++it)
    {
        ustrPath.push_back(izenelib::util::UString(*it, ENCODING_TYPE));
    }

    return categoryValueTable_->insertPropValueId(ustrPath);
}

void MerchantScoreManagerTestFixture::checkNonExistingId_()
{
    merchant_id_t merchantId = getMerchantId_("不存在");
    std::vector<category_id_t> categoryParentIds;
    BOOST_CHECK_EQUAL(merchantScoreManager_->getIdScore(merchantId, categoryParentIds),
                      0);

    category_id_t categoryId = getCategoryId_("手机数码");
    categoryParentIds.push_back(categoryId);
    BOOST_CHECK_EQUAL(merchantScoreManager_->getIdScore(merchantId, categoryParentIds),
                      0);
}

void MerchantScoreManagerTestFixture::checkIdScoreEqual_(
    const std::string& merchant,
    const std::string& category,
    score_t gold)
{
    BOOST_TEST_MESSAGE("checkIdScoreEqual_, merchant: " << merchant <<
                       ", category: " << category);

    merchant_id_t merchantId = getMerchantId_(merchant);
    category_id_t categoryId = getCategoryId_(category);
    std::vector<category_id_t> categoryParentIds;
    categoryValueTable_->getParentIds(categoryId, categoryParentIds);
    score_t actual = merchantScoreManager_->getIdScore(merchantId, categoryParentIds);

    BOOST_CHECK_EQUAL(actual, gold);
}

void MerchantScoreManagerTestFixture::checkIdScoreClose_(
    const std::string& merchant,
    const std::string& category,
    score_t gold)
{
    BOOST_TEST_MESSAGE("checkIdScoreClose_, merchant: " << merchant <<
                       ", category: " << category);

    merchant_id_t merchantId = getMerchantId_(merchant);
    category_id_t categoryId = getCategoryId_(category);
    std::vector<category_id_t> categoryParentIds;
    categoryValueTable_->getParentIds(categoryId, categoryParentIds);
    score_t actual = merchantScoreManager_->getIdScore(merchantId, categoryParentIds);

    BOOST_CHECK_CLOSE(actual, gold, FLOAT_TOLERANCE);
}

void MerchantScoreManagerTestFixture::checkAllScore1_()
{
    MerchantStrScoreMap strScoreMap;
    merchantScoreManager_->getAllStrScore(strScoreMap);

    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;
    BOOST_CHECK_EQUAL(merchantMap.size(), 2U);

    {
        CategoryStrScore& category = merchantMap["京东"];
        BOOST_CHECK_EQUAL(category.generalScore, 6);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 2U);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "手机数码 手机通讯 手机"), 9);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "家用电器"), 8);
    }

    {
        CategoryStrScore& category = merchantMap["一号店"];
        BOOST_CHECK_CLOSE(category.generalScore, 7.7, FLOAT_TOLERANCE);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 0U);
    }
}

void MerchantScoreManagerTestFixture::checkPartScore1_()
{
    MerchantStrScoreMap strScoreMap;
    std::vector<std::string> merchantNames;
    merchantNames.push_back("京东");
    merchantNames.push_back("易讯");

    merchantScoreManager_->getStrScore(merchantNames, strScoreMap);

    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;
    BOOST_CHECK_EQUAL(merchantMap.size(), 2U);

    {
        CategoryStrScore& category = merchantMap["京东"];
        BOOST_CHECK_EQUAL(category.generalScore, 6);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 2U);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "手机数码 手机通讯 手机"), 9);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "家用电器"), 8);
    }

    {
        CategoryStrScore& category = merchantMap["易讯"];
        BOOST_CHECK_EQUAL(category.generalScore, 0);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 0U);
    }
}

void MerchantScoreManagerTestFixture::checkIdScore1_()
{
    checkNonExistingId_();

    std::string merchant = "京东";
    checkIdScoreEqual_(merchant, "", 6);
    checkIdScoreEqual_(merchant, "手机数码 手机通讯 手机", 9);
    checkIdScoreEqual_(merchant, "手机数码 手机通讯", 6);
    checkIdScoreEqual_(merchant, "手机数码", 6);
    checkIdScoreEqual_(merchant, "家用电器", 8);
    checkIdScoreEqual_(merchant, "食品", 6);

    std::string subNode("手机数码 手机通讯 手机 iPad");
    insertCategoryId_(subNode);
    checkIdScoreEqual_(merchant, subNode, 9);

    merchant = "一号店";
    checkIdScoreClose_(merchant, "", 7.7);
    checkIdScoreClose_(merchant, "食品", 7.7);
}

void MerchantScoreManagerTestFixture::checkAllScore2_()
{
    MerchantStrScoreMap strScoreMap;
    merchantScoreManager_->getAllStrScore(strScoreMap);

    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;
    BOOST_CHECK_EQUAL(merchantMap.size(), 3U);

    {
        CategoryStrScore& category = merchantMap["京东"];
        BOOST_CHECK_EQUAL(category.generalScore, 5);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 4U);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码 手机通讯 手机"),
                          9.8, FLOAT_TOLERANCE);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码 手机通讯"),
                          8.8, FLOAT_TOLERANCE);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码"),
                          7.8, FLOAT_TOLERANCE);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "服装服饰 男装"), 6);
    }

    {
        CategoryStrScore& category = merchantMap["一号店"];
        BOOST_CHECK_EQUAL(category.generalScore, 0);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 1U);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "食品"), 8);
    }

    {
        CategoryStrScore& category = merchantMap["卓越亚马逊"];
        BOOST_CHECK_EQUAL(category.generalScore, 0);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 1U);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "图书"), 9.5);
    }
}

void MerchantScoreManagerTestFixture::checkPartScore2_()
{
    MerchantStrScoreMap strScoreMap;
    std::vector<std::string> merchantNames;
    merchantNames.push_back("京东");
    merchantNames.push_back("易讯");

    merchantScoreManager_->getStrScore(merchantNames, strScoreMap);

    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;
    BOOST_CHECK_EQUAL(merchantMap.size(), 2U);

    {
        CategoryStrScore& category = merchantMap["京东"];
        BOOST_CHECK_EQUAL(category.generalScore, 5);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 4U);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码 手机通讯 手机"),
                          9.8, FLOAT_TOLERANCE);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码 手机通讯"),
                          8.8, FLOAT_TOLERANCE);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码"),
                          7.8, FLOAT_TOLERANCE);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "服装服饰 男装"), 6);
    }

    {
        CategoryStrScore& category = merchantMap["易讯"];
        BOOST_CHECK_EQUAL(category.generalScore, 0);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 0U);
    }
}

void MerchantScoreManagerTestFixture::checkIdScore2_()
{
    checkNonExistingId_();

    std::string merchant = "京东";
    checkIdScoreEqual_(merchant, "", 5);
    checkIdScoreClose_(merchant, "手机数码 手机通讯 手机", 9.8);
    checkIdScoreClose_(merchant, "手机数码 手机通讯", 8.8);
    checkIdScoreClose_(merchant, "手机数码", 7.8);
    checkIdScoreEqual_(merchant, "家用电器", 5);
    checkIdScoreEqual_(merchant, "服装服饰 男装", 6);
    checkIdScoreEqual_(merchant, "食品", 5);

    std::string subNode("手机数码 手机通讯 手机 iPhone");
    insertCategoryId_(subNode);
    checkIdScoreClose_(merchant, subNode, 9.8);

    merchant = "一号店";
    checkIdScoreEqual_(merchant, "", 0);
    checkIdScoreEqual_(merchant, "食品", 8);
    checkIdScoreEqual_(merchant, "数码", 0);

    merchant = "卓越亚马逊";
    checkIdScoreEqual_(merchant, "", 0);
    checkIdScoreEqual_(merchant, "图书", 9.5);
    checkIdScoreEqual_(merchant, "数码", 0);
}

} // namespace sf1r
<commit_msg>add more check statements in test case t_MerchantScoreManager<commit_after>#include "MerchantScoreManagerTestFixture.h"
#include "../recommend-manager/test_util.h"
#include <util/ustring/UString.h>

#include <boost/test/unit_test.hpp>
#include <boost/filesystem.hpp>

namespace bfs = boost::filesystem;

namespace
{
const char* TEST_DIR = "merchant_score_test";
const char* GROUP_DIR = "group";
const char* SCORE_FILE = "merchant_score.bin";

const char* MERCHANT_PROP = "Source";
const char* CATEGORY_PROP = "Category";

const izenelib::util::UString::EncodingType ENCODING_TYPE = izenelib::util::UString::UTF_8;

const float FLOAT_TOLERANCE = 0.00001;
}

namespace sf1r
{

/**
 * @param categoryStr a string containing a category path,
 * from root node to leaf node, each splitted by space.
 * For example, "node1 node2 node3".
 */
score_t& getCategoryScore(
    CategoryStrScore& categoryStrScore,
    const std::string& categoryStr)
{
    CategoryStrPath categoryPath;
    split_str_to_items(categoryStr, categoryPath);

    return categoryStrScore.categoryScoreMap[categoryPath];
}

MerchantScoreManagerTestFixture::MerchantScoreManagerTestFixture()
{
    bfs::path testDir = TEST_DIR;
    bfs::remove_all(testDir);
    bfs::create_directory(testDir);

    groupDir_ = (testDir / GROUP_DIR).string();
    bfs::create_directory(groupDir_);

    scoreFile_ = (testDir / SCORE_FILE).string();

    resetInstance();
}

void MerchantScoreManagerTestFixture::resetInstance()
{
    merchantScoreManager_.reset();
    merchantValueTable_.reset();
    categoryValueTable_.reset();

    merchantValueTable_.reset(new faceted::PropValueTable(groupDir_, MERCHANT_PROP));
    categoryValueTable_.reset(new faceted::PropValueTable(groupDir_, CATEGORY_PROP));
    merchantScoreManager_.reset(new MerchantScoreManager(merchantValueTable_.get(),
                                                         categoryValueTable_.get()));

    BOOST_CHECK(merchantValueTable_->open());
    BOOST_CHECK(categoryValueTable_->open());
    BOOST_CHECK(merchantScoreManager_->open(scoreFile_));
}

void MerchantScoreManagerTestFixture::checkEmptyScore()
{
    MerchantStrScoreMap strScoreMap;
    merchantScoreManager_->getAllStrScore(strScoreMap);
    BOOST_CHECK(strScoreMap.map.empty());

    checkNonExistingId_();
}

void MerchantScoreManagerTestFixture::setScore1()
{
    MerchantStrScoreMap strScoreMap;
    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;

    {
        CategoryStrScore& category = merchantMap["京东"];
        category.generalScore = 6;
        getCategoryScore(category, "手机数码 手机通讯 手机") = 9;
        getCategoryScore(category, "家用电器") = 8;
    }

    {
        CategoryStrScore& category = merchantMap["一号店"];
        category.generalScore = 7.7;
    }

    merchantScoreManager_->setScore(strScoreMap);
}

void MerchantScoreManagerTestFixture::checkScore1()
{
    checkAllScore1_();
    checkPartScore1_();
    checkIdScore1_();
}

void MerchantScoreManagerTestFixture::setScore2()
{
    MerchantStrScoreMap strScoreMap;
    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;

    {
        CategoryStrScore& category = merchantMap["京东"];
        category.generalScore = 5;
        getCategoryScore(category, "手机数码 手机通讯 手机") = 9.8;
        getCategoryScore(category, "手机数码 手机通讯") = 8.8;
        getCategoryScore(category, "手机数码") = 7.8;
        getCategoryScore(category, "服装服饰 男装") = 6;
    }

    {
        CategoryStrScore& category = merchantMap["一号店"];
        category.generalScore = 0;
        getCategoryScore(category, "食品") = 8;
    }

    {
        CategoryStrScore& category = merchantMap["卓越亚马逊"];
        getCategoryScore(category, "图书") = 9.5;
    }

    merchantScoreManager_->setScore(strScoreMap);
}

void MerchantScoreManagerTestFixture::checkScore2()
{
    checkAllScore2_();
    checkPartScore2_();
    checkIdScore2_();
}

merchant_id_t MerchantScoreManagerTestFixture::getMerchantId_(const std::string& merchant) const
{
    std::vector<izenelib::util::UString> path;
    izenelib::util::UString ustr(merchant, ENCODING_TYPE);
    path.push_back(ustr);

    return merchantValueTable_->propValueId(path);
}

category_id_t MerchantScoreManagerTestFixture::getCategoryId_(const std::string& category) const
{
    CategoryStrPath categoryPath;
    split_str_to_items(category, categoryPath);

    std::vector<izenelib::util::UString> ustrPath;
    for (CategoryStrPath::const_iterator it = categoryPath.begin();
         it != categoryPath.end(); ++it)
    {
        ustrPath.push_back(izenelib::util::UString(*it, ENCODING_TYPE));
    }

    return categoryValueTable_->propValueId(ustrPath);
}

category_id_t MerchantScoreManagerTestFixture::insertCategoryId_(const std::string& category) const
{
    CategoryStrPath categoryPath;
    split_str_to_items(category, categoryPath);

    std::vector<izenelib::util::UString> ustrPath;
    for (CategoryStrPath::const_iterator it = categoryPath.begin();
         it != categoryPath.end(); ++it)
    {
        ustrPath.push_back(izenelib::util::UString(*it, ENCODING_TYPE));
    }

    return categoryValueTable_->insertPropValueId(ustrPath);
}

void MerchantScoreManagerTestFixture::checkNonExistingId_()
{
    merchant_id_t merchantId = getMerchantId_("不存在");
    std::vector<category_id_t> categoryParentIds;
    BOOST_CHECK_EQUAL(merchantScoreManager_->getIdScore(merchantId, categoryParentIds),
                      0);

    category_id_t categoryId = getCategoryId_("手机数码");
    categoryParentIds.push_back(categoryId);
    BOOST_CHECK_EQUAL(merchantScoreManager_->getIdScore(merchantId, categoryParentIds),
                      0);
}

void MerchantScoreManagerTestFixture::checkIdScoreEqual_(
    const std::string& merchant,
    const std::string& category,
    score_t gold)
{
    BOOST_TEST_MESSAGE("checkIdScoreEqual_, merchant: " << merchant <<
                       ", category: " << category);

    merchant_id_t merchantId = getMerchantId_(merchant);
    category_id_t categoryId = getCategoryId_(category);
    std::vector<category_id_t> categoryParentIds;
    categoryValueTable_->getParentIds(categoryId, categoryParentIds);
    score_t actual = merchantScoreManager_->getIdScore(merchantId, categoryParentIds);

    BOOST_CHECK_EQUAL(actual, gold);
}

void MerchantScoreManagerTestFixture::checkIdScoreClose_(
    const std::string& merchant,
    const std::string& category,
    score_t gold)
{
    BOOST_TEST_MESSAGE("checkIdScoreClose_, merchant: " << merchant <<
                       ", category: " << category);

    merchant_id_t merchantId = getMerchantId_(merchant);
    category_id_t categoryId = getCategoryId_(category);
    std::vector<category_id_t> categoryParentIds;
    categoryValueTable_->getParentIds(categoryId, categoryParentIds);
    score_t actual = merchantScoreManager_->getIdScore(merchantId, categoryParentIds);

    BOOST_CHECK_CLOSE(actual, gold, FLOAT_TOLERANCE);
}

void MerchantScoreManagerTestFixture::checkAllScore1_()
{
    MerchantStrScoreMap strScoreMap;
    merchantScoreManager_->getAllStrScore(strScoreMap);

    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;
    BOOST_CHECK_EQUAL(merchantMap.size(), 2U);

    {
        CategoryStrScore& category = merchantMap["京东"];
        BOOST_CHECK_EQUAL(category.generalScore, 6);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 2U);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "手机数码 手机通讯 手机"), 9);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "家用电器"), 8);
    }

    {
        CategoryStrScore& category = merchantMap["一号店"];
        BOOST_CHECK_CLOSE(category.generalScore, 7.7, FLOAT_TOLERANCE);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 0U);
    }
}

void MerchantScoreManagerTestFixture::checkPartScore1_()
{
    MerchantStrScoreMap strScoreMap;
    std::vector<std::string> merchantNames;
    merchantNames.push_back("京东");
    merchantNames.push_back("易讯");

    merchantScoreManager_->getStrScore(merchantNames, strScoreMap);

    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;
    BOOST_CHECK_EQUAL(merchantMap.size(), 2U);

    {
        CategoryStrScore& category = merchantMap["京东"];
        BOOST_CHECK_EQUAL(category.generalScore, 6);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 2U);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "手机数码 手机通讯 手机"), 9);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "家用电器"), 8);
    }

    {
        CategoryStrScore& category = merchantMap["易讯"];
        BOOST_CHECK_EQUAL(category.generalScore, 0);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 0U);
    }
}

void MerchantScoreManagerTestFixture::checkIdScore1_()
{
    checkNonExistingId_();

    std::string merchant = "京东";
    checkIdScoreEqual_(merchant, "", 6);
    checkIdScoreEqual_(merchant, "手机数码 手机通讯 手机", 9);
    checkIdScoreEqual_(merchant, "手机数码 手机通讯", 6);
    checkIdScoreEqual_(merchant, "手机数码", 6);
    checkIdScoreEqual_(merchant, "家用电器", 8);
    checkIdScoreEqual_(merchant, "食品", 6);

    std::string subNode("手机数码 手机通讯 手机 iPad");
    insertCategoryId_(subNode);
    checkIdScoreEqual_(merchant, subNode, 9);

    merchant = "一号店";
    checkIdScoreClose_(merchant, "", 7.7);
    checkIdScoreClose_(merchant, "食品", 7.7);
}

void MerchantScoreManagerTestFixture::checkAllScore2_()
{
    MerchantStrScoreMap strScoreMap;
    merchantScoreManager_->getAllStrScore(strScoreMap);

    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;
    BOOST_CHECK_EQUAL(merchantMap.size(), 3U);

    {
        CategoryStrScore& category = merchantMap["京东"];
        BOOST_CHECK_EQUAL(category.generalScore, 5);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 4U);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码 手机通讯 手机"),
                          9.8, FLOAT_TOLERANCE);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码 手机通讯"),
                          8.8, FLOAT_TOLERANCE);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码"),
                          7.8, FLOAT_TOLERANCE);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "服装服饰 男装"), 6);
    }

    {
        CategoryStrScore& category = merchantMap["一号店"];
        BOOST_CHECK_EQUAL(category.generalScore, 0);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 1U);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "食品"), 8);
    }

    {
        CategoryStrScore& category = merchantMap["卓越亚马逊"];
        BOOST_CHECK_EQUAL(category.generalScore, 0);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 1U);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "图书"), 9.5);
    }
}

void MerchantScoreManagerTestFixture::checkPartScore2_()
{
    MerchantStrScoreMap strScoreMap;
    std::vector<std::string> merchantNames;
    merchantNames.push_back("京东");
    merchantNames.push_back("易讯");

    merchantScoreManager_->getStrScore(merchantNames, strScoreMap);

    MerchantStrScoreMap::map_t& merchantMap = strScoreMap.map;
    BOOST_CHECK_EQUAL(merchantMap.size(), 2U);

    {
        CategoryStrScore& category = merchantMap["京东"];
        BOOST_CHECK_EQUAL(category.generalScore, 5);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 4U);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码 手机通讯 手机"),
                          9.8, FLOAT_TOLERANCE);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码 手机通讯"),
                          8.8, FLOAT_TOLERANCE);
        BOOST_CHECK_CLOSE(getCategoryScore(category, "手机数码"),
                          7.8, FLOAT_TOLERANCE);
        BOOST_CHECK_EQUAL(getCategoryScore(category, "服装服饰 男装"), 6);
    }

    {
        CategoryStrScore& category = merchantMap["易讯"];
        BOOST_CHECK_EQUAL(category.generalScore, 0);
        BOOST_CHECK_EQUAL(category.categoryScoreMap.size(), 0U);
    }
}

void MerchantScoreManagerTestFixture::checkIdScore2_()
{
    checkNonExistingId_();

    std::string merchant = "京东";
    checkIdScoreEqual_(merchant, "", 5);
    checkIdScoreClose_(merchant, "手机数码 手机通讯 手机", 9.8);
    checkIdScoreClose_(merchant, "手机数码 手机通讯", 8.8);
    checkIdScoreClose_(merchant, "手机数码", 7.8);
    checkIdScoreEqual_(merchant, "家用电器", 5);
    checkIdScoreEqual_(merchant, "服装服饰 男装", 6);
    checkIdScoreEqual_(merchant, "食品", 5);

    std::string subNode("手机数码 手机通讯 手机 iPhone");
    insertCategoryId_(subNode);
    checkIdScoreClose_(merchant, subNode, 9.8);

    subNode = "手机数码 手机通讯 手机配件";
    insertCategoryId_(subNode);
    checkIdScoreClose_(merchant, subNode, 8.8);

    subNode = "手机数码 配件";
    insertCategoryId_(subNode);
    checkIdScoreClose_(merchant, subNode, 7.8);

    merchant = "一号店";
    checkIdScoreEqual_(merchant, "", 0);
    checkIdScoreEqual_(merchant, "食品", 8);
    checkIdScoreEqual_(merchant, "数码", 0);

    merchant = "卓越亚马逊";
    checkIdScoreEqual_(merchant, "", 0);
    checkIdScoreEqual_(merchant, "图书", 9.5);
    checkIdScoreEqual_(merchant, "数码", 0);
}

} // namespace sf1r
<|endoftext|>


<commit_before>// -----------------------------------------------------------------------------
//
// Copyright (C) 2021 CERN & Newcastle University for the benefit of the
// BioDynaMo collaboration. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//
// See the LICENSE file distributed with this work for details.
// See the NOTICE file distributed with this work for additional information
// regarding copyright ownership.
//
// -----------------------------------------------------------------------------

#include "core/container/parallel_resize_vector.h"
#include <gtest/gtest.h>

namespace bdm {

TEST(ParallelResizeVectorTest, Basics) {
  ParallelResizeVector<unsigned> v = {0, 1, 2, 3};
  ASSERT_EQ(4u, v.size());

  // push_back
  v.push_back(4);
  ASSERT_EQ(5u, v.size());

  // subscript operator
  for (unsigned i = 0; i < v.size(); i++) {
    EXPECT_EQ(i, v[i]);
  }

  // iterator
  unsigned cnt = 0;
  for (auto& el : v) {
    EXPECT_EQ(cnt++, el);
  }
  EXPECT_EQ(5u, cnt);

  // clear
  v.clear();
  EXPECT_EQ(0u, v.size());

  // resize
  v.resize(10);
  ASSERT_EQ(10u, v.size());
  for (unsigned i = 0; i < v.size(); i++) {
    EXPECT_EQ(0u, v[i]);
  }
}

TEST(ParallelResizeVectorTest, SizeAndDefaultValueCtor) {
  ParallelResizeVector<int> v(9, 3);
  EXPECT_EQ(9u, v.size());
  for (uint64_t i = 0; i < 9; ++i) {
    EXPECT_EQ(3, v[i]);
  }
}

TEST(ParallelResizeVector, Reserve) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.reserve(123);
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(123u, v.capacity());
}

TEST(ParallelResizeVector, CopyCtor) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.resize(10, 123);

  auto copy(v);

  EXPECT_EQ(10u, copy.size());
  EXPECT_EQ(10u, copy.capacity());

  for (auto el : copy) {
    EXPECT_EQ(123, el);
  }
}

TEST(ParallelResizeVector, AssignmentOperator) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.resize(10, 123);

  ParallelResizeVector<int> copy;
  copy = v;

  EXPECT_EQ(10u, copy.size());
  EXPECT_EQ(10u, copy.capacity());

  for (auto el : copy) {
    EXPECT_EQ(123, el);
  }
}

TEST(ParallelResizeVector, AssignmentOperator2) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.resize(17576, 123);

  ParallelResizeVector<int> copy{};
  copy = v;

  EXPECT_EQ(17576u, copy.size());
  EXPECT_EQ(17576u, copy.capacity());

  for (auto el : copy) {
    EXPECT_EQ(123, el);
  }

  v.clear();
  v.resize(10, 124);
  copy = v;

  EXPECT_EQ(10u, copy.size());

  for (auto el : copy) {
    EXPECT_EQ(124, el);
  }
}

TEST(ParallelResizeVector, AssignmentOperator_Self) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.resize(17576, 123);
  v = v;

  EXPECT_EQ(17576u, v.size());
  EXPECT_EQ(17576u, v.capacity());

  for (auto el : v) {
    EXPECT_EQ(123, el);
  }
}

}  // namespace bdm
<commit_msg>Fix compiler warning for self assignment (#206)<commit_after>// -----------------------------------------------------------------------------
//
// Copyright (C) 2021 CERN & Newcastle University for the benefit of the
// BioDynaMo collaboration. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//
// See the LICENSE file distributed with this work for details.
// See the NOTICE file distributed with this work for additional information
// regarding copyright ownership.
//
// -----------------------------------------------------------------------------

#include "core/container/parallel_resize_vector.h"
#include <gtest/gtest.h>

namespace bdm {

TEST(ParallelResizeVectorTest, Basics) {
  ParallelResizeVector<unsigned> v = {0, 1, 2, 3};
  ASSERT_EQ(4u, v.size());

  // push_back
  v.push_back(4);
  ASSERT_EQ(5u, v.size());

  // subscript operator
  for (unsigned i = 0; i < v.size(); i++) {
    EXPECT_EQ(i, v[i]);
  }

  // iterator
  unsigned cnt = 0;
  for (auto& el : v) {
    EXPECT_EQ(cnt++, el);
  }
  EXPECT_EQ(5u, cnt);

  // clear
  v.clear();
  EXPECT_EQ(0u, v.size());

  // resize
  v.resize(10);
  ASSERT_EQ(10u, v.size());
  for (unsigned i = 0; i < v.size(); i++) {
    EXPECT_EQ(0u, v[i]);
  }
}

TEST(ParallelResizeVectorTest, SizeAndDefaultValueCtor) {
  ParallelResizeVector<int> v(9, 3);
  EXPECT_EQ(9u, v.size());
  for (uint64_t i = 0; i < 9; ++i) {
    EXPECT_EQ(3, v[i]);
  }
}

TEST(ParallelResizeVector, Reserve) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.reserve(123);
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(123u, v.capacity());
}

TEST(ParallelResizeVector, CopyCtor) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.resize(10, 123);

  auto copy(v);

  EXPECT_EQ(10u, copy.size());
  EXPECT_EQ(10u, copy.capacity());

  for (auto el : copy) {
    EXPECT_EQ(123, el);
  }
}

TEST(ParallelResizeVector, AssignmentOperator) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.resize(10, 123);

  ParallelResizeVector<int> copy;
  copy = v;

  EXPECT_EQ(10u, copy.size());
  EXPECT_EQ(10u, copy.capacity());

  for (auto el : copy) {
    EXPECT_EQ(123, el);
  }
}

TEST(ParallelResizeVector, AssignmentOperator2) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.resize(17576, 123);

  ParallelResizeVector<int> copy{};
  copy = v;

  EXPECT_EQ(17576u, copy.size());
  EXPECT_EQ(17576u, copy.capacity());

  for (auto el : copy) {
    EXPECT_EQ(123, el);
  }

  v.clear();
  v.resize(10, 124);
  copy = v;

  EXPECT_EQ(10u, copy.size());

  for (auto el : copy) {
    EXPECT_EQ(124, el);
  }
}

TEST(ParallelResizeVector, AssignmentOperator_Self) {
  ParallelResizeVector<int> v;
  EXPECT_EQ(0u, v.size());
  EXPECT_EQ(0u, v.capacity());

  v.resize(17576, 123);
  v = static_cast<ParallelResizeVector<int>&>(v);

  EXPECT_EQ(17576u, v.size());
  EXPECT_EQ(17576u, v.capacity());

  for (auto el : v) {
    EXPECT_EQ(123, el);
  }
}

}  // namespace bdm
<|endoftext|>


<commit_before>/*
    OpenDeck MIDI platform firmware
    Copyright (C) 2015-2017 Igor Petrovic

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "interface/Interface.h"

SysEx sysEx;
MIDI midi;

void initSysEx()
{
    sysEx.addBlocks(DB_BLOCKS);

    sysExSection section;

    {
        //MIDI block

        //midi feature section
        section.numberOfParameters = MIDI_FEATURES;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_MIDI, section);

        //midi channel section
        section.numberOfParameters = MIDI_CHANNELS;
        section.minValue = 1;
        section.maxValue = 16;

        sysEx.addSection(DB_BLOCK_MIDI, section);
    }

    {
        //button block

        //type section
        section.numberOfParameters = MAX_NUMBER_OF_BUTTONS+MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = BUTTON_TYPES-1;

        sysEx.addSection(DB_BLOCK_BUTTON, section);

        //midi message type section
        section.numberOfParameters = MAX_NUMBER_OF_BUTTONS+MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = BUTTON_MESSAGE_TYPES-1;

        sysEx.addSection(DB_BLOCK_BUTTON, section);

        //midi id section
        section.numberOfParameters = MAX_NUMBER_OF_BUTTONS+MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_BUTTON, section);
    }

    {
        //encoder block

        //encoder enabled section
        section.numberOfParameters = MAX_NUMBER_OF_ENCODERS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_ENCODER, section);

        //encoder inverted section
        section.numberOfParameters = MAX_NUMBER_OF_ENCODERS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_ENCODER, section);

        //encoding mode section
        section.numberOfParameters = MAX_NUMBER_OF_ENCODERS;
        section.minValue = 0;
        section.maxValue = ENCODING_MODES-1;

        sysEx.addSection(DB_BLOCK_ENCODER, section);

        //midi id section
        section.numberOfParameters = MAX_NUMBER_OF_ENCODERS;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_ENCODER, section);
    }

    {
        //analog block

        //analog enabled section
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //analog inverted section
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //analog type section
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = ANALOG_TYPES-1;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //midi id section
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //lower cc limit
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //upper cc limit
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_ANALOG, section);
    }

    {
        //led block

        //hardware parameters section
        section.numberOfParameters = LED_HARDWARE_PARAMETERS;
        section.minValue = 0;
        section.maxValue = 0;

        sysEx.addSection(DB_BLOCK_LED, section);

        //activation note section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_LED, section);

        //rgb enabled section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_LED, section);

        //local led control enabled section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_LED, section);

        //led color section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = LED_COLORS-1;

        sysEx.addSection(DB_BLOCK_LED, section);

        //led blink section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_LED, section);
    }
}

void globalInit()
{
    #if defined(BOARD_OPEN_DECK) || defined(BOARD_A_LEO)
    midi.setUSBMIDIstate(true);
    #endif

    #if defined(BOARD_OPEN_DECK) || defined(BOARD_A_MEGA)
    midi.setDINMIDIstate(true);
    #endif

    midi.setOneByteParseDINstate(true);

    database.init();
    board.init();

    midi.setInputChannel(database.read(DB_BLOCK_MIDI, midiChannelSection, inputChannel));
    initSysEx();

    //enable global interrupts
    sei();

    leds.init();
}

bool onCustom(uint8_t value)
{
    switch(value)
    {
        case FIRMWARE_VERSION_STRING:
        sysEx.addToResponse(1);
        sysEx.addToResponse(0);
        sysEx.addToResponse(0);
        return true;

        case HARDWARE_VERSION_STRING:
        sysEx.addToResponse(HARDWARE_VERSION_MAJOR);
        sysEx.addToResponse(HARDWARE_VERSION_MINOR);
        sysEx.addToResponse(HARDWARE_VERSION_REVISION);
        return true;

        case MAX_COMPONENTS_STRING:
        sysEx.addToResponse(MAX_NUMBER_OF_BUTTONS+MAX_NUMBER_OF_ANALOG);
        sysEx.addToResponse(MAX_NUMBER_OF_ENCODERS);
        sysEx.addToResponse(MAX_NUMBER_OF_ANALOG);
        sysEx.addToResponse(MAX_NUMBER_OF_LEDS);
        return true;

        case REBOOT_APP_STRING:
        leds.setAllOff();
        wait_ms(2500);
        board.reboot(rebootApp);
        return true;

        case REBOOT_BTLDR_STRING:
        leds.setAllOff();
        wait_ms(2500);
        board.reboot(rebootBtldr);
        return true;

        case FACTORY_RESET_STRING:
        leds.setAllOff();
        wait_ms(1500);
        database.factoryReset(initPartial);
        board.reboot(rebootApp);
        return true;
    }

    return false;
}

sysExParameter_t onGet(uint8_t block, uint8_t section, uint16_t index)
{
    switch(block)
    {
        case DB_BLOCK_LED:
        switch(section)
        {
            case ledColorSection:
            return leds.getColor(index);

            case ledBlinkSection:
            return leds.getBlinkState(index);

            default:
            return database.read(block, section, index);
        }
        break;

        default:
        return database.read(block, section, index);
    }
}

bool onSet(uint8_t block, uint8_t section, uint16_t index, sysExParameter_t newValue)
{
    bool returnValue = true;
    //check this block manually
    if (block != DB_BLOCK_LED)
        returnValue = database.update(block, section, index, newValue);

    if (returnValue)
    {
        //special checks
        switch(block)
        {
            case DB_BLOCK_ANALOG:
            if (section == analogTypeSection)
                analog.debounceReset(index);
            break;

            case DB_BLOCK_MIDI:
            if (section == midiFeatureSection)
            {
                if (index == midiFeatureRunningStatus)
                    midi.setRunningStatusState(newValue);
                else if (index == midiFeatureStandardNoteOff)
                    newValue ? midi.setNoteOffMode(noteOffType_standardNoteOff) : midi.setNoteOffMode(noteOffType_noteOnZeroVel);
            }
            break;

            case DB_BLOCK_LED:
            switch(section)
            {
                case ledColorSection:
                //no writing to database
                leds.setColor(index, (ledColor_t)newValue);
                break;

                case ledBlinkSection:
                //no writing to database
                leds.setBlinkState(index, newValue);
                break;

                case ledHardwareParameterSection:
                //this entire section needs specific value check
                switch(index)
                {
                    case ledHwParameterBlinkTime:
                    if ((newValue < BLINK_TIME_MIN) || (newValue > BLINK_TIME_MAX))
                        return false;
                    leds.setBlinkTime(newValue);
                    break;

                    case ledHwParameterFadeTime:
                    if ((newValue < FADE_TIME_MIN) || (newValue > FADE_TIME_MAX))
                        return false;
                    #ifdef BOARD_OPEN_DECK
                    leds.setFadeTime(newValue);
                    #endif
                    break;

                    case ledHwParameterStartUpRoutine:
                    if (newValue > 1)
                        return false;
                    break;
                }
                //values are ok - write
                database.update(block, section, index, newValue);
                break;

                case ledRGBenabledSection:
                //make sure to turn all three leds off before setting new state
                leds.setColor(board.getRGBaddress(index, rgb_R), colorOff);
                leds.setColor(board.getRGBaddress(index, rgb_G), colorOff);
                leds.setColor(board.getRGBaddress(index, rgb_B), colorOff);
                //write rgb enabled bit to three leds
                database.update(block, section, board.getRGBaddress(index, rgb_R), newValue);
                database.update(block, section, board.getRGBaddress(index, rgb_G), newValue);
                database.update(block, section, board.getRGBaddress(index, rgb_B), newValue);
                break;

                default:
                database.update(block, section, index, newValue);
                break;
            }
            break;

            default:
            break;
        }
    }

    return returnValue;
}

void writeSysEx(uint8_t sysExArray[], uint8_t arraysize)
{
    midi.sendSysEx(arraysize, sysExArray, true);
}

int main()
{
    globalInit();

    sysEx.setHandleGet(onGet);
    sysEx.setHandleSet(onSet);
    sysEx.setHandleCustomRequest(onCustom);
    sysEx.setHandleSysExWrite(writeSysEx);

    sysEx.addCustomRequest(FIRMWARE_VERSION_STRING);
    sysEx.addCustomRequest(HARDWARE_VERSION_STRING);
    sysEx.addCustomRequest(MAX_COMPONENTS_STRING);
    sysEx.addCustomRequest(REBOOT_APP_STRING);
    sysEx.addCustomRequest(REBOOT_BTLDR_STRING);
    sysEx.addCustomRequest(FACTORY_RESET_STRING);

    while(1)
    {
        #if defined(BOARD_A_LEO) || defined(BOARD_OPEN_DECK)
        if (midi.read(usbInterface))
        {
            //new message on usb
            midiMessageType_t messageType = midi.getType(usbInterface);
            uint8_t data1 = midi.getData1(usbInterface);
            uint8_t data2 = midi.getData2(usbInterface);

            switch(messageType)
            {
                case midiMessageSystemExclusive:
                sysEx.handleMessage(midi.getSysExArray(usbInterface), midi.getSysExArrayLength(usbInterface));
                break;

                case midiMessageNoteOn:
                //we're using received note data to control LED color
                leds.noteToState(data1, data2);
                break;

                case midiMessageNoteOff:
                //always turn led off when note off is received
                leds.noteToState(data1, 0);
                break;

                case midiMessageControlChange:
                //control change is used to control led blinking
                leds.ccToBlink(data1, data2);
                break;

                default:
                break;
            }
        }
        #endif

        #ifndef BOARD_A_MEGA
        if (midi.getDINMIDIstate())
        {
            //check for incoming MIDI messages on USART
            if (!database.read(DB_BLOCK_MIDI, midiFeatureSection, midiFeatureUSBconvert))
            {
                midi.read(dinInterface);
                midiMessageType_t messageType = midi.getType(dinInterface);
                uint8_t data1 = midi.getData1(dinInterface);
                uint8_t data2 = midi.getData2(dinInterface);

                switch(messageType)
                {
                    case midiMessageNoteOff:
                    case midiMessageNoteOn:
                    leds.noteToState(data1, data2);
                    break;

                    default:
                    break;
                }
            }
            else
            {
                //dump everything from MIDI in to USB MIDI out
                midi.read(dinInterface, THRU_FULL_USB);
            }
        }
        #endif

        #ifdef BOARD_A_MEGA
        if (midi.read(dinInterface))
        {
            midiMessageType_t messageType = midi.getType(dinInterface);
            uint8_t data1 = midi.getData1(dinInterface);
            uint8_t data2 = midi.getData2(dinInterface);

            switch(messageType)
            {
                sysEx.handleMessage(midi.getSysExArray(dinInterface), midi.getSysExArrayLength(dinInterface));
                break;

                case midiMessageNoteOn:
                //we're using received note data to control LED color
                leds.noteToState(data1, data2);
                break;

                case midiMessageNoteOff:
                //always turn led off when note off is received
                leds.noteToState(data1, 0);
                break;

                case midiMessageControlChange:
                //control change is used to control led blinking
                leds.ccToBlink(data1, data2);
                break;

                default:
                break;
            }
        }
        #endif

        //digitalInput.update();
        //analog.update();
        //leds.update();
    }
}
<commit_msg>fix case<commit_after>/*
    OpenDeck MIDI platform firmware
    Copyright (C) 2015-2017 Igor Petrovic

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

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "interface/Interface.h"

SysEx sysEx;
MIDI midi;

void initSysEx()
{
    sysEx.addBlocks(DB_BLOCKS);

    sysExSection section;

    {
        //MIDI block

        //midi feature section
        section.numberOfParameters = MIDI_FEATURES;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_MIDI, section);

        //midi channel section
        section.numberOfParameters = MIDI_CHANNELS;
        section.minValue = 1;
        section.maxValue = 16;

        sysEx.addSection(DB_BLOCK_MIDI, section);
    }

    {
        //button block

        //type section
        section.numberOfParameters = MAX_NUMBER_OF_BUTTONS+MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = BUTTON_TYPES-1;

        sysEx.addSection(DB_BLOCK_BUTTON, section);

        //midi message type section
        section.numberOfParameters = MAX_NUMBER_OF_BUTTONS+MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = BUTTON_MESSAGE_TYPES-1;

        sysEx.addSection(DB_BLOCK_BUTTON, section);

        //midi id section
        section.numberOfParameters = MAX_NUMBER_OF_BUTTONS+MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_BUTTON, section);
    }

    {
        //encoder block

        //encoder enabled section
        section.numberOfParameters = MAX_NUMBER_OF_ENCODERS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_ENCODER, section);

        //encoder inverted section
        section.numberOfParameters = MAX_NUMBER_OF_ENCODERS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_ENCODER, section);

        //encoding mode section
        section.numberOfParameters = MAX_NUMBER_OF_ENCODERS;
        section.minValue = 0;
        section.maxValue = ENCODING_MODES-1;

        sysEx.addSection(DB_BLOCK_ENCODER, section);

        //midi id section
        section.numberOfParameters = MAX_NUMBER_OF_ENCODERS;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_ENCODER, section);
    }

    {
        //analog block

        //analog enabled section
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //analog inverted section
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //analog type section
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = ANALOG_TYPES-1;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //midi id section
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //lower cc limit
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_ANALOG, section);

        //upper cc limit
        section.numberOfParameters = MAX_NUMBER_OF_ANALOG;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_ANALOG, section);
    }

    {
        //led block

        //hardware parameters section
        section.numberOfParameters = LED_HARDWARE_PARAMETERS;
        section.minValue = 0;
        section.maxValue = 0;

        sysEx.addSection(DB_BLOCK_LED, section);

        //activation note section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = 127;

        sysEx.addSection(DB_BLOCK_LED, section);

        //rgb enabled section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_LED, section);

        //local led control enabled section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_LED, section);

        //led color section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = LED_COLORS-1;

        sysEx.addSection(DB_BLOCK_LED, section);

        //led blink section
        section.numberOfParameters = MAX_NUMBER_OF_LEDS;
        section.minValue = 0;
        section.maxValue = 1;

        sysEx.addSection(DB_BLOCK_LED, section);
    }
}

void globalInit()
{
    #if defined(BOARD_OPEN_DECK) || defined(BOARD_A_LEO)
    midi.setUSBMIDIstate(true);
    #endif

    #if defined(BOARD_OPEN_DECK) || defined(BOARD_A_MEGA)
    midi.setDINMIDIstate(true);
    #endif

    midi.setOneByteParseDINstate(true);

    database.init();
    board.init();

    midi.setInputChannel(database.read(DB_BLOCK_MIDI, midiChannelSection, inputChannel));
    initSysEx();

    //enable global interrupts
    sei();

    leds.init();
}

bool onCustom(uint8_t value)
{
    switch(value)
    {
        case FIRMWARE_VERSION_STRING:
        sysEx.addToResponse(1);
        sysEx.addToResponse(0);
        sysEx.addToResponse(0);
        return true;

        case HARDWARE_VERSION_STRING:
        sysEx.addToResponse(HARDWARE_VERSION_MAJOR);
        sysEx.addToResponse(HARDWARE_VERSION_MINOR);
        sysEx.addToResponse(HARDWARE_VERSION_REVISION);
        return true;

        case MAX_COMPONENTS_STRING:
        sysEx.addToResponse(MAX_NUMBER_OF_BUTTONS+MAX_NUMBER_OF_ANALOG);
        sysEx.addToResponse(MAX_NUMBER_OF_ENCODERS);
        sysEx.addToResponse(MAX_NUMBER_OF_ANALOG);
        sysEx.addToResponse(MAX_NUMBER_OF_LEDS);
        return true;

        case REBOOT_APP_STRING:
        leds.setAllOff();
        wait_ms(2500);
        board.reboot(rebootApp);
        return true;

        case REBOOT_BTLDR_STRING:
        leds.setAllOff();
        wait_ms(2500);
        board.reboot(rebootBtldr);
        return true;

        case FACTORY_RESET_STRING:
        leds.setAllOff();
        wait_ms(1500);
        database.factoryReset(initPartial);
        board.reboot(rebootApp);
        return true;
    }

    return false;
}

sysExParameter_t onGet(uint8_t block, uint8_t section, uint16_t index)
{
    switch(block)
    {
        case DB_BLOCK_LED:
        switch(section)
        {
            case ledColorSection:
            return leds.getColor(index);

            case ledBlinkSection:
            return leds.getBlinkState(index);

            default:
            return database.read(block, section, index);
        }
        break;

        default:
        return database.read(block, section, index);
    }
}

bool onSet(uint8_t block, uint8_t section, uint16_t index, sysExParameter_t newValue)
{
    bool returnValue = true;
    //check this block manually
    if (block != DB_BLOCK_LED)
        returnValue = database.update(block, section, index, newValue);

    if (returnValue)
    {
        //special checks
        switch(block)
        {
            case DB_BLOCK_ANALOG:
            if (section == analogTypeSection)
                analog.debounceReset(index);
            break;

            case DB_BLOCK_MIDI:
            if (section == midiFeatureSection)
            {
                if (index == midiFeatureRunningStatus)
                    midi.setRunningStatusState(newValue);
                else if (index == midiFeatureStandardNoteOff)
                    newValue ? midi.setNoteOffMode(noteOffType_standardNoteOff) : midi.setNoteOffMode(noteOffType_noteOnZeroVel);
            }
            break;

            case DB_BLOCK_LED:
            switch(section)
            {
                case ledColorSection:
                //no writing to database
                leds.setColor(index, (ledColor_t)newValue);
                break;

                case ledBlinkSection:
                //no writing to database
                leds.setBlinkState(index, newValue);
                break;

                case ledHardwareParameterSection:
                //this entire section needs specific value check
                switch(index)
                {
                    case ledHwParameterBlinkTime:
                    if ((newValue < BLINK_TIME_MIN) || (newValue > BLINK_TIME_MAX))
                        return false;
                    leds.setBlinkTime(newValue);
                    break;

                    case ledHwParameterFadeTime:
                    if ((newValue < FADE_TIME_MIN) || (newValue > FADE_TIME_MAX))
                        return false;
                    #ifdef BOARD_OPEN_DECK
                    leds.setFadeTime(newValue);
                    #endif
                    break;

                    case ledHwParameterStartUpRoutine:
                    if (newValue > 1)
                        return false;
                    break;
                }
                //values are ok - write
                database.update(block, section, index, newValue);
                break;

                case ledRGBenabledSection:
                //make sure to turn all three leds off before setting new state
                leds.setColor(board.getRGBaddress(index, rgb_R), colorOff);
                leds.setColor(board.getRGBaddress(index, rgb_G), colorOff);
                leds.setColor(board.getRGBaddress(index, rgb_B), colorOff);
                //write rgb enabled bit to three leds
                database.update(block, section, board.getRGBaddress(index, rgb_R), newValue);
                database.update(block, section, board.getRGBaddress(index, rgb_G), newValue);
                database.update(block, section, board.getRGBaddress(index, rgb_B), newValue);
                break;

                default:
                database.update(block, section, index, newValue);
                break;
            }
            break;

            default:
            break;
        }
    }

    return returnValue;
}

void writeSysEx(uint8_t sysExArray[], uint8_t arraysize)
{
    midi.sendSysEx(arraysize, sysExArray, true);
}

int main()
{
    globalInit();

    sysEx.setHandleGet(onGet);
    sysEx.setHandleSet(onSet);
    sysEx.setHandleCustomRequest(onCustom);
    sysEx.setHandleSysExWrite(writeSysEx);

    sysEx.addCustomRequest(FIRMWARE_VERSION_STRING);
    sysEx.addCustomRequest(HARDWARE_VERSION_STRING);
    sysEx.addCustomRequest(MAX_COMPONENTS_STRING);
    sysEx.addCustomRequest(REBOOT_APP_STRING);
    sysEx.addCustomRequest(REBOOT_BTLDR_STRING);
    sysEx.addCustomRequest(FACTORY_RESET_STRING);

    while(1)
    {
        #if defined(BOARD_A_LEO) || defined(BOARD_OPEN_DECK)
        if (midi.read(usbInterface))
        {
            //new message on usb
            midiMessageType_t messageType = midi.getType(usbInterface);
            uint8_t data1 = midi.getData1(usbInterface);
            uint8_t data2 = midi.getData2(usbInterface);

            switch(messageType)
            {
                case midiMessageSystemExclusive:
                sysEx.handleMessage(midi.getSysExArray(usbInterface), midi.getSysExArrayLength(usbInterface));
                break;

                case midiMessageNoteOn:
                //we're using received note data to control LED color
                leds.noteToState(data1, data2);
                break;

                case midiMessageNoteOff:
                //always turn led off when note off is received
                leds.noteToState(data1, 0);
                break;

                case midiMessageControlChange:
                //control change is used to control led blinking
                leds.ccToBlink(data1, data2);
                break;

                default:
                break;
            }
        }
        #endif

        #ifndef BOARD_A_MEGA
        if (midi.getDINMIDIstate())
        {
            //check for incoming MIDI messages on USART
            if (!database.read(DB_BLOCK_MIDI, midiFeatureSection, midiFeatureUSBconvert))
            {
                midi.read(dinInterface);
                midiMessageType_t messageType = midi.getType(dinInterface);
                uint8_t data1 = midi.getData1(dinInterface);
                uint8_t data2 = midi.getData2(dinInterface);

                switch(messageType)
                {
                    case midiMessageNoteOff:
                    case midiMessageNoteOn:
                    leds.noteToState(data1, data2);
                    break;

                    default:
                    break;
                }
            }
            else
            {
                //dump everything from MIDI in to USB MIDI out
                midi.read(dinInterface, THRU_FULL_USB);
            }
        }
        #endif

        #ifdef BOARD_A_MEGA
        if (midi.read(dinInterface))
        {
            midiMessageType_t messageType = midi.getType(dinInterface);
            uint8_t data1 = midi.getData1(dinInterface);
            uint8_t data2 = midi.getData2(dinInterface);

            switch(messageType)
            {
                case midiMessageSystemExclusive:
                sysEx.handleMessage(midi.getSysExArray(dinInterface), midi.getSysExArrayLength(dinInterface));
                break;

                case midiMessageNoteOn:
                //we're using received note data to control LED color
                leds.noteToState(data1, data2);
                break;

                case midiMessageNoteOff:
                //always turn led off when note off is received
                leds.noteToState(data1, 0);
                break;

                case midiMessageControlChange:
                //control change is used to control led blinking
                leds.ccToBlink(data1, data2);
                break;

                default:
                break;
            }
        }
        #endif

        //digitalInput.update();
        //analog.update();
        //leds.update();
    }
}
<|endoftext|>


<commit_before>#include "common.h"
#include <vector>
#include <string>

void fmitcp::sendProtoBuffer(lw_client c, fmitcp_proto::fmitcp_message * message){
    std::string s;
    bool status = message->SerializeToString(&s);
    //printf("serialize status=%d\n", status);
    lw_stream_write(c, s.c_str(), s.size());
    std::string newline = "\n";
    lw_stream_write(c, newline.c_str(),newline.size());
    //fflush(NULL);
}

std::string fmitcp::dataToString(const char* data, long size) {
    std::string data2(data, size);
    return data2;
    /*
    // Make this data safe!
    std::string data2;
    for(int i=0; i<size; i++){
        if(data[i] != '\0')
            data2.push_back(data[i]);
        else
            printf("contained null!\n");
    }
    return data2;
    */
}

fmitcp_proto::jm_status_enu_t fmitcp::fmiJMStatusToProtoJMStatus(jm_status_enu_t status) {
  switch (status) {
  case jm_status_error:
    return fmitcp_proto::jm_status_error;
  case jm_status_success:
    return fmitcp_proto::jm_status_success;
  case jm_status_warning:
    return fmitcp_proto::jm_status_warning;
  default: // should never be reached
    return fmitcp_proto::jm_status_error;
  }
}

fmitcp_proto::fmi2_status_t fmitcp::fmi2StatusToProtofmi2Status(fmi2_status_t status) {
  switch (status) {
  case fmi2_status_ok:
    return fmitcp_proto::fmi2_status_ok;
  case fmi2_status_warning:
    return fmitcp_proto::fmi2_status_warning;
  case fmi2_status_discard:
    return fmitcp_proto::fmi2_status_discard;
  case fmi2_status_error:
      return fmitcp_proto::fmi2_status_error;
  case fmi2_status_fatal:
      return fmitcp_proto::fmi2_status_fatal;
  case fmi2_status_pending:
      return fmitcp_proto::fmi2_status_pending;
  default: // should never be reached
    return fmitcp_proto::fmi2_status_error;
  }
}
<commit_msg>flushing fix<commit_after>#include "common.h"
#include <vector>
#include <string>

void fmitcp::sendProtoBuffer(lw_client c, fmitcp_proto::fmitcp_message * message){
    std::string s;
    bool status = message->SerializeToString(&s);
    //printf("serialize status=%d\n", status);
    lw_stream_write(c, s.c_str(), s.size());
    std::string newline = "\n";
    lw_stream_write(c, newline.c_str(),newline.size());
    fflush(NULL);
}

std::string fmitcp::dataToString(const char* data, long size) {
    std::string data2(data, size);
    return data2;
    /*
    // Make this data safe!
    std::string data2;
    for(int i=0; i<size; i++){
        if(data[i] != '\0')
            data2.push_back(data[i]);
        else
            printf("contained null!\n");
    }
    return data2;
    */
}

fmitcp_proto::jm_status_enu_t fmitcp::fmiJMStatusToProtoJMStatus(jm_status_enu_t status) {
  switch (status) {
  case jm_status_error:
    return fmitcp_proto::jm_status_error;
  case jm_status_success:
    return fmitcp_proto::jm_status_success;
  case jm_status_warning:
    return fmitcp_proto::jm_status_warning;
  default: // should never be reached
    return fmitcp_proto::jm_status_error;
  }
}

fmitcp_proto::fmi2_status_t fmitcp::fmi2StatusToProtofmi2Status(fmi2_status_t status) {
  switch (status) {
  case fmi2_status_ok:
    return fmitcp_proto::fmi2_status_ok;
  case fmi2_status_warning:
    return fmitcp_proto::fmi2_status_warning;
  case fmi2_status_discard:
    return fmitcp_proto::fmi2_status_discard;
  case fmi2_status_error:
      return fmitcp_proto::fmi2_status_error;
  case fmi2_status_fatal:
      return fmitcp_proto::fmi2_status_fatal;
  case fmi2_status_pending:
      return fmitcp_proto::fmi2_status_pending;
  default: // should never be reached
    return fmitcp_proto::fmi2_status_error;
  }
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011-2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>

#include "args.hpp"
#include "debts.hpp"

using namespace budget;

int main(int argc, const char* argv[]) {
    if(argc == 1){
        std::cout << "A command is necessary" << std::endl;

        return 1;
    }

    auto args = parse_args(argc, argv);

    auto& command = args[0];

    if(command == "help"){
        std::cout << "Usage: budget command [options]" << std::endl;

        //TODO Display complete help
    } else if(command == "debt"){
        return handle_debts(args);
    } else {
        std::cout << "Invalid command \"" << command << "\"" << std::endl;

        return 1;
    }

    return 0;
}
<commit_msg>Cleanup<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011-2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <string>
#include <iostream>

#include "args.hpp"
#include "debts.hpp"

using namespace budget;

int main(int argc, const char* argv[]) {
    if(argc == 1){
        //TODO In the future, display the default module
        std::cout << "A command is necessary" << std::endl;

        return 1;
    }

    auto args = parse_args(argc, argv);

    auto& command = args[0];

    if(command == "help"){
        std::cout << "Usage: budget command [options]" << std::endl;

        //TODO Display complete help
    } else if(command == "debt"){
        return handle_debts(args);
    } else {
        std::cout << "Unhandled command \"" << command << "\"" << std::endl;

        return 1;
    }

    return 0;
}
<|endoftext|>


<commit_before>/*
 * shrenderer.cpp
 *
 *  Created on: 03.07.2012
 *      Author: Ralph
 */
#include "../../thirdparty/glew/include/glew.h"

#include <limits>

#include <QtOpenGL/QGLShaderProgram>
#include <QtCore/QDebug>
#include <QtGui/QVector3D>
#include <QtGui/QMatrix4x4>

#include "../../data/datasets/datasetdwi.h"
#include "../../data/enums.h"
#include "../../data/vptr.h"
#include "../../data/qball.h"

#include "../../data/mesh/tesselation.h"
#include "../../data/mesh/trianglemesh.h"

#include "../../thirdparty/newmat10/newmat.h"

#include "glfunctions.h"
#include "shrenderer.h"

SHRenderer::SHRenderer() :
    ObjectRenderer(),
    m_tris1( 0 ),
    vboIds( new GLuint[ 6 ] )
{
    for ( int lod = 0; lod < 6; ++lod )
    {
        const Matrix* vertices = tess::vertices( lod );
        const int* faces = tess::faces( lod );
        int numVerts = tess::n_vertices( lod );
        int numTris = tess::n_faces( lod );

        TriangleMesh* mesh = new TriangleMesh( numVerts, numTris );

        for ( int i = 0; i < numVerts; ++i )
        {
            mesh->addVertex( i, QVector3D( (*vertices)( i+1, 1 ), (*vertices)( i+1, 2 ), (*vertices)( i+1, 3 ) ) );
        }
        for ( int i = 0; i < numTris; ++i )
        {
            Triangle tri = {faces[i*3], faces[i*3+1], faces[i*3+2]};
            mesh->addTriangle( i, tri );
        }
        m_spheres.push_back( mesh );
    }
}

SHRenderer::~SHRenderer()
{
}

void SHRenderer::init()
{
    glGenBuffers( 6, vboIds );
}

void SHRenderer::draw( QMatrix4x4 mvp_matrix )
{
    QList<int>rl;

    int countDatasets = model()->rowCount();
    for ( int i = 0; i < countDatasets; ++i )
    {
        QModelIndex index = model()->index( i, FNDSE_ACTIVE );
        if ( model()->data( index, Qt::EditRole ).toBool() )
        {
            index = model()->index( i, FNDSP_CREATED_BY );
            if ( model()->data( index, Qt::DisplayRole ).toInt() == FNALGO_QBALL )
            {
                rl.push_back( i );
                //qDebug() << "found QBall to render";
            }
        }
    }

    if ( rl.size() > 0 )
    {
        //qDebug() << "sh draw";

        m_dataset = VPtr<DatasetDWI>::asPtr( model()->data( model()->index( rl[0], 2 ), Qt::EditRole ) );

        int orient = m_dataset->getProperty( "renderSlice" ).toInt();
        if ( orient == 0 )
        {
            return;
        }

        GLFunctions::getShader( "qball" )->bind();
        // Set modelview-projection matrix
        GLFunctions::getShader( "qball" )->setUniformValue( "mvp_matrix", mvp_matrix );

        initGeometry();

        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIds[ 0 ] );
        glBindBuffer( GL_ARRAY_BUFFER, vboIds[ 1 ] );
        setShaderVars();
        glDrawElements( GL_TRIANGLES, m_tris1, GL_UNSIGNED_INT, 0 );
        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
        glBindBuffer( GL_ARRAY_BUFFER, 0 );
    }
}

void SHRenderer::setupTextures()
{
}

void SHRenderer::setShaderVars()
{
    GLFunctions::setShaderVars( "qball", model() );
}

void SHRenderer::initGeometry()
{
    int xi = model()->data( model()->index( 0, FNGLOBAL_SAGITTAL ), Qt::UserRole ).toInt();
    int yi = model()->data( model()->index( 0, FNGLOBAL_CORONAL ), Qt::UserRole ).toInt();
    int zi = model()->data( model()->index( 0, FNGLOBAL_AXIAL ), Qt::UserRole ).toInt();
    int xbi = model()->data( model()->index( 0, FNGLOBAL_MAX_SAGITTAL ), Qt::UserRole ).toInt();
    int ybi = model()->data( model()->index( 0, FNGLOBAL_MAX_CORONAL ), Qt::UserRole ).toInt();
    //int zbi = model()->data( model()->index( 0, FNGLOBAL_MAX_AXIAL ), Qt::UserRole ).toInt();

    float dx = model()->data( model()->index( 0, FNGLOBAL_SLICE_DX ), Qt::UserRole ).toFloat();
    float dy = model()->data( model()->index( 0, FNGLOBAL_SLICE_DY ), Qt::UserRole ).toFloat();
    float dz = model()->data( model()->index( 0, FNGLOBAL_SLICE_DZ ), Qt::UserRole ).toFloat();

    int lowerX = m_dataset->getProperty( "renderLowerX" ).toInt();
    int lowerY = m_dataset->getProperty( "renderLowerY" ).toInt();
    int lowerZ = m_dataset->getProperty( "renderLowerZ" ).toInt();
    int upperX = m_dataset->getProperty( "renderUpperX" ).toInt();
    int upperY = m_dataset->getProperty( "renderUpperY" ).toInt();
    int upperZ = m_dataset->getProperty( "renderUpperZ" ).toInt();

    int order = m_dataset->getProperty( "order" ).toInt();
    int lod = m_dataset->getProperty( "lod" ).toInt();

    //float scaling = m_dataset->getProperty( "scaling" ).toFloat();
    int orient = m_dataset->getProperty( "renderSlice" ).toInt();

    bool minmaxScaling = m_dataset->getProperty( "minmaxScaling" ).toBool();

    QString s = createSettingsString( xi, yi, zi, lod, orient, lowerX, upperX, lowerY, upperY, lowerZ, upperZ, minmaxScaling);
    if ( s == m_previousSettings )
    {
        return;
    }
    m_previousSettings = s;

    float x = (float)xi * dx + dx / 2.;
    float y = (float)yi * dy + dy / 2.;
    float z = (float)zi * dz + dz / 2.;

    TriangleMesh* mesh = m_spheres[lod];
    QVector< QVector3D > normals = mesh->getVertNormals();

    const Matrix* v1 = tess::vertices( lod );
    Matrix base = ( QBall::sh_base( (*v1), order ) );

    std::vector<float>verts;
    std::vector<int>indexes;

    int numVerts = mesh->getVertSize();
    int currentBall = 0;

    if ( orient == 1 )
    {
        qDebug() << "QBall: start init geometry";
        QVector< QVector3D > vertices = mesh->getVertices();
        QVector< Triangle > triangles = mesh->getTriangles();

        QVector<ColumnVector>* data = m_dataset->getData();

        int glyphs = ( upperX - lowerX ) * ( upperY - lowerY );
        verts.reserve( mesh->getVertSize() * glyphs * 10 );
        indexes.reserve( triangles.size() * glyphs * 3 );

        Matrix m = base * data->at( 0 );

        for( int yy = lowerY; yy < upperY; ++yy )
        {
            for ( int xx = lowerX; xx < upperX; ++xx )
            {
                if ( ( fabs( data->at( xx + yy * xbi + zi * xbi * ybi )(1) ) > 0.0001 ) )
                {
                    ColumnVector dv = data->at( xx + yy * xbi + zi * xbi * ybi );
                    ColumnVector r = base * dv;

                    float max = 0;
                    float min = std::numeric_limits<float>::max();
                    for ( int i = 0; i < r.Nrows(); ++i )
                    {
                        max = qMax( max, (float)r(i+1) );
                        min = qMin( min, (float)r(i+1) );
                    }

                    if ( minmaxScaling )
                    {
                        max = max - min;
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = ( r(i+1) - min ) / max * 0.8;
                        }
                    }
                    else
                    {
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            //r(i+1) *= -1.0;
                            //if ( r( i + 1) < 0.0 ) r( i+1 ) = 0.0;
                            r(i+1) = r(i+1) / max * 0.8;
                        }
                    }

                    float locX = xx * dx + dx / 2;
                    float locY =  + yy * dy + dy / 2;

                    for ( int i = 0; i < vertices.size(); ++i )
                    {
                        verts.push_back( vertices[i].x() );
                        verts.push_back( vertices[i].y() );
                        verts.push_back( vertices[i].z() );
                        verts.push_back( normals[i].x() );
                        verts.push_back( normals[i].y() );
                        verts.push_back( normals[i].z() );
                        verts.push_back( locX );
                        verts.push_back( locY );
                        verts.push_back( z );
                        verts.push_back( r(i + 1) );
                    }
                    for ( int i = 0; i < triangles.size(); ++i )
                    {
                        indexes.push_back( triangles[i].v0 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v1 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v2 + numVerts * currentBall );
                    }
                    ++currentBall;
                }
            }
        }
    }
    else if ( orient == 2 )
    {
        qDebug() << "QBall: start init geometry";
        QVector< QVector3D > vertices = mesh->getVertices();
        QVector< Triangle > triangles = mesh->getTriangles();

        QVector<ColumnVector>* data = m_dataset->getData();

        Matrix m = base * data->at( 0 );

        for( int zz = lowerZ; zz < upperZ; ++zz )
        {
            for ( int xx = lowerX; xx < upperX; ++xx )
            {
                if ( ( fabs( data->at( xx + yi * xbi + zz * xbi * ybi )(1) ) > 0.0001 ) )
                {
                    ColumnVector dv = data->at( xx + yi * xbi + zz * xbi * ybi );
                    ColumnVector r = base * dv;

                    float max = 0;
                    float min = std::numeric_limits<float>::max();
                    for ( int i = 0; i < r.Nrows(); ++i )
                    {
                        max = qMax( max, (float)r(i+1) );
                        min = qMin( min, (float)r(i+1) );
                    }
                    if ( minmaxScaling )
                    {
                        max = max - min;
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = ( r(i+1) - min ) / max;
                        }
                    }
                    else
                    {
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = r(i+1) / max;
                        }
                    }

                    float locX = xx * dx + dx / 2;
                    float locZ = zz * dz + dz / 2;

                    for ( int i = 0; i < vertices.size(); ++i )
                    {
                        verts.push_back( vertices[i].x() );
                        verts.push_back( vertices[i].y() );
                        verts.push_back( vertices[i].z() );
                        verts.push_back( normals[i].x() );
                        verts.push_back( normals[i].y() );
                        verts.push_back( normals[i].z() );
                        verts.push_back( locX );
                        verts.push_back( y );
                        verts.push_back( locZ );
                        verts.push_back( r(i + 1) );
                    }
                    for ( int i = 0; i < triangles.size(); ++i )
                    {
                        indexes.push_back( triangles[i].v0 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v1 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v2 + numVerts * currentBall );
                    }
                    ++currentBall;
                }
            }
        }
    }
    else if ( orient == 3 )
    {
        qDebug() << "QBall: start init geometry";
        QVector< QVector3D > vertices = mesh->getVertices();
        QVector< Triangle > triangles = mesh->getTriangles();

        QVector<ColumnVector>* data = m_dataset->getData();

        Matrix m = base * data->at( 0 );

        for( int yy = lowerY; yy < upperY; ++yy )
        {
            for ( int zz = lowerZ; zz < upperZ; ++zz )
            {
                if ( ( fabs( data->at( xi + yy * xbi + zz * xbi * ybi )(1) ) > 0.0001 ) )
                {
                    ColumnVector dv = data->at( xi + yy * xbi + zz * xbi * ybi );
                    ColumnVector r = base * dv;

                    float max = 0;
                    float min = std::numeric_limits<float>::max();
                    for ( int i = 0; i < r.Nrows(); ++i )
                    {
                        max = qMax( max, (float)r(i+1) );
                        min = qMin( min, (float)r(i+1) );
                    }
                    if ( minmaxScaling )
                    {
                        max = max - min;
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = ( r(i+1) - min ) / max;
                        }
                    }
                    else
                    {
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = r(i+1) / max;
                        }
                    }

                    float locY = yy * dy + dy / 2;
                    float locZ = zz * dz + dz / 2;

                    for ( int i = 0; i < vertices.size(); ++i )
                    {
                        verts.push_back( vertices[i].x() );
                        verts.push_back( vertices[i].y() );
                        verts.push_back( vertices[i].z() );
                        verts.push_back( normals[i].x() );
                        verts.push_back( normals[i].y() );
                        verts.push_back( normals[i].z() );
                        verts.push_back( x );
                        verts.push_back( locY );
                        verts.push_back( locZ );
                        verts.push_back( r(i + 1) );
                    }
                    for ( int i = 0; i < triangles.size(); ++i )
                    {
                        indexes.push_back( triangles[i].v0 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v1 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v2 + numVerts * currentBall );
                    }
                    ++currentBall;
                }
            }
        }
    }
    else
    {
        return;
    }

    m_tris1 = mesh->getTriSize() * currentBall * 3;

    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIds[ 0 ] );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, indexes.size() * sizeof(GLuint), &indexes[0], GL_STATIC_DRAW );

    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIds[ 1 ] );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, verts.size() * sizeof(GLfloat), &verts[0], GL_STATIC_DRAW );

    qDebug() << "QBall: end init geometry";
}
<commit_msg>return early when nothing to render<commit_after>/*
 * shrenderer.cpp
 *
 *  Created on: 03.07.2012
 *      Author: Ralph
 */
#include "../../thirdparty/glew/include/glew.h"

#include <limits>

#include <QtOpenGL/QGLShaderProgram>
#include <QtCore/QDebug>
#include <QtGui/QVector3D>
#include <QtGui/QMatrix4x4>

#include "../../data/datasets/datasetdwi.h"
#include "../../data/enums.h"
#include "../../data/vptr.h"
#include "../../data/qball.h"

#include "../../data/mesh/tesselation.h"
#include "../../data/mesh/trianglemesh.h"

#include "../../thirdparty/newmat10/newmat.h"

#include "glfunctions.h"
#include "shrenderer.h"

SHRenderer::SHRenderer() :
    ObjectRenderer(),
    m_tris1( 0 ),
    vboIds( new GLuint[ 6 ] )
{
    for ( int lod = 0; lod < 6; ++lod )
    {
        const Matrix* vertices = tess::vertices( lod );
        const int* faces = tess::faces( lod );
        int numVerts = tess::n_vertices( lod );
        int numTris = tess::n_faces( lod );

        TriangleMesh* mesh = new TriangleMesh( numVerts, numTris );

        for ( int i = 0; i < numVerts; ++i )
        {
            mesh->addVertex( i, QVector3D( (*vertices)( i+1, 1 ), (*vertices)( i+1, 2 ), (*vertices)( i+1, 3 ) ) );
        }
        for ( int i = 0; i < numTris; ++i )
        {
            Triangle tri = {faces[i*3], faces[i*3+1], faces[i*3+2]};
            mesh->addTriangle( i, tri );
        }
        m_spheres.push_back( mesh );
    }
}

SHRenderer::~SHRenderer()
{
}

void SHRenderer::init()
{
    glGenBuffers( 6, vboIds );
}

void SHRenderer::draw( QMatrix4x4 mvp_matrix )
{
    QList<int>rl;

    int countDatasets = model()->rowCount();
    for ( int i = 0; i < countDatasets; ++i )
    {
        QModelIndex index = model()->index( i, FNDSE_ACTIVE );
        if ( model()->data( index, Qt::EditRole ).toBool() )
        {
            index = model()->index( i, FNDSP_CREATED_BY );
            if ( model()->data( index, Qt::DisplayRole ).toInt() == FNALGO_QBALL )
            {
                rl.push_back( i );
                //qDebug() << "found QBall to render";
            }
        }
    }

    if ( rl.size() > 0 )
    {
        //qDebug() << "sh draw";

        m_dataset = VPtr<DatasetDWI>::asPtr( model()->data( model()->index( rl[0], 2 ), Qt::EditRole ) );

        int orient = m_dataset->getProperty( "renderSlice" ).toInt();
        if ( orient == 0 )
        {
            return;
        }

        GLFunctions::getShader( "qball" )->bind();
        // Set modelview-projection matrix
        GLFunctions::getShader( "qball" )->setUniformValue( "mvp_matrix", mvp_matrix );

        initGeometry();

        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIds[ 0 ] );
        glBindBuffer( GL_ARRAY_BUFFER, vboIds[ 1 ] );
        setShaderVars();
        glDrawElements( GL_TRIANGLES, m_tris1, GL_UNSIGNED_INT, 0 );
        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
        glBindBuffer( GL_ARRAY_BUFFER, 0 );
    }
}

void SHRenderer::setupTextures()
{
}

void SHRenderer::setShaderVars()
{
    GLFunctions::setShaderVars( "qball", model() );
}

void SHRenderer::initGeometry()
{
    int xi = model()->data( model()->index( 0, FNGLOBAL_SAGITTAL ), Qt::UserRole ).toInt();
    int yi = model()->data( model()->index( 0, FNGLOBAL_CORONAL ), Qt::UserRole ).toInt();
    int zi = model()->data( model()->index( 0, FNGLOBAL_AXIAL ), Qt::UserRole ).toInt();
    int xbi = model()->data( model()->index( 0, FNGLOBAL_MAX_SAGITTAL ), Qt::UserRole ).toInt();
    int ybi = model()->data( model()->index( 0, FNGLOBAL_MAX_CORONAL ), Qt::UserRole ).toInt();
    //int zbi = model()->data( model()->index( 0, FNGLOBAL_MAX_AXIAL ), Qt::UserRole ).toInt();

    float dx = model()->data( model()->index( 0, FNGLOBAL_SLICE_DX ), Qt::UserRole ).toFloat();
    float dy = model()->data( model()->index( 0, FNGLOBAL_SLICE_DY ), Qt::UserRole ).toFloat();
    float dz = model()->data( model()->index( 0, FNGLOBAL_SLICE_DZ ), Qt::UserRole ).toFloat();

    int lowerX = m_dataset->getProperty( "renderLowerX" ).toInt();
    int lowerY = m_dataset->getProperty( "renderLowerY" ).toInt();
    int lowerZ = m_dataset->getProperty( "renderLowerZ" ).toInt();
    int upperX = m_dataset->getProperty( "renderUpperX" ).toInt();
    int upperY = m_dataset->getProperty( "renderUpperY" ).toInt();
    int upperZ = m_dataset->getProperty( "renderUpperZ" ).toInt();

    int order = m_dataset->getProperty( "order" ).toInt();
    int lod = m_dataset->getProperty( "lod" ).toInt();

    //float scaling = m_dataset->getProperty( "scaling" ).toFloat();
    int orient = m_dataset->getProperty( "renderSlice" ).toInt();

    bool minmaxScaling = m_dataset->getProperty( "minmaxScaling" ).toBool();

    QString s = createSettingsString( xi, yi, zi, lod, orient, lowerX, upperX, lowerY, upperY, lowerZ, upperZ, minmaxScaling);
    if ( s == m_previousSettings || orient == 0 )
    {
        return;
    }
    m_previousSettings = s;

    float x = (float)xi * dx + dx / 2.;
    float y = (float)yi * dy + dy / 2.;
    float z = (float)zi * dz + dz / 2.;

    TriangleMesh* mesh = m_spheres[lod];
    QVector< QVector3D > normals = mesh->getVertNormals();

    const Matrix* v1 = tess::vertices( lod );
    Matrix base = ( QBall::sh_base( (*v1), order ) );

    std::vector<float>verts;
    std::vector<int>indexes;

    int numVerts = mesh->getVertSize();
    int currentBall = 0;

    if ( orient == 1 )
    {
        qDebug() << "QBall: start init geometry";
        QVector< QVector3D > vertices = mesh->getVertices();
        QVector< Triangle > triangles = mesh->getTriangles();

        QVector<ColumnVector>* data = m_dataset->getData();

        int glyphs = ( upperX - lowerX ) * ( upperY - lowerY );
        verts.reserve( mesh->getVertSize() * glyphs * 10 );
        indexes.reserve( triangles.size() * glyphs * 3 );

        Matrix m = base * data->at( 0 );

        for( int yy = lowerY; yy < upperY; ++yy )
        {
            for ( int xx = lowerX; xx < upperX; ++xx )
            {
                if ( ( fabs( data->at( xx + yy * xbi + zi * xbi * ybi )(1) ) > 0.0001 ) )
                {
                    ColumnVector dv = data->at( xx + yy * xbi + zi * xbi * ybi );
                    ColumnVector r = base * dv;

                    float max = 0;
                    float min = std::numeric_limits<float>::max();
                    for ( int i = 0; i < r.Nrows(); ++i )
                    {
                        max = qMax( max, (float)r(i+1) );
                        min = qMin( min, (float)r(i+1) );
                    }

                    if ( minmaxScaling )
                    {
                        max = max - min;
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = ( r(i+1) - min ) / max * 0.8;
                        }
                    }
                    else
                    {
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            //r(i+1) *= -1.0;
                            //if ( r( i + 1) < 0.0 ) r( i+1 ) = 0.0;
                            r(i+1) = r(i+1) / max * 0.8;
                        }
                    }

                    float locX = xx * dx + dx / 2;
                    float locY =  + yy * dy + dy / 2;

                    for ( int i = 0; i < vertices.size(); ++i )
                    {
                        verts.push_back( vertices[i].x() );
                        verts.push_back( vertices[i].y() );
                        verts.push_back( vertices[i].z() );
                        verts.push_back( normals[i].x() );
                        verts.push_back( normals[i].y() );
                        verts.push_back( normals[i].z() );
                        verts.push_back( locX );
                        verts.push_back( locY );
                        verts.push_back( z );
                        verts.push_back( r(i + 1) );
                    }
                    for ( int i = 0; i < triangles.size(); ++i )
                    {
                        indexes.push_back( triangles[i].v0 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v1 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v2 + numVerts * currentBall );
                    }
                    ++currentBall;
                }
            }
        }
    }
    else if ( orient == 2 )
    {
        qDebug() << "QBall: start init geometry";
        QVector< QVector3D > vertices = mesh->getVertices();
        QVector< Triangle > triangles = mesh->getTriangles();

        QVector<ColumnVector>* data = m_dataset->getData();

        Matrix m = base * data->at( 0 );

        for( int zz = lowerZ; zz < upperZ; ++zz )
        {
            for ( int xx = lowerX; xx < upperX; ++xx )
            {
                if ( ( fabs( data->at( xx + yi * xbi + zz * xbi * ybi )(1) ) > 0.0001 ) )
                {
                    ColumnVector dv = data->at( xx + yi * xbi + zz * xbi * ybi );
                    ColumnVector r = base * dv;

                    float max = 0;
                    float min = std::numeric_limits<float>::max();
                    for ( int i = 0; i < r.Nrows(); ++i )
                    {
                        max = qMax( max, (float)r(i+1) );
                        min = qMin( min, (float)r(i+1) );
                    }
                    if ( minmaxScaling )
                    {
                        max = max - min;
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = ( r(i+1) - min ) / max;
                        }
                    }
                    else
                    {
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = r(i+1) / max;
                        }
                    }

                    float locX = xx * dx + dx / 2;
                    float locZ = zz * dz + dz / 2;

                    for ( int i = 0; i < vertices.size(); ++i )
                    {
                        verts.push_back( vertices[i].x() );
                        verts.push_back( vertices[i].y() );
                        verts.push_back( vertices[i].z() );
                        verts.push_back( normals[i].x() );
                        verts.push_back( normals[i].y() );
                        verts.push_back( normals[i].z() );
                        verts.push_back( locX );
                        verts.push_back( y );
                        verts.push_back( locZ );
                        verts.push_back( r(i + 1) );
                    }
                    for ( int i = 0; i < triangles.size(); ++i )
                    {
                        indexes.push_back( triangles[i].v0 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v1 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v2 + numVerts * currentBall );
                    }
                    ++currentBall;
                }
            }
        }
    }
    else if ( orient == 3 )
    {
        qDebug() << "QBall: start init geometry";
        QVector< QVector3D > vertices = mesh->getVertices();
        QVector< Triangle > triangles = mesh->getTriangles();

        QVector<ColumnVector>* data = m_dataset->getData();

        Matrix m = base * data->at( 0 );

        for( int yy = lowerY; yy < upperY; ++yy )
        {
            for ( int zz = lowerZ; zz < upperZ; ++zz )
            {
                if ( ( fabs( data->at( xi + yy * xbi + zz * xbi * ybi )(1) ) > 0.0001 ) )
                {
                    ColumnVector dv = data->at( xi + yy * xbi + zz * xbi * ybi );
                    ColumnVector r = base * dv;

                    float max = 0;
                    float min = std::numeric_limits<float>::max();
                    for ( int i = 0; i < r.Nrows(); ++i )
                    {
                        max = qMax( max, (float)r(i+1) );
                        min = qMin( min, (float)r(i+1) );
                    }
                    if ( minmaxScaling )
                    {
                        max = max - min;
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = ( r(i+1) - min ) / max;
                        }
                    }
                    else
                    {
                        for ( int i = 0; i < r.Nrows(); ++i )
                        {
                            r(i+1) = r(i+1) / max;
                        }
                    }

                    float locY = yy * dy + dy / 2;
                    float locZ = zz * dz + dz / 2;

                    for ( int i = 0; i < vertices.size(); ++i )
                    {
                        verts.push_back( vertices[i].x() );
                        verts.push_back( vertices[i].y() );
                        verts.push_back( vertices[i].z() );
                        verts.push_back( normals[i].x() );
                        verts.push_back( normals[i].y() );
                        verts.push_back( normals[i].z() );
                        verts.push_back( x );
                        verts.push_back( locY );
                        verts.push_back( locZ );
                        verts.push_back( r(i + 1) );
                    }
                    for ( int i = 0; i < triangles.size(); ++i )
                    {
                        indexes.push_back( triangles[i].v0 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v1 + numVerts * currentBall );
                        indexes.push_back( triangles[i].v2 + numVerts * currentBall );
                    }
                    ++currentBall;
                }
            }
        }
    }
    else
    {
        return;
    }

    m_tris1 = mesh->getTriSize() * currentBall * 3;

    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIds[ 0 ] );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, indexes.size() * sizeof(GLuint), &indexes[0], GL_STATIC_DRAW );

    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIds[ 1 ] );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, verts.size() * sizeof(GLfloat), &verts[0], GL_STATIC_DRAW );

    qDebug() << "QBall: end init geometry";
}
<|endoftext|>