<commit_before>/*  This file is part of the Pinocchio automatic rigging library.
    Copyright (C) 2007 Ilya Baran (ibaran@mit.edu)

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

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <fstream>
#include <sstream>
#include "attachment.h"
#include "vecutils.h"
#include "lsqSolver.h"

class AttachmentPrivate
{
public:
    AttachmentPrivate() {}
    virtual ~AttachmentPrivate() {}
    virtual Mesh deform(const Mesh &mesh,
            const vector<Transform<> > &transforms) const = 0;
    virtual Vector<double, -1> getWeights(int i) const = 0;
    virtual AttachmentPrivate *clone() const = 0;
};

bool vectorInCone(const Vector3 &v, const vector<Vector3> &ns)
{
    int i;
    Vector3 avg;
    for(i = 0; i < (int)ns.size(); ++i)
        avg += ns[i];

    return v.normalize() * avg.normalize() > 0.5;
}

class AttachmentPrivate1 : public AttachmentPrivate {
public:
    AttachmentPrivate1() {}

    AttachmentPrivate1(const Mesh &mesh, const Skeleton &skeleton,
            const vector<Vector3> &match, const VisibilityTester *tester)
    {
        int i, j;
        int nv = mesh.vertices.size();
        //compute edges
        vector<vector<int> > edges(nv);

        for(i = 0; i < nv; ++i) {
            int cur, start;
            cur = start = mesh.vertices[i].edge;
            do {
                edges[i].push_back(mesh.edges[cur].vertex);
                cur = mesh.edges[mesh.edges[cur].prev].twin;
            } while(cur != start);
        }

        weights.resize(nv);
        int bones = skeleton.fGraph().verts.size() - 1;

        // initialize the weights vectors so they are big enough
        for(i = 0; i < nv; ++i)
            weights[i][bones - 1] = 0.;

        vector<vector<double> > boneDists(nv);
        vector<vector<bool> > boneVis(nv);

        for(i = 0; i < nv; ++i) {
            boneDists[i].resize(bones, -1);
            boneVis[i].resize(bones);
            Vector3 cPos = mesh.vertices[i].pos;

            vector<Vector3> normals;
            for(j = 0; j < (int)edges[i].size(); ++j) {
                int nj = (j + 1) % edges[i].size();
                Vector3 v1 = mesh.vertices[edges[i][j]].pos - cPos;
                Vector3 v2 = mesh.vertices[edges[i][nj]].pos - cPos;
                normals.push_back((v1 % v2).normalize());
            }

            double minDist = 1e37;
            for(j = 1; j <= bones; ++j) {
                const Vector3 &v1 = match[j],
                      &v2 = match[skeleton.fPrev()[j]];
                boneDists[i][j - 1] = sqrt(distsqToSeg(cPos, v1, v2));
                minDist = min(boneDists[i][j - 1], minDist);
            }
            for(j = 1; j <= bones; ++j) {
                //the reason we don't just pick the closest bone is so
                //that if two are equally close, both are factored in.
                if(boneDists[i][j - 1] > minDist * 1.0001)
                    continue;

                const Vector3 &v1 = match[j],
                      &v2 = match[skeleton.fPrev()[j]];
                Vector3 p = projToSeg(cPos, v1, v2);
                boneVis[i][j - 1] = tester->canSee(cPos, p)
                    && vectorInCone(cPos - p, normals);
            }
        }

        //We have -Lw+Hw=HI, same as (H-L)w=HI, with (H-L)=DA (with
        //D=diag(1./area)) so w = A^-1 (HI/D)

        vector<vector<pair<int, double> > > A(nv);
        vector<double> D(nv, 0.), H(nv, 0.);
        vector<int> closest(nv, -1);
        for(i = 0; i < nv; ++i) {
            //get areas
            for(j = 0; j < (int)edges[i].size(); ++j) {
                int nj = (j + 1) % edges[i].size();

                D[i] += ((mesh.vertices[edges[i][j]].pos -
                            mesh.vertices[i].pos) %
                         (mesh.vertices[edges[i][nj]].pos -
                          mesh.vertices[i].pos)).length();
            }
            D[i] = 1. / (1e-10 + D[i]);

            //get bones
            double minDist = 1e37;
            for(j = 0; j < bones; ++j) {
                if(boneDists[i][j] < minDist) {
                    closest[i] = j;
                    minDist = boneDists[i][j];
                }
            }
            for(j = 0; j < bones; ++j)
                if(boneVis[i][j] && boneDists[i][j] <= minDist * 1.00001)
                    H[i] += 1. / SQR(1e-8 + boneDists[i][closest[i]]);

            //get laplacian
            double sum = 0.;
            for(j = 0; j < (int)edges[i].size(); ++j) {
                int nj = (j + 1) % edges[i].size();
                int pj = (j + edges[i].size() - 1) % edges[i].size();

                Vector3 v1 = mesh.vertices[i].pos -
                    mesh.vertices[edges[i][pj]].pos;
                Vector3 v2 = mesh.vertices[edges[i][j]].pos -
                    mesh.vertices[edges[i][pj]].pos;
                Vector3 v3 = mesh.vertices[i].pos -
                    mesh.vertices[edges[i][nj]].pos;
                Vector3 v4 = mesh.vertices[edges[i][j]].pos -
                    mesh.vertices[edges[i][nj]].pos;

                double cot1 = (v1 * v2) / (1e-6 + (v1 % v2).length());
                double cot2 = (v3 * v4) / (1e-6 + (v3 % v4).length());
                sum += (cot1 + cot2);

                // check for triangular here because sum should be
                // computed regardless
                if(edges[i][j] > i)
                    continue;
                A[i].push_back(make_pair(edges[i][j], -cot1 - cot2));
            }

            A[i].push_back(make_pair(i, sum + H[i] / D[i]));

            sort(A[i].begin(), A[i].end());
        }

        nzweights.resize(nv);
        SPDMatrix Am(A);
        LLTMatrix *Ainv = Am.factor();
        if(Ainv == NULL)
            return;

        for(j = 0; j < bones; ++j) {
            vector<double> rhs(nv, 0.);
            for(i = 0; i < nv; ++i) {
                if(boneVis[i][j] && boneDists[i][j] <=
                        boneDists[i][closest[i]] * 1.00001)
                    rhs[i] = H[i] / D[i];
            }

            Ainv->solve(rhs);
            for(i = 0; i < nv; ++i) {
                if(rhs[i] > 1.)
                    rhs[i] = 1.; //clip just in case
                if(rhs[i] > 1e-8)
                    nzweights[i].push_back(make_pair(j, rhs[i]));
            }
        }

        for(i = 0; i < nv; ++i) {
            double sum = 0.;
            for(j = 0; j < (int)nzweights[i].size(); ++j)
                sum += nzweights[i][j].second;

            for(j = 0; j < (int)nzweights[i].size(); ++j) {
                nzweights[i][j].second /= sum;
                weights[i][nzweights[i][j].first] = nzweights[i][j].second;
            }
        }

        delete Ainv;
        return;
    }

    Mesh deform(const Mesh &mesh, const vector<Transform<> > &transforms)
        const
    {
        Mesh out = mesh;
        Tbx::Dual_quat_cu dquat_blend = Tbx::Dual_quat_cu::identity();
        int i, nv = mesh.vertices.size();

        if(mesh.vertices.size() != weights.size())
            return out; //error

        for(i = 0; i < nv; ++i) {
            int j;
            int nbones = (int)nzweights[i].size();
            Tbx::Quat_cu q0;

            // inititialize the first dual quaternion
            if (nbones == 0) {
                dquat_blend = Tbx::Dual_quat_cu::identity();
                q0 = dquat_blend.rotation();
            } else {
                Tbx::Dual_quat_cu dquat =
                    getQuatFromMat(transforms[nzweights[i][0].first]);
                dquat_blend = dquat * nzweights[i][0].second;
                q0 = dquat.rotation();
            }

            for(j = 1; j < nbones; ++j) {
                float w = nzweights[i][j].second;
                const Tbx::Dual_quat_cu& dq =
                    (nzweights[i][j].second <= 0) ?
                    Tbx::Dual_quat_cu::identity() :
                    getQuatFromMat(transforms[nzweights[i][j].first]);

                // find shortest rotation
                if (dq.rotation().dot(q0) < 0.f)
                    w *= -1.f;

                dquat_blend = dquat_blend + dq * w;

             //   newPos += ((transforms[nzweights[i][j].first] *
             //               out.vertices[i].pos) * nzweights[i][j].second);
            }

            // Transform the vertex
            out.vertices[i].pos = transformPoint(out.vertices[i].pos,
                                                dquat_blend);
        }
        out.computeVertexNormals();

        return out;
    }

    Vector<double, -1> getWeights(int i) const { return weights[i]; }

    AttachmentPrivate *clone() const
    {
        AttachmentPrivate1 *out = new AttachmentPrivate1();
        *out = *this;
        return out;
    }

private:
    vector<Vector<double, -1> > weights;
    vector<vector<pair<int, double> > > nzweights; //sparse representation
};

Attachment::~Attachment()
{
    if(a)
        delete a;
}

Attachment::Attachment(const Attachment &att)
{
    a = att.a->clone();
}

Vector<double, -1> Attachment::getWeights(int i) const {
    return a->getWeights(i);
}

Mesh Attachment::deform(const Mesh &mesh,
        const vector<Transform<> > &transforms) const
{
    return a->deform(mesh, transforms);
}

Attachment::Attachment(const Mesh &mesh, const Skeleton &skeleton,
        const vector<Vector3> &match, const VisibilityTester *tester)
{
    a = new AttachmentPrivate1(mesh, skeleton, match, tester);
}
<commit_msg>added capability to merge results of both LBS and DQS<commit_after>/*  This file is part of the Pinocchio automatic rigging library.
    Copyright (C) 2007 Ilya Baran (ibaran@mit.edu)

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

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <fstream>
#include <sstream>
#include "attachment.h"
#include "vecutils.h"
#include "lsqSolver.h"

class AttachmentPrivate
{
public:
    AttachmentPrivate() {}
    virtual ~AttachmentPrivate() {}
    virtual Mesh deform(const Mesh &mesh,
            const vector<Transform<> > &transforms) const = 0;
    virtual Vector<double, -1> getWeights(int i) const = 0;
    virtual AttachmentPrivate *clone() const = 0;
};

bool vectorInCone(const Vector3 &v, const vector<Vector3> &ns)
{
    int i;
    Vector3 avg;
    for(i = 0; i < (int)ns.size(); ++i)
        avg += ns[i];

    return v.normalize() * avg.normalize() > 0.5;
}

class AttachmentPrivate1 : public AttachmentPrivate {
public:
    AttachmentPrivate1() {}

    AttachmentPrivate1(const Mesh &mesh, const Skeleton &skeleton,
            const vector<Vector3> &match, const VisibilityTester *tester)
    {
        int i, j;
        int nv = mesh.vertices.size();
        //compute edges
        vector<vector<int> > edges(nv);

        for(i = 0; i < nv; ++i) {
            int cur, start;
            cur = start = mesh.vertices[i].edge;
            do {
                edges[i].push_back(mesh.edges[cur].vertex);
                cur = mesh.edges[mesh.edges[cur].prev].twin;
            } while(cur != start);
        }

        weights.resize(nv);
        int bones = skeleton.fGraph().verts.size() - 1;

        // initialize the weights vectors so they are big enough
        for(i = 0; i < nv; ++i)
            weights[i][bones - 1] = 0.;

        vector<vector<double> > boneDists(nv);
        vector<vector<bool> > boneVis(nv);

        for(i = 0; i < nv; ++i) {
            boneDists[i].resize(bones, -1);
            boneVis[i].resize(bones);
            Vector3 cPos = mesh.vertices[i].pos;

            vector<Vector3> normals;
            for(j = 0; j < (int)edges[i].size(); ++j) {
                int nj = (j + 1) % edges[i].size();
                Vector3 v1 = mesh.vertices[edges[i][j]].pos - cPos;
                Vector3 v2 = mesh.vertices[edges[i][nj]].pos - cPos;
                normals.push_back((v1 % v2).normalize());
            }

            double minDist = 1e37;
            for(j = 1; j <= bones; ++j) {
                const Vector3 &v1 = match[j],
                      &v2 = match[skeleton.fPrev()[j]];
                boneDists[i][j - 1] = sqrt(distsqToSeg(cPos, v1, v2));
                minDist = min(boneDists[i][j - 1], minDist);
            }
            for(j = 1; j <= bones; ++j) {
                //the reason we don't just pick the closest bone is so
                //that if two are equally close, both are factored in.
                if(boneDists[i][j - 1] > minDist * 1.0001)
                    continue;

                const Vector3 &v1 = match[j],
                      &v2 = match[skeleton.fPrev()[j]];
                Vector3 p = projToSeg(cPos, v1, v2);
                boneVis[i][j - 1] = tester->canSee(cPos, p)
                    && vectorInCone(cPos - p, normals);
            }
        }

        //We have -Lw+Hw=HI, same as (H-L)w=HI, with (H-L)=DA (with
        //D=diag(1./area)) so w = A^-1 (HI/D)

        vector<vector<pair<int, double> > > A(nv);
        vector<double> D(nv, 0.), H(nv, 0.);
        vector<int> closest(nv, -1);
        for(i = 0; i < nv; ++i) {
            //get areas
            for(j = 0; j < (int)edges[i].size(); ++j) {
                int nj = (j + 1) % edges[i].size();

                D[i] += ((mesh.vertices[edges[i][j]].pos -
                            mesh.vertices[i].pos) %
                         (mesh.vertices[edges[i][nj]].pos -
                          mesh.vertices[i].pos)).length();
            }
            D[i] = 1. / (1e-10 + D[i]);

            //get bones
            double minDist = 1e37;
            for(j = 0; j < bones; ++j) {
                if(boneDists[i][j] < minDist) {
                    closest[i] = j;
                    minDist = boneDists[i][j];
                }
            }
            for(j = 0; j < bones; ++j)
                if(boneVis[i][j] && boneDists[i][j] <= minDist * 1.00001)
                    H[i] += 1. / SQR(1e-8 + boneDists[i][closest[i]]);

            //get laplacian
            double sum = 0.;
            for(j = 0; j < (int)edges[i].size(); ++j) {
                int nj = (j + 1) % edges[i].size();
                int pj = (j + edges[i].size() - 1) % edges[i].size();

                Vector3 v1 = mesh.vertices[i].pos -
                    mesh.vertices[edges[i][pj]].pos;
                Vector3 v2 = mesh.vertices[edges[i][j]].pos -
                    mesh.vertices[edges[i][pj]].pos;
                Vector3 v3 = mesh.vertices[i].pos -
                    mesh.vertices[edges[i][nj]].pos;
                Vector3 v4 = mesh.vertices[edges[i][j]].pos -
                    mesh.vertices[edges[i][nj]].pos;

                double cot1 = (v1 * v2) / (1e-6 + (v1 % v2).length());
                double cot2 = (v3 * v4) / (1e-6 + (v3 % v4).length());
                sum += (cot1 + cot2);

                // check for triangular here because sum should be
                // computed regardless
                if(edges[i][j] > i)
                    continue;
                A[i].push_back(make_pair(edges[i][j], -cot1 - cot2));
            }

            A[i].push_back(make_pair(i, sum + H[i] / D[i]));

            sort(A[i].begin(), A[i].end());
        }

        nzweights.resize(nv);
        SPDMatrix Am(A);
        LLTMatrix *Ainv = Am.factor();
        if(Ainv == NULL)
            return;

        for(j = 0; j < bones; ++j) {
            vector<double> rhs(nv, 0.);
            for(i = 0; i < nv; ++i) {
                if(boneVis[i][j] && boneDists[i][j] <=
                        boneDists[i][closest[i]] * 1.00001)
                    rhs[i] = H[i] / D[i];
            }

            Ainv->solve(rhs);
            for(i = 0; i < nv; ++i) {
                if(rhs[i] > 1.)
                    rhs[i] = 1.; //clip just in case
                if(rhs[i] > 1e-8)
                    nzweights[i].push_back(make_pair(j, rhs[i]));
            }
        }

        for(i = 0; i < nv; ++i) {
            double sum = 0.;
            for(j = 0; j < (int)nzweights[i].size(); ++j)
                sum += nzweights[i][j].second;

            for(j = 0; j < (int)nzweights[i].size(); ++j) {
                nzweights[i][j].second /= sum;
                weights[i][nzweights[i][j].first] = nzweights[i][j].second;
            }
        }

        delete Ainv;
        return;
    }

    Mesh deform(const Mesh &mesh, const vector<Transform<> > &transforms)
        const
    {
        int DQ = 0, LB = 1, MIX = 2;
        int type = MIX;
        Mesh out = mesh;
        Tbx::Dual_quat_cu dquat_blend = Tbx::Dual_quat_cu::identity();
        int i, nv = mesh.vertices.size();

        if(mesh.vertices.size() != weights.size())
            return out; //error

        for(i = 0; i < nv; ++i) {
            int j;
            int nbones = (int)nzweights[i].size();
            Tbx::Quat_cu q0;
            Vector3 newPos;

            if (type == MIX || type == DQ) {
                // inititialize the first dual quaternion
                if (nbones == 0) {
                    dquat_blend = Tbx::Dual_quat_cu::identity();
                    q0 = dquat_blend.rotation();
                } else {
                    Tbx::Dual_quat_cu dquat =
                        getQuatFromMat(transforms[nzweights[i][0].first]);
                    dquat_blend = dquat * nzweights[i][0].second;
                    q0 = dquat.rotation();
                }
            }
            if (type != DQ) {
                // init first transform for linear blend
                newPos += ((transforms[nzweights[i][0].first] *
                       out.vertices[i].pos) * nzweights[i][0].second);
            }

            for(j = 1; j < nbones; ++j) {
                float w = nzweights[i][j].second;

                if (type == MIX || type == DQ) {
                    const Tbx::Dual_quat_cu& dq =
                        (nzweights[i][j].second <= 0) ?
                        Tbx::Dual_quat_cu::identity() :
                        getQuatFromMat(transforms[nzweights[i][j].first]);

                    // find shortest rotation
                    if (dq.rotation().dot(q0) < 0.f)
                        w *= -1.f;

                    dquat_blend = dquat_blend + dq * w;
                }

                if (type != DQ)
                    newPos += ((transforms[nzweights[i][j].first] *
                        out.vertices[i].pos) * nzweights[i][j].second);
            }

            // Transform the vertex
            Vector3 dqpos = out.vertices[i].pos;
            if (type == DQ || type == MIX) {
                dqpos = transformPoint(out.vertices[i].pos, dquat_blend);
                out.vertices[i].pos = dqpos;
            }
            if (type == LB || type == MIX)
                out.vertices[i].pos = newPos;
            if (type == MIX)
                out.vertices[i].pos = newPos * .5 + dqpos * .5;

        }
        out.computeVertexNormals();

        return out;
    }

    Vector<double, -1> getWeights(int i) const { return weights[i]; }

    AttachmentPrivate *clone() const
    {
        AttachmentPrivate1 *out = new AttachmentPrivate1();
        *out = *this;
        return out;
    }

private:
    vector<Vector<double, -1> > weights;
    vector<vector<pair<int, double> > > nzweights; //sparse representation
};

Attachment::~Attachment()
{
    if(a)
        delete a;
}

Attachment::Attachment(const Attachment &att)
{
    a = att.a->clone();
}

Vector<double, -1> Attachment::getWeights(int i) const {
    return a->getWeights(i);
}

Mesh Attachment::deform(const Mesh &mesh,
        const vector<Transform<> > &transforms) const
{
    return a->deform(mesh, transforms);
}

Attachment::Attachment(const Mesh &mesh, const Skeleton &skeleton,
        const vector<Vector3> &match, const VisibilityTester *tester)
{
    a = new AttachmentPrivate1(mesh, skeleton, match, tester);
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Arista Networks, Inc.  All rights reserved.
// Arista Networks, Inc. Confidential and Proprietary.

#include "eos/policy_map.h"

namespace eos {

policy_map_mgr::policy_map_mgr() {
}

policy_map_mgr::~policy_map_mgr() {
}

policy_map_action_t::~policy_map_action_t() {
}

policy_map_handler::policy_map_handler(policy_map_mgr * mgr) : base_handler(mgr) {
}

void
policy_map_handler::on_policy_map_sync_fail(policy_map_key_t const & key,
                                            std::string const & message) {
   // TODO: no op impl.
}

void
policy_map_handler::on_policy_map_sync(policy_map_key_t const & key) {
   // TODO: no op impl.
}

}
<commit_msg>@1781343 Fix stubs coverage test<commit_after>// Copyright (c) 2014 Arista Networks, Inc.  All rights reserved.
// Arista Networks, Inc. Confidential and Proprietary.

#include "eos/policy_map.h"

namespace eos {

policy_map_mgr::policy_map_mgr() {
}

policy_map_mgr::~policy_map_mgr() {
}

policy_map_action_t::~policy_map_action_t() {
}

policy_map_handler::policy_map_handler(policy_map_mgr * mgr) : base_handler(mgr) {
}

void
policy_map_handler::watch_policy_feature(policy_map_key_t const & key,
                                         bool interest) {
   // TODO: no op impl.
}

void
policy_map_handler::on_policy_map_sync_fail(policy_map_key_t const & key,
                                            std::string const & message) {
   // TODO: no op impl.
}

void
policy_map_handler::on_policy_map_sync(policy_map_key_t const & key) {
   // TODO: no op impl.
}

}
<|endoftext|>


<commit_before>#include "SceneDialog.h"
#include "Globals.h"

SceneDialog* SceneDialog::sInstance = NULL;

void TW_CALL SceneDialog::OpenMeshDialog(void *clientData)
{
	int index = (int)clientData;
	SceneDialog::GetInstance()->SetCurrentMesh(index);
}
void TW_CALL SceneDialog::OpenParticleSystemDialog(void *clientData)
{
	int index = (int)clientData;
	SceneDialog::GetInstance()->SetCurrentParticleSystem(index);
}
void TW_CALL SceneDialog::OpenMaterialDialog(void *clientData)
{
	int index = (int)clientData;
	SceneDialog::GetInstance()->SetCurrentMaterial(index);
}
void TW_CALL SceneDialog::OpenMergeDialog(void *clientData)
{
	SceneDialog::GetInstance()->m_materialDialog->hide();
	SceneDialog::GetInstance()->m_particleSystemDialog->hide();
	SceneDialog::GetInstance()->m_meshDialog->hide();
	SceneDialog::GetInstance()->m_mergeDialog->show();
}
void TW_CALL SceneDialog::SetCOSystem(void *clientData)
{
	int index = (int)clientData;
	if (index == 0)
	{
		//FLIP X
		AglMatrix mat(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 1)
	{
		//FLIP Y
		AglMatrix mat(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 2)
	{
		//FLIP Z
		AglMatrix mat(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 3)
	{
		//ROTATE X
		AglMatrix mat(1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1);
		mat = AglMatrix::inverse(mat);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 4)
	{
		//ROTATE Y
		AglMatrix mat(0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1);
		mat = AglMatrix::inverse(mat);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 5)
	{
		//ROTATE Z
		AglMatrix mat(0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
		mat = AglMatrix::inverse(mat);
		Scene::GetInstance()->Transform(mat);
	}
}

void TW_CALL SceneDialog::LoadAGL(void *clientData)
{
	SceneDialog* sceneDialog = (SceneDialog*)clientData;
	string file = openfilename("Agile Files (*.agl*)\0*.agl*\0");
	if (file != "")
	{
		AGLLoader::GetInstance()->Load(file);

		vector<Mesh*> meshes = Scene::GetInstance()->GetMeshes();
		for (unsigned int i = 0; i < meshes.size(); i++)
		{
			string s = "Mesh" + toString(i+1);
			string info = " label='" + s + "' help='Load an Agile file into the editor.' group='Meshes' label='" + meshes[i]->GetName() + "'";

			TwAddButton(sceneDialog->m_dialog, s.c_str(), OpenMeshDialog, (void*)i, info.c_str());
		}
		vector<AglMaterial*> materials = Scene::GetInstance()->GetMaterials();
		for (unsigned int i = 0; i < materials.size(); i++)
		{
			sceneDialog->AddMaterial(materials[i]);
		}

		TwAddButton(sceneDialog->m_dialog, "Merge", OpenMergeDialog, NULL, "");

		TwAddButton(sceneDialog->m_dialog, "AddMaterial", AddMaterial, sceneDialog, " label='Material' key=c help='Load an Agile file into the editor.' group='Add'");
		TwAddButton(sceneDialog->m_dialog, "AddParticleEffect", AddPE, sceneDialog, " label='Particle Effect' key=c help='Load an Agile file into the editor.' group='Add'");

		TwAddButton(sceneDialog->m_dialog, "FLIPX", SetCOSystem, (void*)0, " label='Flip X' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		TwAddButton(sceneDialog->m_dialog, "FLIPY", SetCOSystem, (void*)1, " label='Flip Y' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		TwAddButton(sceneDialog->m_dialog, "FLIPZ", SetCOSystem, (void*)2, " label='Flip Z' key=c help='Load an Agile file into the editor.' group='Coordinate System'");

		TwAddButton(sceneDialog->m_dialog, "Rot90X", SetCOSystem, (void*)3, " label='Rotate 90 X' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		TwAddButton(sceneDialog->m_dialog, "Rot90Y", SetCOSystem, (void*)4, " label='Rotate 90 Y' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		TwAddButton(sceneDialog->m_dialog, "Rot90Z", SetCOSystem, (void*)5, " label='Rotate 90 Z' key=c help='Load an Agile file into the editor.' group='Coordinate System'");

		//TwAddButton(sceneDialog->m_dialog, "Sys1", SetCOSystem, (void*)3, " label='Up: Y Forward: Z L' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		//TwAddButton(sceneDialog->m_dialog, "Sys2", SetCOSystem, (void*)4, " label='Up: Z Forward: -X L' key=c help='Load an Agile file into the editor.' group='Coordinate System'");

		TwAddVarRW(sceneDialog->m_dialog, "Sphere", TW_TYPE_BOOLCPP, &DRAWDEBUGSPHERE, "group='Debug'");
		TwAddVarRW(sceneDialog->m_dialog, "Box", TW_TYPE_BOOLCPP, &DRAWDEBUGBOX, "group='Debug'");

		vector<AglConnectionPoint> cps = Scene::GetInstance()->getConnectionPoints();
		for (unsigned int i = 0; i < cps.size(); i++)
		{
			string name = Scene::GetInstance()->GetName(cps[i].nameID);
			TwAddButton(sceneDialog->m_dialog, name.c_str(), NULL, (void*)0, "group='Connection Points'");
		}
		TwAddVarRW(sceneDialog->m_dialog, "Base Size", TW_TYPE_FLOAT, Scene::GetInstance()->GetConPointLengthPtr(), "group='Connection Points' min=0.0 max=1.0 step=0.001");

		vector<ParticleSystem*> ps = Scene::GetInstance()->GetParticleSystems();
		for (unsigned int i = 0; i < ps.size(); i++)
		{
			sceneDialog->AddPE(ps[i]->getParticleSystem(), i);
		}

		TwAddVarRW(sceneDialog->m_dialog, "Draw Scene Planes", TW_TYPE_BOOLCPP, Scene::GetInstance()->getDrawPlanes(), "group='Debug'");
	}
}
void TW_CALL SceneDialog::SaveAGL(void *clientData)
{
	string file = savefilename();
	if (file != "")
		Scene::GetInstance()->Save(file);
}
void TW_CALL SceneDialog::AddMaterial(void *clientData)
{
	SceneDialog* sceneDialog = (SceneDialog*)clientData;
	sceneDialog->AddMaterial(new AglMaterial());
}
void SceneDialog::AddMaterial(AglMaterial* pMaterial)
{
	if (pMaterial->id == -1)
		Scene::GetInstance()->AddMaterial(pMaterial, false, false);
	if (pMaterial->nameID == -1)
		pMaterial->nameID = Scene::GetInstance()->AddName("Material" + toString(pMaterial->id));
	string s = Scene::GetInstance()->GetName(pMaterial->nameID);
	string info = " label='" + s + "' group='Materials'";
	TwAddButton(m_dialog, ("Material" + toString(pMaterial->id)).c_str(), OpenMaterialDialog, (void*)pMaterial->id, info.c_str());
}
void TW_CALL SceneDialog::AddPE(void* clientData)
{
	SceneDialog* sceneDialog = (SceneDialog*)clientData;
	sceneDialog->AddPE(new AglParticleSystem(), Scene::GetInstance()->GetParticleSystems().size()-1);
}
void SceneDialog::AddPE(AglParticleSystem* pParticleSystem, int p_index)
{
	int index = p_index;
	if (Scene::GetInstance()->GetIndex(pParticleSystem) < 0)
	{
		Scene::GetInstance()->AddParticleSystem(pParticleSystem);
		index = Scene::GetInstance()->GetIndex(pParticleSystem);
	}
	string s = "NoName";
	string info = " label='" + s + "' group='Particle Effects'";
	TwAddButton(m_dialog, ("Particle Effect" + toString(index)).c_str(), OpenParticleSystemDialog, (void*)index, info.c_str());
}
void SceneDialog::ClonePE(AglParticleSystemHeader pHeader)
{
	AglParticleSystem* ps = new AglParticleSystem(pHeader);
	Scene::GetInstance()->AddParticleSystem(ps);
	string s = "NoName";
	string info = " label='" + s + "' help='Load an Agile file into the editor.' group='Particle Effects'";
	int zero = Scene::GetInstance()->GetParticleSystems().size()-1;

	TwAddButton(this->m_dialog, ("Particle Effect" + toString(zero)).c_str(), OpenParticleSystemDialog, (void*)zero, info.c_str());
}

SceneDialog::SceneDialog()
{
	// Create a tweak bar
    m_dialog = TwNewBar("Scene");
    TwDefine(" GLOBAL help='This example shows how to integrate AntTweakBar into a DirectX11 application.' "); // Message added to the help bar.
	int barSize[2] = {200, 1060};
    TwSetParam(m_dialog, NULL, "size", TW_PARAM_INT32, 2, barSize);
	TwDefine(" Scene position='10 10' ");

	TwAddButton(m_dialog, "Load Scene", LoadAGL, this, " label='Load Scene' key=c help='Load an Agile file into the editor.' group='I/O'");
	TwAddButton(m_dialog, "Save Scene", SaveAGL, this, " label='Save Scene' key=c help='Save a scene into an Agile file.' group='I/O'");

	TwAddVarRW(m_dialog, "Rotation", TW_TYPE_QUAT4F, Scene::GetInstance()->GetQuaternionRotation(), "opened=true axisz=-z");

	TwStructMember pointMembers[] = {
        { "X", TW_TYPE_FLOAT, offsetof(AglVector3, x), " Step=0.01 " },
        { "Y", TW_TYPE_FLOAT, offsetof(AglVector3, y), " Step=0.01 " },
		{ "Z", TW_TYPE_FLOAT, offsetof(AglVector3, z), " Step=0.01 " }};
    TwType pointType = TwDefineStruct("POINT", pointMembers, 3, sizeof(AglVector3), NULL, NULL);

	TwAddVarRW(m_dialog, "Position", pointType, Scene::GetInstance()->GetPosition(), "");

	TwAddVarRW(m_dialog, "ShowHideDiffuse", TW_TYPE_BOOLCPP, &DIFFUSEON, "group='Show/Hide'");
	TwAddVarRW(m_dialog, "ShowHideSpec", TW_TYPE_BOOLCPP, &SPECULARON, "group='Show/Hide'");
	TwAddVarRW(m_dialog, "ShowHideGlow", TW_TYPE_BOOLCPP, &GLOWON, "group='Show/Hide'");
	TwAddVarRW(m_dialog, "ShowHideNormal", TW_TYPE_BOOLCPP, &NORMALON, "group='Show/Hide'");

	m_meshDialog = new MeshDialog();
	m_materialDialog = new MaterialDialog();
	m_particleSystemDialog = new ParticleSystemDialog();
	m_mergeDialog = new MergeDialog();
}
SceneDialog::~SceneDialog()
{
	delete m_meshDialog;
	delete m_materialDialog;
	delete m_particleSystemDialog;
	delete m_mergeDialog;
}

SceneDialog* SceneDialog::GetInstance()
{
	if (!sInstance)
		sInstance = new SceneDialog();
	return sInstance;
}
void SceneDialog::Release()
{
	delete sInstance;
}
void SceneDialog::SetCurrentMesh(int pIndex)
{
	m_materialDialog->hide();
	m_particleSystemDialog->hide();
	m_mergeDialog->hide();
	m_meshDialog->setMesh(pIndex);
}
void SceneDialog::SetCurrentParticleSystem(int pIndex)
{
	m_materialDialog->hide();
	m_meshDialog->hide();
	m_mergeDialog->hide();

	m_particleSystemDialog->setPS(pIndex);
}
void SceneDialog::SetCurrentMaterial(int pIndex)
{
	m_meshDialog->hide();
	m_particleSystemDialog->hide();
	m_mergeDialog->hide();

	m_materialDialog->setMaterial(pIndex);
}

void SceneDialog::RemoveMaterial(AglMaterial* pMaterial)
{
	vector<AglMaterial*> materials = Scene::GetInstance()->GetMaterials();
	for (unsigned int i = 0; i < materials.size(); i++)
	{
		string name = ("Material" + toString(materials[i]->id));
		TwRemoveVar(m_dialog, name.c_str());
	}
	Scene::GetInstance()->RemoveMaterial(pMaterial);
	materials = Scene::GetInstance()->GetMaterials();
	for (unsigned int i = 0; i < materials.size(); i++)
	{
		AddMaterial(materials[i]);
	}
}
void SceneDialog::RemoveParticleSystem(AglParticleSystem* pParticleSystem)
{
	vector<ParticleSystem*> ps = Scene::GetInstance()->GetParticleSystems();
	for (unsigned int i = 0; i < ps.size(); i++)
	{
		string name = "Particle Effect" + toString(i);
		TwRemoveVar(m_dialog, name.c_str());
	}
	Scene::GetInstance()->RemoveParticleSystem(pParticleSystem);
	ps = Scene::GetInstance()->GetParticleSystems();
	for (unsigned int i = 0; i < ps.size(); i++)
	{
		AddPE(ps[i]->getParticleSystem());
	}
}<commit_msg>Fixed editor particle issues<commit_after>#include "SceneDialog.h"
#include "Globals.h"

SceneDialog* SceneDialog::sInstance = NULL;

void TW_CALL SceneDialog::OpenMeshDialog(void *clientData)
{
	int index = (int)clientData;
	SceneDialog::GetInstance()->SetCurrentMesh(index);
}
void TW_CALL SceneDialog::OpenParticleSystemDialog(void *clientData)
{
	int index = (int)clientData;
	SceneDialog::GetInstance()->SetCurrentParticleSystem(index);
}
void TW_CALL SceneDialog::OpenMaterialDialog(void *clientData)
{
	int index = (int)clientData;
	SceneDialog::GetInstance()->SetCurrentMaterial(index);
}
void TW_CALL SceneDialog::OpenMergeDialog(void *clientData)
{
	SceneDialog::GetInstance()->m_materialDialog->hide();
	SceneDialog::GetInstance()->m_particleSystemDialog->hide();
	SceneDialog::GetInstance()->m_meshDialog->hide();
	SceneDialog::GetInstance()->m_mergeDialog->show();
}
void TW_CALL SceneDialog::SetCOSystem(void *clientData)
{
	int index = (int)clientData;
	if (index == 0)
	{
		//FLIP X
		AglMatrix mat(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 1)
	{
		//FLIP Y
		AglMatrix mat(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 2)
	{
		//FLIP Z
		AglMatrix mat(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 3)
	{
		//ROTATE X
		AglMatrix mat(1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1);
		mat = AglMatrix::inverse(mat);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 4)
	{
		//ROTATE Y
		AglMatrix mat(0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1);
		mat = AglMatrix::inverse(mat);
		Scene::GetInstance()->Transform(mat);
	}
	else if (index == 5)
	{
		//ROTATE Z
		AglMatrix mat(0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
		mat = AglMatrix::inverse(mat);
		Scene::GetInstance()->Transform(mat);
	}
}

void TW_CALL SceneDialog::LoadAGL(void *clientData)
{
	SceneDialog* sceneDialog = (SceneDialog*)clientData;
	string file = openfilename("Agile Files (*.agl*)\0*.agl*\0");
	if (file != "")
	{
		AGLLoader::GetInstance()->Load(file);

		vector<Mesh*> meshes = Scene::GetInstance()->GetMeshes();
		for (unsigned int i = 0; i < meshes.size(); i++)
		{
			string s = "Mesh" + toString(i+1);
			string info = " label='" + s + "' help='Load an Agile file into the editor.' group='Meshes' label='" + meshes[i]->GetName() + "'";

			TwAddButton(sceneDialog->m_dialog, s.c_str(), OpenMeshDialog, (void*)i, info.c_str());
		}
		vector<AglMaterial*> materials = Scene::GetInstance()->GetMaterials();
		for (unsigned int i = 0; i < materials.size(); i++)
		{
			sceneDialog->AddMaterial(materials[i]);
		}

		TwAddButton(sceneDialog->m_dialog, "Merge", OpenMergeDialog, NULL, "");

		TwAddButton(sceneDialog->m_dialog, "AddMaterial", AddMaterial, sceneDialog, " label='Material' key=c help='Load an Agile file into the editor.' group='Add'");
		TwAddButton(sceneDialog->m_dialog, "AddParticleEffect", AddPE, sceneDialog, " label='Particle Effect' key=c help='Load an Agile file into the editor.' group='Add'");

		TwAddButton(sceneDialog->m_dialog, "FLIPX", SetCOSystem, (void*)0, " label='Flip X' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		TwAddButton(sceneDialog->m_dialog, "FLIPY", SetCOSystem, (void*)1, " label='Flip Y' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		TwAddButton(sceneDialog->m_dialog, "FLIPZ", SetCOSystem, (void*)2, " label='Flip Z' key=c help='Load an Agile file into the editor.' group='Coordinate System'");

		TwAddButton(sceneDialog->m_dialog, "Rot90X", SetCOSystem, (void*)3, " label='Rotate 90 X' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		TwAddButton(sceneDialog->m_dialog, "Rot90Y", SetCOSystem, (void*)4, " label='Rotate 90 Y' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		TwAddButton(sceneDialog->m_dialog, "Rot90Z", SetCOSystem, (void*)5, " label='Rotate 90 Z' key=c help='Load an Agile file into the editor.' group='Coordinate System'");

		//TwAddButton(sceneDialog->m_dialog, "Sys1", SetCOSystem, (void*)3, " label='Up: Y Forward: Z L' key=c help='Load an Agile file into the editor.' group='Coordinate System'");
		//TwAddButton(sceneDialog->m_dialog, "Sys2", SetCOSystem, (void*)4, " label='Up: Z Forward: -X L' key=c help='Load an Agile file into the editor.' group='Coordinate System'");

		TwAddVarRW(sceneDialog->m_dialog, "Sphere", TW_TYPE_BOOLCPP, &DRAWDEBUGSPHERE, "group='Debug'");
		TwAddVarRW(sceneDialog->m_dialog, "Box", TW_TYPE_BOOLCPP, &DRAWDEBUGBOX, "group='Debug'");

		vector<AglConnectionPoint> cps = Scene::GetInstance()->getConnectionPoints();
		for (unsigned int i = 0; i < cps.size(); i++)
		{
			string name = Scene::GetInstance()->GetName(cps[i].nameID);
			TwAddButton(sceneDialog->m_dialog, name.c_str(), NULL, (void*)0, "group='Connection Points'");
		}
		TwAddVarRW(sceneDialog->m_dialog, "Base Size", TW_TYPE_FLOAT, Scene::GetInstance()->GetConPointLengthPtr(), "group='Connection Points' min=0.0 max=1.0 step=0.001");

		vector<ParticleSystem*> ps = Scene::GetInstance()->GetParticleSystems();
		for (unsigned int i = 0; i < ps.size(); i++)
		{
			sceneDialog->AddPE(ps[i]->getParticleSystem(), i);
		}

		TwAddVarRW(sceneDialog->m_dialog, "Draw Scene Planes", TW_TYPE_BOOLCPP, Scene::GetInstance()->getDrawPlanes(), "group='Debug'");
	}
}
void TW_CALL SceneDialog::SaveAGL(void *clientData)
{
	string file = savefilename();
	if (file != "")
		Scene::GetInstance()->Save(file);
}
void TW_CALL SceneDialog::AddMaterial(void *clientData)
{
	SceneDialog* sceneDialog = (SceneDialog*)clientData;
	sceneDialog->AddMaterial(new AglMaterial());
}
void SceneDialog::AddMaterial(AglMaterial* pMaterial)
{
	if (pMaterial->id == -1)
		Scene::GetInstance()->AddMaterial(pMaterial, false, false);
	if (pMaterial->nameID == -1)
		pMaterial->nameID = Scene::GetInstance()->AddName("Material" + toString(pMaterial->id));
	string s = Scene::GetInstance()->GetName(pMaterial->nameID);
	string info = " label='" + s + "' group='Materials'";
	TwAddButton(m_dialog, ("Material" + toString(pMaterial->id)).c_str(), OpenMaterialDialog, (void*)pMaterial->id, info.c_str());
}
void TW_CALL SceneDialog::AddPE(void* clientData)
{
	SceneDialog* sceneDialog = (SceneDialog*)clientData;
	sceneDialog->AddPE(new AglParticleSystem(), Scene::GetInstance()->GetParticleSystems().size()-1);
}
void SceneDialog::AddPE(AglParticleSystem* pParticleSystem, int p_index)
{
	int index = p_index;
	if (Scene::GetInstance()->GetIndex(pParticleSystem) < 0)
	{
		Scene::GetInstance()->AddParticleSystem(pParticleSystem);
		index = Scene::GetInstance()->GetIndex(pParticleSystem);
	}
	string s = "NoName";
	string info = " label='" + s + "' group='Particle Effects'";
	TwAddButton(m_dialog, ("Particle Effect" + toString(index)).c_str(), OpenParticleSystemDialog, (void*)index, info.c_str());
}
void SceneDialog::ClonePE(AglParticleSystemHeader pHeader)
{
	AglParticleSystem* ps = new AglParticleSystem(pHeader);
	Scene::GetInstance()->AddParticleSystem(ps);
	string s = "NoName";
	string info = " label='" + s + "' help='Load an Agile file into the editor.' group='Particle Effects'";
	int zero = Scene::GetInstance()->GetParticleSystems().size()-1;

	TwAddButton(this->m_dialog, ("Particle Effect" + toString(zero)).c_str(), OpenParticleSystemDialog, (void*)zero, info.c_str());
}

SceneDialog::SceneDialog()
{
	// Create a tweak bar
    m_dialog = TwNewBar("Scene");
    TwDefine(" GLOBAL help='This example shows how to integrate AntTweakBar into a DirectX11 application.' "); // Message added to the help bar.
	int barSize[2] = {200, 1060};
    TwSetParam(m_dialog, NULL, "size", TW_PARAM_INT32, 2, barSize);
	TwDefine(" Scene position='10 10' ");

	TwAddButton(m_dialog, "Load Scene", LoadAGL, this, " label='Load Scene' key=c help='Load an Agile file into the editor.' group='I/O'");
	TwAddButton(m_dialog, "Save Scene", SaveAGL, this, " label='Save Scene' key=c help='Save a scene into an Agile file.' group='I/O'");

	TwAddVarRW(m_dialog, "Rotation", TW_TYPE_QUAT4F, Scene::GetInstance()->GetQuaternionRotation(), "opened=true axisz=-z");

	TwStructMember pointMembers[] = {
        { "X", TW_TYPE_FLOAT, offsetof(AglVector3, x), " Step=0.01 " },
        { "Y", TW_TYPE_FLOAT, offsetof(AglVector3, y), " Step=0.01 " },
		{ "Z", TW_TYPE_FLOAT, offsetof(AglVector3, z), " Step=0.01 " }};
    TwType pointType = TwDefineStruct("POINT", pointMembers, 3, sizeof(AglVector3), NULL, NULL);

	TwAddVarRW(m_dialog, "Position", pointType, Scene::GetInstance()->GetPosition(), "");

	TwAddVarRW(m_dialog, "ShowHideDiffuse", TW_TYPE_BOOLCPP, &DIFFUSEON, "group='Show/Hide'");
	TwAddVarRW(m_dialog, "ShowHideSpec", TW_TYPE_BOOLCPP, &SPECULARON, "group='Show/Hide'");
	TwAddVarRW(m_dialog, "ShowHideGlow", TW_TYPE_BOOLCPP, &GLOWON, "group='Show/Hide'");
	TwAddVarRW(m_dialog, "ShowHideNormal", TW_TYPE_BOOLCPP, &NORMALON, "group='Show/Hide'");

	m_meshDialog = new MeshDialog();
	m_materialDialog = new MaterialDialog();
	m_particleSystemDialog = new ParticleSystemDialog();
	m_mergeDialog = new MergeDialog();
}
SceneDialog::~SceneDialog()
{
	delete m_meshDialog;
	delete m_materialDialog;
	delete m_particleSystemDialog;
	delete m_mergeDialog;
}

SceneDialog* SceneDialog::GetInstance()
{
	if (!sInstance)
		sInstance = new SceneDialog();
	return sInstance;
}
void SceneDialog::Release()
{
	delete sInstance;
}
void SceneDialog::SetCurrentMesh(int pIndex)
{
	m_materialDialog->hide();
	m_particleSystemDialog->hide();
	m_mergeDialog->hide();
	m_meshDialog->setMesh(pIndex);
}
void SceneDialog::SetCurrentParticleSystem(int pIndex)
{
	m_materialDialog->hide();
	m_meshDialog->hide();
	m_mergeDialog->hide();

	m_particleSystemDialog->setPS(pIndex);
}
void SceneDialog::SetCurrentMaterial(int pIndex)
{
	m_meshDialog->hide();
	m_particleSystemDialog->hide();
	m_mergeDialog->hide();

	m_materialDialog->setMaterial(pIndex);
}

void SceneDialog::RemoveMaterial(AglMaterial* pMaterial)
{
	vector<AglMaterial*> materials = Scene::GetInstance()->GetMaterials();
	for (unsigned int i = 0; i < materials.size(); i++)
	{
		string name = ("Material" + toString(materials[i]->id));
		TwRemoveVar(m_dialog, name.c_str());
	}
	Scene::GetInstance()->RemoveMaterial(pMaterial);
	materials = Scene::GetInstance()->GetMaterials();
	for (unsigned int i = 0; i < materials.size(); i++)
	{
		AddMaterial(materials[i]);
	}
}
void SceneDialog::RemoveParticleSystem(AglParticleSystem* pParticleSystem)
{
	vector<ParticleSystem*> ps = Scene::GetInstance()->GetParticleSystems();
	for (unsigned int i = 0; i < ps.size(); i++)
	{
		string name = "Particle Effect" + toString(i);
		TwRemoveVar(m_dialog, name.c_str());
	}
	Scene::GetInstance()->RemoveParticleSystem(pParticleSystem);
	ps = Scene::GetInstance()->GetParticleSystems();
	for (unsigned int i = 0; i < ps.size(); i++)
	{
		AddPE(ps[i]->getParticleSystem(), i);
	}
}<|endoftext|>


<commit_before>//
// Created by Esha Uboweja on 12/5/16.
//

#include "BinaryLayer.h"
#include "TestBinaryConvolution.h"

#define DEBUG 1

using namespace bd;
using namespace bconv;

void TestBinaryConvolution::printTestArma2(std::string testName, std::string desc, arma::mat input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma cube " << desc << " : \n" << input << std::endl;
#endif
}

void TestBinaryConvolution::printTestUArma2(std::string testName, std::string desc, arma::umat input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma cube " << desc << " : \n" << input << std::endl;
#endif
}

void TestBinaryConvolution::printTestBM(std::string testName, std::string desc, BinaryMatrix input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] binary tensor3d " << desc << " : \n";
    input.print();
    std::cout << std::endl;
#endif
}

void TestBinaryConvolution::printTestArma3(std::string testName, std::string desc, arma::cube input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma cube " << desc << " : \n" << input << std::endl;
#endif
}

void TestBinaryConvolution::printTestUArma3(std::string testName, std::string desc, arma::ucube input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma cube " << desc << " : \n" << input << std::endl;
#endif
}

void TestBinaryConvolution::printTestBT3(std::string testName, std::string desc, BinaryTensor3D input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] binary tensor3d " << desc << " : \n"
              << input.toString() << std::endl;
#endif
}

void TestBinaryConvolution::printTestUArma4(std::string testName, std::string desc, ArmaUTensor4D input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma tensor4D" << desc << " : \n";
    for (uint f = 0; f < input.size(); ++f) {
        std::cout << "[ARMA FILTER #" << f << "]:\n" << input[f] << std::endl;
    }
#endif
}

void TestBinaryConvolution::printTestBT4(std::string testName, std::string desc, BinaryTensor4D input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] binary tensor4d " << desc << " : \n"
              << BinaryConvolution::bt4ToString(input) << std::endl;
#endif
}

template<typename T>
void TestBinaryConvolution::printTestVec(std::string testName, std::string desc, std::vector<T> input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] vector " << desc << " : \n";
    for (auto value : input) {
        std::cout << value << std::endl;
    }
    std::cout << std::endl;
#endif
}

bool TestBinaryConvolution::test_convolution_single(uint rows_in, uint cols_in, uint width, uint height,
                                                    uint channels, uint filters, uint stride,
                                                    Convolution conv_type) {

    std::string testName = "test_convolution_single";

    BinaryConvolution bconv = BinaryConvolution(width, height, channels, filters, stride, conv_type, Nonlinearity::none,
                                                Pooling::none);

    // Generate a random input matrix
    arma::cube input3D = BinaryTensor3D::randomArmaCube(rows_in, cols_in, channels);
    printTestArma3(testName, "Arma Input3D", input3D);

    // Normalize the input
    arma::cube norm_input3D = bconv.normalizeData3D(input3D);
    printTestArma3(testName, "Arma Normalized Input3D", norm_input3D);
/*
    // Compute K beta matrix
    arma::mat K = bconv.input2KMat(norm_input3D);
    printTestArma2(testName, "Arma K betas for input", K);

    // Generate a random weights matrix
    ArmaUTensor4D armaWeights4D = BinaryConvolution::randomTensor4DUArma(width, height, channels, filters);
    printTestUArma4(testName, "Arma weights 4D", armaWeights4D);

    std::vector<double> alphaPerFilter;
    alphaPerFilter.reserve(filters);
    for (uint f = 0; f < filters; ++f) {
        alphaPerFilter.emplace_back(1.0);
    }
    printTestVec(testName, "weights 4D alphas", alphaPerFilter);

    BinaryTensor4D bt4Weights4D = BinaryConvolution::uarmaToBT4(armaWeights4D);
    printTestBT4(testName, "Binary weights 4D", bt4Weights4D);
    bconv.setWeights(bt4Weights4D);
*/

    return true;
}

bool TestBinaryConvolution::test_convolution() {
    return test_convolution_single();
}

void TestBinaryConvolution::runAllTests() {
    std::cout << "----Testing BinaryConvolution class functions...\n";
    bool result = test_convolution();
    std::cout << "[TestBinaryConvolution] Tests completed! Result = " << (result? "PASSED" : "FAILED") << std::endl;
}<commit_msg>input2K gives desired output<commit_after>//
// Created by Esha Uboweja on 12/5/16.
//

#include "BinaryLayer.h"
#include "TestBinaryConvolution.h"

#define DEBUG 1

using namespace bd;
using namespace bconv;

void TestBinaryConvolution::printTestArma2(std::string testName, std::string desc, arma::mat input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma cube " << desc << " : \n" << input << std::endl;
#endif
}

void TestBinaryConvolution::printTestUArma2(std::string testName, std::string desc, arma::umat input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma cube " << desc << " : \n" << input << std::endl;
#endif
}

void TestBinaryConvolution::printTestBM(std::string testName, std::string desc, BinaryMatrix input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] binary tensor3d " << desc << " : \n";
    input.print();
    std::cout << std::endl;
#endif
}

void TestBinaryConvolution::printTestArma3(std::string testName, std::string desc, arma::cube input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma cube " << desc << " : \n" << input << std::endl;
#endif
}

void TestBinaryConvolution::printTestUArma3(std::string testName, std::string desc, arma::ucube input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma cube " << desc << " : \n" << input << std::endl;
#endif
}

void TestBinaryConvolution::printTestBT3(std::string testName, std::string desc, BinaryTensor3D input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] binary tensor3d " << desc << " : \n"
              << input.toString() << std::endl;
#endif
}

void TestBinaryConvolution::printTestUArma4(std::string testName, std::string desc, ArmaUTensor4D input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] arma tensor4D" << desc << " : \n";
    for (uint f = 0; f < input.size(); ++f) {
        std::cout << "[ARMA FILTER #" << f << "]:\n" << input[f] << std::endl;
    }
#endif
}

void TestBinaryConvolution::printTestBT4(std::string testName, std::string desc, BinaryTensor4D input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] binary tensor4d " << desc << " : \n"
              << BinaryConvolution::bt4ToString(input) << std::endl;
#endif
}

template<typename T>
void TestBinaryConvolution::printTestVec(std::string testName, std::string desc, std::vector<T> input) {
#ifdef DEBUG
    std::cout << "[TestBinaryConvolution::" << testName << "] vector " << desc << " : \n";
    for (auto value : input) {
        std::cout << value << std::endl;
    }
    std::cout << std::endl;
#endif
}

bool TestBinaryConvolution::test_convolution_single(uint rows_in, uint cols_in, uint width, uint height,
                                                    uint channels, uint filters, uint stride,
                                                    Convolution conv_type) {

    std::string testName = "test_convolution_single";

    BinaryConvolution bconv = BinaryConvolution(width, height, channels, filters, stride, conv_type, Nonlinearity::none,
                                                Pooling::none);

    // Generate a random input matrix
    arma::cube input3D = BinaryTensor3D::randomArmaCube(rows_in, cols_in, channels);
    printTestArma3(testName, "Arma Input3D", input3D);

    // Normalize the input
    arma::cube norm_input3D = bconv.normalizeData3D(input3D);
    printTestArma3(testName, "Arma Normalized Input3D", norm_input3D);

    // Compute K beta matrix
    arma::mat K = bconv.input2KMat(norm_input3D);
    printTestArma2(testName, "Arma K betas for input", K);

/*
    // Generate a random weights matrix
    ArmaUTensor4D armaWeights4D = BinaryConvolution::randomTensor4DUArma(width, height, channels, filters);
    printTestUArma4(testName, "Arma weights 4D", armaWeights4D);

    std::vector<double> alphaPerFilter;
    alphaPerFilter.reserve(filters);
    for (uint f = 0; f < filters; ++f) {
        alphaPerFilter.emplace_back(1.0);
    }
    printTestVec(testName, "weights 4D alphas", alphaPerFilter);

    BinaryTensor4D bt4Weights4D = BinaryConvolution::uarmaToBT4(armaWeights4D);
    printTestBT4(testName, "Binary weights 4D", bt4Weights4D);
    bconv.setWeights(bt4Weights4D);
*/

    return true;
}

bool TestBinaryConvolution::test_convolution() {
    return test_convolution_single();
}

void TestBinaryConvolution::runAllTests() {
    std::cout << "----Testing BinaryConvolution class functions...\n";
    bool result = test_convolution();
    std::cout << "[TestBinaryConvolution] Tests completed! Result = " << (result? "PASSED" : "FAILED") << std::endl;
}<|endoftext|>


<commit_before>#pragma once

#include <functional>
#include <memory>

#include "Runtime/GuiSys/CGuiCompoundWidget.hpp"

namespace urde {
class CSimplePool;

class CGuiSliderGroup : public CGuiCompoundWidget {
public:
  enum class EState { None, Decreasing, Increasing, MouseMove };

private:
  float xb8_minVal;
  float xbc_maxVal;
  float xc0_roundedCurVal;
  float xc4_curVal;
  float xc8_increment;
  CGuiWidget* xcc_sliderRangeWidgets[2] = {};
  std::function<void(CGuiSliderGroup*, float)> xd8_changeCallback;
  EState xf0_state = EState::None;
  union {
    struct {
      bool xf4_24_inputPending : 1;
      mutable bool m_mouseInside : 1;
      bool m_mouseDown : 1;
    };
    u32 _dummy = 0;
  };

  mutable float m_mouseT = 0.f;

  void StartDecreasing();
  void StartIncreasing();

public:
  CGuiSliderGroup(const CGuiWidgetParms& parms, float a, float b, float c, float d);
  FourCC GetWidgetTypeID() const override { return FOURCC('SLGP'); }

  EState GetState() const { return xf0_state; }
  void SetSelectionChangedCallback(std::function<void(CGuiSliderGroup*, float)>&& func);
  void SetIncrement(float inc) { xc8_increment = inc; }
  void SetMinVal(float min) {
    xb8_minVal = min;
    SetCurVal(xc0_roundedCurVal);
  }
  void SetMaxVal(float max) {
    xbc_maxVal = max;
    SetCurVal(xc0_roundedCurVal);
  }
  void SetCurVal(float cur);
  float GetGurVal() const { return xc0_roundedCurVal; }

  bool TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const override;

  void ProcessUserInput(const CFinalInput& input) override;
  void Update(float dt) override;

  bool AddWorkerWidget(CGuiWidget* worker) override;
  CGuiWidget* GetWorkerWidget(int id) const override;

  static std::shared_ptr<CGuiWidget> Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp);
};

} // namespace urde
<commit_msg>CGuiSliderGroup: Make use of std::array where applicable<commit_after>#pragma once

#include <array>
#include <functional>
#include <memory>

#include "Runtime/GuiSys/CGuiCompoundWidget.hpp"

namespace urde {
class CSimplePool;

class CGuiSliderGroup : public CGuiCompoundWidget {
public:
  enum class EState { None, Decreasing, Increasing, MouseMove };

private:
  float xb8_minVal;
  float xbc_maxVal;
  float xc0_roundedCurVal;
  float xc4_curVal;
  float xc8_increment;
  std::array<CGuiWidget*, 2> xcc_sliderRangeWidgets{};
  std::function<void(CGuiSliderGroup*, float)> xd8_changeCallback;
  EState xf0_state = EState::None;
  union {
    struct {
      bool xf4_24_inputPending : 1;
      mutable bool m_mouseInside : 1;
      bool m_mouseDown : 1;
    };
    u32 _dummy = 0;
  };

  mutable float m_mouseT = 0.f;

  void StartDecreasing();
  void StartIncreasing();

public:
  CGuiSliderGroup(const CGuiWidgetParms& parms, float a, float b, float c, float d);
  FourCC GetWidgetTypeID() const override { return FOURCC('SLGP'); }

  EState GetState() const { return xf0_state; }
  void SetSelectionChangedCallback(std::function<void(CGuiSliderGroup*, float)>&& func);
  void SetIncrement(float inc) { xc8_increment = inc; }
  void SetMinVal(float min) {
    xb8_minVal = min;
    SetCurVal(xc0_roundedCurVal);
  }
  void SetMaxVal(float max) {
    xbc_maxVal = max;
    SetCurVal(xc0_roundedCurVal);
  }
  void SetCurVal(float cur);
  float GetGurVal() const { return xc0_roundedCurVal; }

  bool TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const override;

  void ProcessUserInput(const CFinalInput& input) override;
  void Update(float dt) override;

  bool AddWorkerWidget(CGuiWidget* worker) override;
  CGuiWidget* GetWorkerWidget(int id) const override;

  static std::shared_ptr<CGuiWidget> Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp);
};

} // namespace urde
<|endoftext|>


<commit_before>#include <cmath>
#include <cstdlib>
#include <iostream>
#include "mpi.h"
#include "pipe.h"
#include <pthread.h>
#include <set>
#include <string>
#include "unistd.h"
#include <vector>
#include <map>

using namespace std;

const int element_shape_x = 5;
const int element_shape_y = 6;

const int mpi_shape_x = 4;
const int mpi_shape_y = 3;

//// const int element_shape_x = 20;
//// const int element_shape_y = 18;
////
//// const int mpi_shape_x = 1;
//// const int mpi_shape_y = 1;

const int shape_x = element_shape_x * mpi_shape_x;
const int shape_y = element_shape_y * mpi_shape_y;
const int shape_t = 300;

int mpi_rank;
int mpi_size;

int wrap_x(const int x) {
  return (x+shape_x)%shape_x;
}
int wrap_y(const int y) {
  return (y+shape_y)%shape_y;
}
int irand(const int hi) {
  return floor(rand()/double(RAND_MAX)*hi);
}
enum Direction{
  TP,
  XP,
  XM,
  YP,
  YM
};

struct Region{
  int t,x,y;
  Region() {}
  Region(int t,int x,int y) : t(t), x(wrap_x(x)), y(wrap_y(y)) {}

  bool operator==(const Region &other) const {
    return other.t==t && other.x==x && other.y==y;
  }
  bool operator!=(const Region &other) {
    return !(*this == other);
  }
  bool operator<(const Region &other) const {
    return t<other.t || (t==other.t && (x<other.x || (x==other.x && y<other.y)));
  }
};

ostream& operator<<(ostream& ostr, const Region& r) {
  ostr << "("
       << r.t << ","
       << r.x << ","
       << r.y << ")";
  return ostr;
}

struct Facet{
  Direction d;
  int t,x,y;
  Facet() {}
  Facet(Direction d,int t,int x,int y) : d(d), t(t), x(wrap_x(x)), y(wrap_y(y)) {}
  bool operator<(const Facet &other) const {
    return d<other.d || (d==other.d && (t<other.t || (t==other.t && (x<other.x || (x==other.x && y<other.y)))));
  }

};
ostream& operator<<(ostream& ostr, const Facet& f) {
  ostr << "("
       << f.d << ","
       << f.t << ","
       << f.x << ","
       << f.y << ")";
  return ostr;
}

struct Task {
  Region region;
  vector<Facet> facets;
  Task() {}
  Task(const Region& r) : region(r), facets() {}
  Task(const Region& r, const vector<Facet> fs) : region(r), facets(fs) {}
  bool operator<(const Task &other) const {
    return region < other.region;
  }
};

Region random_region() {
  return Region(irand(shape_t), irand(shape_x), irand(shape_y));
}

Region prev_region(const Facet &f) {
  return Region(f.t, f.x, f.y);
}
Region next_region(const Facet &f) {
  switch(f.d) {
  case TP:
    return Region(f.t + 1, f.x, f.y);
  case XP:
    return Region(f.t, f.x + 1, f.y);
  case XM:
    return Region(f.t, f.x - 1, f.y);
  case YP:
    return Region(f.t, f.x, f.y + 1);
  case YM:
    return Region(f.t, f.x, f.y - 1);
  }
}

vector<Facet> prev_facets(const Region &r) {
  vector<Facet> ret;
  if (r.t < shape_t) ret.push_back(Facet(TP, r.t - 1, r.x, r.y));
  if (r.t&1 != r.x%2) {
    ret.push_back( Facet(XP, r.t, r.x-1, r.y) );
    ret.push_back( Facet(XM, r.t, r.x+1, r.y) );
  }
  if (r.t&1 != r.y%2) {
    ret.push_back( Facet(YP, r.t, r.x, r.y-1) );
    ret.push_back( Facet(YM, r.t, r.x, r.y+1) );
  }/*
  if (r == Region(0,6,15)) {
    for (const auto &v : ret) {
      cout << v << endl;
    }
    exit(0);
    }*/

  return ret;
}
vector<Facet> next_facets(const Region &r) {
  vector<Facet> ret;
  if (r.t < shape_t -1) ret.push_back(Facet(TP, r.t, r.x, r.y));
  if (r.t%2 == r.x%2) {
    ret.push_back( Facet(XP, r.t, r.x, r.y) );
    ret.push_back( Facet(XM, r.t, r.x, r.y) );
  }
  if (r.t%2 == r.y%2) {
    ret.push_back( Facet(YP, r.t, r.x, r.y) );
    ret.push_back( Facet(YM, r.t, r.x, r.y) );
  }
  return ret;
}

int rank_assingment(const Region &r) {
  int rx = r.x / element_shape_x;
  int ry = r.y / element_shape_y;
  return ry * mpi_shape_x + rx;
}

vector<Facet> initial_facets() {
  vector<Facet> ret;

  int rx = mpi_rank % mpi_shape_x;
  int ry = mpi_rank % mpi_shape_y;
  for (int j = 0; j < element_shape_y; ++j) {
    for (int i = 0; i < element_shape_x; ++i) {
      ret.push_back(Facet(TP,-1,rx*element_shape_x+i, ry*element_shape_y+j));
    }
  }
  return ret;
}

set<Facet> facet_pool;
set<Task> task_pool;

pipe_producer_t* inbound_facet_producer;
pipe_consumer_t* inbound_facet_consumer;
pipe_producer_t* outbound_facet_producer;
pipe_consumer_t* outbound_facet_consumer;
pipe_producer_t* task_producer;
pipe_consumer_t* task_consumer;

void add_facet_event(const Facet &f) {
  facet_pool.insert(f);
  Region r = next_region(f);
  vector<Facet> fs = prev_facets(r);
  bool all_found = true;
  Task task(r);
  for (int i=0;i<fs.size();++i) {
    set<Facet>::iterator fit = facet_pool.find(fs[i]);
    if(fit == facet_pool.end()){
      cerr << "for region : " << r << " missing facet:  " << (fs[i]) << endl;
      all_found = false;
      break;
    } else {
      task.facets.push_back(*fit);
    }
  }
  if (all_found) {
    pipe_push(task_producer, &task, 1);
  }
}

void send_facet(const Facet &f) {
  int dest = rank_assingment(next_region(f));
  if (dest == mpi_rank) {
    pipe_push(inbound_facet_producer, &f, 1);
  } else {
    pipe_push(outbound_facet_producer, &f, 1);
  }
}

void actually_compute_the_task (const Task &task) {
  cerr << "rank " << mpi_rank << " computes region: " << task.region << endl;
  usleep(10000);
}

void* thread_process_task(void* arg) {

  Task task;
  for(;;) {
    size_t n = pipe_pop(task_consumer, &task, 1);
    if (n <= 0) return NULL;
    actually_compute_the_task(task);

    vector<Facet> next_fs = next_facets(task.region);
    for (int i=0;i<next_fs.size();++i) {
      send_facet(next_fs[i]);
    }
    for (int i=0;i<task.facets.size();++i) {
      facet_pool.erase(task.facets[i]);
    }
  }
}

void* thread_recv(void* arg) {
  Facet f;
  MPI_Status status;
  for(;;) {
    MPI_Recv(&f, sizeof(Facet), MPI_BYTE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    pipe_push(inbound_facet_producer, &f, 1);
  }
}
void* thread_send(void* arg) {
  Facet f;
  for(;;) {
    size_t n = pipe_pop(outbound_facet_consumer, &f, 1);
    if(n<=0) return NULL;
    int dest=rank_assingment(next_region(f));
    MPI_Send((void*)(&f), sizeof(Facet), MPI_BYTE, dest, 0, MPI_COMM_WORLD);
  }
}
void* thread_create_task(void* arg) {
  Facet f;
  for(;;) {
    size_t n = pipe_pop(inbound_facet_consumer, &f, 1);
    if(n<=0) return NULL;
    add_facet_event(f);
  }
}

int test(){
  cout << "ping" << endl;
  cout << "pong" << endl;

  cout << sizeof(Region) << endl;
  cout << sizeof(Facet) << endl;

  for(int i=0;i<1000000; ++i) {
    Region r = random_region();
    vector<Facet> fs = next_facets(r);
    for (int j=0; j< fs.size(); ++j) {
      Facet &f=fs[j];
      if(prev_region(f) != r) {
        cout << "wrong facet " << endl;
        cout << r << endl;
      }
    }
  }

  for(int i=0;i<1000000; ++i) {
    Region r = random_region();
    vector<Facet> fs = prev_facets(r);
    for (int j=0; j< fs.size(); ++j) {
      Facet &f=fs[j];
      if(next_region(f) != r) {
        cout << "wrong facet " << endl;
        cout << r << endl;
        cout << next_region(f) << endl;
        return -1;
      }
    }
  }

  {
    map<int, int> ctr;
    for(int j=0;j<shape_y; ++j) {
      for(int i=0;i<shape_x; ++i) {
        Region r(0,i,j);
        ctr[rank_assingment(r)]++;
      }
    }
    for(map<int,int>::iterator it=ctr.begin(); it!=ctr.end();++it) {
      cout << it->first << " " << it->second << endl;
    }

  }
  return 0;
}

void init_pipes() {
  {
    pipe_t* p = pipe_new(sizeof(Facet), 0);
    inbound_facet_producer = pipe_producer_new(p);
    inbound_facet_consumer = pipe_consumer_new(p);
    pipe_free(p);
  }
  {
    pipe_t* p = pipe_new(sizeof(Facet), 0);
    outbound_facet_producer = pipe_producer_new(p);
    outbound_facet_consumer = pipe_consumer_new(p);
    pipe_free(p);
  }
  {
    pipe_t* p = pipe_new(sizeof(Task), 0);
    task_producer = pipe_producer_new(p);
    task_consumer = pipe_consumer_new(p);
    pipe_free(p);
  }
}

void free_pipes() {
  pipe_producer_free(inbound_facet_producer);
  pipe_consumer_free(inbound_facet_consumer);
  pipe_producer_free(outbound_facet_producer);
  pipe_consumer_free(outbound_facet_consumer);
  pipe_producer_free(task_producer);
  pipe_consumer_free(task_consumer);
}

int main(int argc, char **argv){

  int provided;
  MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
  if (provided < MPI_THREAD_MULTIPLE) {
    cerr << "Uwa, hikusugi? :" << provided <<endl;
    MPI_Init_thread(&argc, &argv, provided, &provided);
  }

  MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);

  init_pipes();

  pthread_t tid_recv; pthread_create(&tid_recv, NULL, thread_recv, NULL);
  pthread_t tid_send; pthread_create(&tid_send, NULL, thread_send, NULL);
  pthread_t tid_task; pthread_create(&tid_task, NULL, thread_create_task, NULL);

  vector<Facet> ifs = initial_facets();
  for (int i=0;i<ifs.size(); ++i) {
    add_facet_event(ifs[i]);
  }

  thread_process_task(NULL);

  free_pipes();

  MPI_Finalize();
}
<commit_msg>downgrade the requirement.<commit_after>#include <cmath>
#include <cstdlib>
#include <iostream>
#include "mpi.h"
#include "pipe.h"
#include <pthread.h>
#include <set>
#include <string>
#include "unistd.h"
#include <vector>
#include <map>

using namespace std;

const int element_shape_x = 5;
const int element_shape_y = 6;

const int mpi_shape_x = 4;
const int mpi_shape_y = 3;

//// const int element_shape_x = 20;
//// const int element_shape_y = 18;
////
//// const int mpi_shape_x = 1;
//// const int mpi_shape_y = 1;

const int shape_x = element_shape_x * mpi_shape_x;
const int shape_y = element_shape_y * mpi_shape_y;
const int shape_t = 300;

int mpi_rank;
int mpi_size;

int wrap_x(const int x) {
  return (x+shape_x)%shape_x;
}
int wrap_y(const int y) {
  return (y+shape_y)%shape_y;
}
int irand(const int hi) {
  return floor(rand()/double(RAND_MAX)*hi);
}
enum Direction{
  TP,
  XP,
  XM,
  YP,
  YM
};

struct Region{
  int t,x,y;
  Region() {}
  Region(int t,int x,int y) : t(t), x(wrap_x(x)), y(wrap_y(y)) {}

  bool operator==(const Region &other) const {
    return other.t==t && other.x==x && other.y==y;
  }
  bool operator!=(const Region &other) {
    return !(*this == other);
  }
  bool operator<(const Region &other) const {
    return t<other.t || (t==other.t && (x<other.x || (x==other.x && y<other.y)));
  }
};

ostream& operator<<(ostream& ostr, const Region& r) {
  ostr << "("
       << r.t << ","
       << r.x << ","
       << r.y << ")";
  return ostr;
}

struct Facet{
  Direction d;
  int t,x,y;
  Facet() {}
  Facet(Direction d,int t,int x,int y) : d(d), t(t), x(wrap_x(x)), y(wrap_y(y)) {}
  bool operator<(const Facet &other) const {
    return d<other.d || (d==other.d && (t<other.t || (t==other.t && (x<other.x || (x==other.x && y<other.y)))));
  }

};
ostream& operator<<(ostream& ostr, const Facet& f) {
  ostr << "("
       << f.d << ","
       << f.t << ","
       << f.x << ","
       << f.y << ")";
  return ostr;
}

struct Task {
  Region region;
  vector<Facet> facets;
  Task() {}
  Task(const Region& r) : region(r), facets() {}
  Task(const Region& r, const vector<Facet> fs) : region(r), facets(fs) {}
  bool operator<(const Task &other) const {
    return region < other.region;
  }
};

Region random_region() {
  return Region(irand(shape_t), irand(shape_x), irand(shape_y));
}

Region prev_region(const Facet &f) {
  return Region(f.t, f.x, f.y);
}
Region next_region(const Facet &f) {
  switch(f.d) {
  case TP:
    return Region(f.t + 1, f.x, f.y);
  case XP:
    return Region(f.t, f.x + 1, f.y);
  case XM:
    return Region(f.t, f.x - 1, f.y);
  case YP:
    return Region(f.t, f.x, f.y + 1);
  case YM:
    return Region(f.t, f.x, f.y - 1);
  }
}

vector<Facet> prev_facets(const Region &r) {
  vector<Facet> ret;
  if (r.t < shape_t) ret.push_back(Facet(TP, r.t - 1, r.x, r.y));
  if (r.t&1 != r.x%2) {
    ret.push_back( Facet(XP, r.t, r.x-1, r.y) );
    ret.push_back( Facet(XM, r.t, r.x+1, r.y) );
  }
  if (r.t&1 != r.y%2) {
    ret.push_back( Facet(YP, r.t, r.x, r.y-1) );
    ret.push_back( Facet(YM, r.t, r.x, r.y+1) );
  }/*
  if (r == Region(0,6,15)) {
    for (const auto &v : ret) {
      cout << v << endl;
    }
    exit(0);
    }*/

  return ret;
}
vector<Facet> next_facets(const Region &r) {
  vector<Facet> ret;
  if (r.t < shape_t -1) ret.push_back(Facet(TP, r.t, r.x, r.y));
  if (r.t%2 == r.x%2) {
    ret.push_back( Facet(XP, r.t, r.x, r.y) );
    ret.push_back( Facet(XM, r.t, r.x, r.y) );
  }
  if (r.t%2 == r.y%2) {
    ret.push_back( Facet(YP, r.t, r.x, r.y) );
    ret.push_back( Facet(YM, r.t, r.x, r.y) );
  }
  return ret;
}

int rank_assingment(const Region &r) {
  int rx = r.x / element_shape_x;
  int ry = r.y / element_shape_y;
  return ry * mpi_shape_x + rx;
}

vector<Facet> initial_facets() {
  vector<Facet> ret;

  int rx = mpi_rank % mpi_shape_x;
  int ry = mpi_rank % mpi_shape_y;
  for (int j = 0; j < element_shape_y; ++j) {
    for (int i = 0; i < element_shape_x; ++i) {
      ret.push_back(Facet(TP,-1,rx*element_shape_x+i, ry*element_shape_y+j));
    }
  }
  return ret;
}

set<Facet> facet_pool;
set<Task> task_pool;

pipe_producer_t* inbound_facet_producer;
pipe_consumer_t* inbound_facet_consumer;
pipe_producer_t* outbound_facet_producer;
pipe_consumer_t* outbound_facet_consumer;
pipe_producer_t* task_producer;
pipe_consumer_t* task_consumer;

void add_facet_event(const Facet &f) {
  facet_pool.insert(f);
  Region r = next_region(f);
  vector<Facet> fs = prev_facets(r);
  bool all_found = true;
  Task task(r);
  for (int i=0;i<fs.size();++i) {
    set<Facet>::iterator fit = facet_pool.find(fs[i]);
    if(fit == facet_pool.end()){
      cerr << "for region : " << r << " missing facet:  " << (fs[i]) << endl;
      all_found = false;
      break;
    } else {
      task.facets.push_back(*fit);
    }
  }
  if (all_found) {
    pipe_push(task_producer, &task, 1);
  }
}

void send_facet(const Facet &f) {
  int dest = rank_assingment(next_region(f));
  if (dest == mpi_rank) {
    pipe_push(inbound_facet_producer, &f, 1);
  } else {
    pipe_push(outbound_facet_producer, &f, 1);
  }
}

void actually_compute_the_task (const Task &task) {
  cerr << "rank " << mpi_rank << " computes region: " << task.region << endl;
  usleep(10000);
}

void* thread_process_task(void* arg) {

  Task task;
  for(;;) {
    size_t n = pipe_pop(task_consumer, &task, 1);
    if (n <= 0) return NULL;
    actually_compute_the_task(task);

    vector<Facet> next_fs = next_facets(task.region);
    for (int i=0;i<next_fs.size();++i) {
      send_facet(next_fs[i]);
    }
    for (int i=0;i<task.facets.size();++i) {
      facet_pool.erase(task.facets[i]);
    }
  }
}

void* thread_recv(void* arg) {
  Facet f;
  MPI_Status status;
  for(;;) {
    MPI_Recv(&f, sizeof(Facet), MPI_BYTE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    pipe_push(inbound_facet_producer, &f, 1);
  }
}
void* thread_send(void* arg) {
  Facet f;
  for(;;) {
    size_t n = pipe_pop(outbound_facet_consumer, &f, 1);
    if(n<=0) return NULL;
    int dest=rank_assingment(next_region(f));
    MPI_Send((void*)(&f), sizeof(Facet), MPI_BYTE, dest, 0, MPI_COMM_WORLD);
  }
}
void* thread_create_task(void* arg) {
  Facet f;
  for(;;) {
    size_t n = pipe_pop(inbound_facet_consumer, &f, 1);
    if(n<=0) return NULL;
    add_facet_event(f);
  }
}

int test(){
  cout << "ping" << endl;
  cout << "pong" << endl;

  cout << sizeof(Region) << endl;
  cout << sizeof(Facet) << endl;

  for(int i=0;i<1000000; ++i) {
    Region r = random_region();
    vector<Facet> fs = next_facets(r);
    for (int j=0; j< fs.size(); ++j) {
      Facet &f=fs[j];
      if(prev_region(f) != r) {
        cout << "wrong facet " << endl;
        cout << r << endl;
      }
    }
  }

  for(int i=0;i<1000000; ++i) {
    Region r = random_region();
    vector<Facet> fs = prev_facets(r);
    for (int j=0; j< fs.size(); ++j) {
      Facet &f=fs[j];
      if(next_region(f) != r) {
        cout << "wrong facet " << endl;
        cout << r << endl;
        cout << next_region(f) << endl;
        return -1;
      }
    }
  }

  {
    map<int, int> ctr;
    for(int j=0;j<shape_y; ++j) {
      for(int i=0;i<shape_x; ++i) {
        Region r(0,i,j);
        ctr[rank_assingment(r)]++;
      }
    }
    for(map<int,int>::iterator it=ctr.begin(); it!=ctr.end();++it) {
      cout << it->first << " " << it->second << endl;
    }

  }
  return 0;
}

void init_pipes() {
  {
    pipe_t* p = pipe_new(sizeof(Facet), 0);
    inbound_facet_producer = pipe_producer_new(p);
    inbound_facet_consumer = pipe_consumer_new(p);
    pipe_free(p);
  }
  {
    pipe_t* p = pipe_new(sizeof(Facet), 0);
    outbound_facet_producer = pipe_producer_new(p);
    outbound_facet_consumer = pipe_consumer_new(p);
    pipe_free(p);
  }
  {
    pipe_t* p = pipe_new(sizeof(Task), 0);
    task_producer = pipe_producer_new(p);
    task_consumer = pipe_consumer_new(p);
    pipe_free(p);
  }
}

void free_pipes() {
  pipe_producer_free(inbound_facet_producer);
  pipe_consumer_free(inbound_facet_consumer);
  pipe_producer_free(outbound_facet_producer);
  pipe_consumer_free(outbound_facet_consumer);
  pipe_producer_free(task_producer);
  pipe_consumer_free(task_consumer);
}

int main(int argc, char **argv){
  const int required = 2; //MPI_THREAD_MULTIPLE
  int provided;
  MPI_Init_thread(&argc, &argv, required, &provided);
  if (provided < MPI_THREAD_MULTIPLE) {
    cerr << "Uwa, hikusugi? :" << provided <<endl;
    MPI_Abort(MPI_COMM_WORLD, 42);
  }

  MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
  MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);

  init_pipes();

  pthread_t tid_recv; pthread_create(&tid_recv, NULL, thread_recv, NULL);
  pthread_t tid_send; pthread_create(&tid_send, NULL, thread_send, NULL);
  pthread_t tid_task; pthread_create(&tid_task, NULL, thread_create_task, NULL);

  vector<Facet> ifs = initial_facets();
  for (int i=0;i<ifs.size(); ++i) {
    add_facet_event(ifs[i]);
  }

  thread_process_task(NULL);

  free_pipes();

  MPI_Finalize();
}
<|endoftext|>


<commit_before>/*******************************************************************************
Name: Samuel Wenninger, Brandon Drumheller, and Malcolm Lorber
Date Created: 11-25-2015
Filename: bank.cpp
Description: Bank server that services requests from the ATM
             using the Boost library. Compile using the following:
             g++ -std=c++11 bank.cpp -lboost_system -lboost_thread -o bank.out
*******************************************************************************/

#include <iostream>
#include <string>
//#include <memory>
//#include <utility>
#include <vector>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include "validate.h"

using boost::asio::ip::tcp;

class User{
    public:
       User(std::string name, long long balance): name(name), balance(balance){}
    private:
        std::string name;
        long long balance;
        unsigned int pin;
};

/*******************************************************************************
 @DESC: The Session class is responsible for reading from the ATM socket and
        to the Bank socket.
 @ARGS: N/A
 @RTN:  N/A
*******************************************************************************/
class Session : public std::enable_shared_from_this<Session> {
    public:
        Session(tcp::socket Socket1)
            : bank_socket_(std::move(Socket1)) {}
        void Start() {
            DoRead();
        }
    private:
        //Read from the listen socket (ATM socket)
        void DoRead() {
            auto Self(shared_from_this());
            bank_socket_.async_read_some(boost::asio::buffer(data_, max_length),
            [this, Self](boost::system::error_code EC, std::size_t Length) {
                if (!EC) {
		    std::cout << "Message received: " << data_ << std::endl;
                    //instead of directly writing, perform the correct operation
                    if(std::string(data_).find("login") == 0){
                      sprintf(data_, "successful write to socket");
                    }
                    DoWrite(Length);
                }
            });
        }
        //Write to the bank socket
        void DoWrite(std::size_t Length) {
            auto Self(shared_from_this());
            boost::asio::async_write(bank_socket_,
                                            boost::asio::buffer(data_, Length),
                        [this, Self](boost::system::error_code EC, std::size_t){
                if (!EC) {
                    DoRead();
                }
            });
        }
        tcp::socket bank_socket_;
        //Max length of messages passed through the proxy
        enum {max_length = 1024};
        //Array to hold the incoming message
        char data_[max_length];
        //string data_;
};

/*******************************************************************************
 @DESC: The Server class is responsible for initializing the connection to both
        ATM and Bank ports and start a Session instance.
 @ARGS: N/A
 @RTN:  N/A
*******************************************************************************/
class Server {
    public:
        Server(boost::asio::io_service & IOService, int BankPort)
            //Call acceptor constructor with the bank's port as the endopoint
            //and assign result to acceptor_
            : bank_acceptor_(IOService, tcp::endpoint(tcp::v4(), BankPort)),
              bank_socket_(IOService) {
                DoAccept();
              }
    private:
        void DoAccept() {
            //Accept a new connection to the bank socket
            bank_acceptor_.async_accept(bank_socket_,
                                         [this](boost::system::error_code EC) {
                if (!EC) {
                        //Accept connection and start a session by calling the
                        //Session constructor
                        std::make_shared<Session>(std::move(bank_socket_)) -> Start();
                        }
                        DoAccept();
                    });
        }
        //Bank acceptor and socket
        tcp::acceptor bank_acceptor_;
        tcp::socket bank_socket_;
};

void CommandLine() {
    while (true) {
        std::string command;
        std::getline(std::cin, command);
        bool matched = IsValidBankCommand(command);
        if (!matched) {
            std::cerr << "INVALID COMMAND" << std::endl;
        }
        else {
            std::cout << command << std::endl;
        }
    }
}

/*******************************************************************************
 @DESC: Call appropriate function(s) to initiate communication between the ATM
        and the bank.
 @ARGS: port to listen on, port to connect to the bank
 @RTN:  EXIT_SUCCESS on success, EXIT_FAILURE on failure
*******************************************************************************/
int main (int argc, char* argv[]) {
    try {
        if (argc != 2) {
            std::cerr << "Incorrect number of arguments. Proper usage ./a.out"
                            " <bank-port>" << std::endl;
            return EXIT_FAILURE;
        }
        boost::thread Thread(CommandLine);
        boost::asio::io_service IOService;
        int BankPort = std::stoi(argv[1]);
        Server S(IOService, BankPort);
        //Throws an exception if something goes wrong
        IOService.run();
    }
    catch (std::exception & e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
    return EXIT_SUCCESS;
}
<commit_msg>Fixed issue of failing to read in full input line<commit_after>/*******************************************************************************
Name: Samuel Wenninger, Brandon Drumheller, and Malcolm Lorber
Date Created: 11-25-2015
Filename: bank.cpp
Description: Bank server that services requests from the ATM
             using the Boost library. Compile using the following:
             g++ -std=c++11 bank.cpp -lboost_system -lboost_thread -o bank.out
*******************************************************************************/

#include <iostream>
#include <string>
//#include <memory>
//#include <utility>
#include <vector>
#include <unordered_map>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include "validate.h"
#include <mutex>

using boost::asio::ip::tcp;

class User{
public:
    User(std::string name, long long balance): name(name), balance(balance){}
    void addMoney(long long money){balance += money;}
    void removeMoney(long long money){balance -= money;}
    long long getBalance(){return balance;}
    int getPin(){return pin;}
private:
    std::string name;
    long long balance;
    int pin;
};

class Bank{
public:
    Bank(){}
    bool login(std::string user, int pin){
        data_m.lock();

        if(users.count(user)!=1){
            data_m.unlock();
            return false;
        }
        if(users[user]->getPin() != pin){
            data_m.unlock();
            return false;
        }

        loggedin[user]=true;

        data_m.unlock();
        return true;
    }
    bool balance(std::string user, long long &retBal){
        data_m.lock();

        if(!loggedin[user]){
            data_m.unlock();
            return false;
        }
        retBal = users[user]->getBalance();

        data_m.unlock();
        return true;
    }
    bool withdraw(std::string user, long long amount){
        data_m.lock();

        if(!loggedin[user]){
            data_m.unlock();
            return false;
        }
        if(amount<=0){
            data_m.unlock();
            return false;
        }
        if(users[user]->getBalance()<amount){
            data_m.unlock();
            return false;
        }
        users[user]->removeMoney(amount);

        data_m.unlock();
        return true;
    }
    bool transfer(std::string user1, std::string user2, long long amount){
        data_m.lock();

        if(!loggedin[user1]){
            data_m.unlock();
            return false;
        }
        if(users[user1]->getBalance()<amount){
            data_m.unlock();
            return false;
        }
        if(amount<=0){
            data_m.unlock();
            return false;
        }
        if(users.count(user2)!=1){
            data_m.unlock();
            return false;
        }

        users[user1]->removeMoney(amount);
        users[user2]->addMoney(amount);

        data_m.unlock();
        return true;
    }
    bool logout(std::string user){
        data_m.lock();

        if(!loggedin[user]){
            data_m.unlock();
            return false;
        }

        loggedin[user]=false;

        data_m.unlock();
        return true;
    }
private:
    std::unordered_map<std::string, bool> loggedin;
    std::unordered_map<std::string, User*> users;
    std::mutex data_m;
};

/*******************************************************************************
 @DESC: The Session class is responsible for reading from the ATM socket and
        to the Bank socket.
 @ARGS: N/A
 @RTN:  N/A
*******************************************************************************/
class Session : public std::enable_shared_from_this<Session> {
    public:
        Session(tcp::socket Socket1)
            : bank_socket_(std::move(Socket1)) {}
        void Start() {
            DoRead();
        }
    private:
        //Read from the listen socket (ATM socket)
        void DoRead() {
            auto Self(shared_from_this());
            bank_socket_.async_read_some(boost::asio::buffer(data_, max_length),
            [this, Self](boost::system::error_code EC, std::size_t Length) {
                if (!EC) {
		    std::cout << "Message received: " << data_ << std::endl;
                    //instead of directly writing, perform the correct operation
                    if(std::string(data_).find("login") == 0){
                        sprintf(data_, "successful write to socket");
                    }
                    DoWrite(Length);
                }
            });
        }
        //Write to the bank socket
        void DoWrite(std::size_t Length) {
            auto Self(shared_from_this());
            boost::asio::async_write(bank_socket_,
                                            boost::asio::buffer(data_, Length),
                        [this, Self](boost::system::error_code EC, std::size_t){
                if (!EC) {
                    DoRead();
                }
            });
        }
        tcp::socket bank_socket_;
        //Max length of messages passed through the proxy
        enum {max_length = 1024};
        //Array to hold the incoming message
        char data_[max_length];
        //string data_;
};

/*******************************************************************************
 @DESC: The Server class is responsible for initializing the connection to both
        ATM and Bank ports and start a Session instance.
 @ARGS: N/A
 @RTN:  N/A
*******************************************************************************/
class Server {
    public:
        Server(boost::asio::io_service & IOService, int BankPort)
            //Call acceptor constructor with the bank's port as the endopoint
            //and assign result to acceptor_
            : bank_acceptor_(IOService, tcp::endpoint(tcp::v4(), BankPort)),
              bank_socket_(IOService) {
                DoAccept();
              }
    private:
        void DoAccept() {
            //Accept a new connection to the bank socket
            bank_acceptor_.async_accept(bank_socket_,
                                         [this](boost::system::error_code EC) {
                if (!EC) {
                        //Accept connection and start a session by calling the
                        //Session constructor
                        std::make_shared<Session>(std::move(bank_socket_)) -> Start();
                        }
                        DoAccept();
                    });
        }
        //Bank acceptor and socket
        tcp::acceptor bank_acceptor_;
        tcp::socket bank_socket_;
};

void CommandLine() {
    while (true) {
        std::string command;
        std::getline(std::cin, command);
        bool matched = IsValidBankCommand(command);
        if (!matched) {
            std::cerr << "INVALID COMMAND" << std::endl;
        }
        else {
            std::cout << command << std::endl;
        }
    }
}

/*******************************************************************************
 @DESC: Call appropriate function(s) to initiate communication between the ATM
        and the bank.
 @ARGS: port to listen on, port to connect to the bank
 @RTN:  EXIT_SUCCESS on success, EXIT_FAILURE on failure
*******************************************************************************/
int main (int argc, char* argv[]) {
    try {
        if (argc != 2) {
            std::cerr << "Incorrect number of arguments. Proper usage ./a.out"
                            " <bank-port>" << std::endl;
            return EXIT_FAILURE;
        }
        boost::thread Thread(CommandLine);
        boost::asio::io_service IOService;
        int BankPort = std::stoi(argv[1]);
        Server S(IOService, BankPort);
        //Throws an exception if something goes wrong
        IOService.run();
    }
    catch (std::exception & e) {
        std::cerr << "Exception: " << e.what() << std::endl;
    }
    return EXIT_SUCCESS;
}
<|endoftext|>