<commit_before>//
//  DialogueBoxSystem.cpp
//  Chilli Source
//  Created by Ian Copland on 04/03/2014.
//
//  The MIT License (MIT)
//
//  Copyright (c) 2014 Tag Games Limited
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

#ifdef CS_TARGETPLATFORM_ANDROID

#include <CSBackend/Platform/Android/Main/JNI/Core/DialogueBox/DialogueBoxSystem.h>

#include <CSBackend/Platform/Android/Main/JNI/Core/DialogueBox/DialogueBoxJavaInterface.h>
#include <CSBackend/Platform/Android/Main/JNI/Core/Java/JavaInterfaceManager.h>
#include <ChilliSource/Core/Base/Application.h>
#include <ChilliSource/Core/Base/PlatformSystem.h>

namespace CSBackend
{
	namespace Android
	{
        CS_DEFINE_NAMEDTYPE(DialogueBoxSystem);
        //----------------------------------------------------
        //----------------------------------------------------
        DialogueBoxSystem::DialogueBoxSystem()
        {
        	m_dialogueBoxJI = JavaInterfaceManager::GetSingletonPtr()->GetJavaInterface<DialogueBoxJavaInterface>();
        	if (m_dialogueBoxJI == nullptr)
        	{
        		m_dialogueBoxJI = std::make_shared<DialogueBoxJavaInterface>();
        		JavaInterfaceManager::GetSingletonPtr()->AddJavaInterface(m_dialogueBoxJI);
        	}
        }
        //----------------------------------------------------
        //----------------------------------------------------
        bool DialogueBoxSystem::IsA(ChilliSource::InterfaceIDType in_interfaceId) const
        {
            return (DialogueBoxSystem::InterfaceID == in_interfaceId || ChilliSource::DialogueBoxSystem::InterfaceID == in_interfaceId);
        }
        //-----------------------------------------------------
        //-----------------------------------------------------
        void DialogueBoxSystem::ShowSystemDialogue(u32 in_id, const ChilliSource::DialogueBoxSystem::DialogueDelegate& in_delegate, const std::string& in_title, const std::string& in_message, const std::string& in_confirm)
        {
        	m_dialogueBoxJI->ShowSystemDialogue(in_id, in_title, in_message, in_confirm);
            m_activeSysConfirmDelegate = in_delegate;
        }
        //-----------------------------------------------------
        //-----------------------------------------------------
        void DialogueBoxSystem::ShowSystemConfirmDialogue(u32 in_id, const ChilliSource::DialogueBoxSystem::DialogueDelegate& in_delegate, const std::string& in_title, const std::string& in_message, const std::string& in_confirm, const std::string& in_cancel)
        {
        	m_dialogueBoxJI->ShowSystemConfirmDialogue(in_id, in_title, in_message, in_confirm, in_cancel);
            m_activeSysConfirmDelegate = in_delegate;
        }
        //-----------------------------------------------------
        //-----------------------------------------------------
        void DialogueBoxSystem::MakeToast(const std::string& in_text)
        {
        	m_dialogueBoxJI->MakeToast(in_text);
        }
        //------------------------------------------------------
        //------------------------------------------------------
        void DialogueBoxSystem::OnSystemConfirmDialogueResult(u32 in_id, ChilliSource::DialogueBoxSystem::DialogueResult in_result)
        {
            if(m_activeSysConfirmDelegate)
        	{
        		m_activeSysConfirmDelegate(in_id, in_result);
        		m_activeSysConfirmDelegate = nullptr;
        	}
        }
        //-----------------------------------------------------
        //-----------------------------------------------------
        DialogueBoxSystem::~DialogueBoxSystem()
        {
        }
	}
}

#endif
<commit_msg>Android now uses system thread scheduling for dialogue boxes.<commit_after>//
//  DialogueBoxSystem.cpp
//  Chilli Source
//  Created by Ian Copland on 04/03/2014.
//
//  The MIT License (MIT)
//
//  Copyright (c) 2014 Tag Games Limited
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

#ifdef CS_TARGETPLATFORM_ANDROID

#include <CSBackend/Platform/Android/Main/JNI/Core/DialogueBox/DialogueBoxSystem.h>

#include <CSBackend/Platform/Android/Main/JNI/Core/DialogueBox/DialogueBoxJavaInterface.h>
#include <CSBackend/Platform/Android/Main/JNI/Core/Java/JavaInterfaceManager.h>
#include <ChilliSource/Core/Threading.h>
#include <ChilliSource/Core/Base/Application.h>
#include <ChilliSource/Core/Base/PlatformSystem.h>

namespace CSBackend
{
	namespace Android
	{
        CS_DEFINE_NAMEDTYPE(DialogueBoxSystem);
        //----------------------------------------------------
        //----------------------------------------------------
        DialogueBoxSystem::DialogueBoxSystem()
        {
        	m_dialogueBoxJI = JavaInterfaceManager::GetSingletonPtr()->GetJavaInterface<DialogueBoxJavaInterface>();
        	if (m_dialogueBoxJI == nullptr)
        	{
        		m_dialogueBoxJI = std::make_shared<DialogueBoxJavaInterface>();
        		JavaInterfaceManager::GetSingletonPtr()->AddJavaInterface(m_dialogueBoxJI);
        	}
        }
        //----------------------------------------------------
        //----------------------------------------------------
        bool DialogueBoxSystem::IsA(ChilliSource::InterfaceIDType in_interfaceId) const
        {
            return (DialogueBoxSystem::InterfaceID == in_interfaceId || ChilliSource::DialogueBoxSystem::InterfaceID == in_interfaceId);
        }
        //-----------------------------------------------------
        //-----------------------------------------------------
        void DialogueBoxSystem::ShowSystemDialogue(u32 in_id, const ChilliSource::DialogueBoxSystem::DialogueDelegate& in_delegate, const std::string& in_title, const std::string& in_message, const std::string& in_confirm)
        {
            CS::Application::Get()->GetTaskScheduler()->ScheduleTask(CS::TaskType::k_system, [=](const CS::TaskContext& in_taskContext)
            {
                m_dialogueBoxJI->ShowSystemDialogue(in_id, in_title, in_message, in_confirm);
                m_activeSysConfirmDelegate = in_delegate;
            });
        }
        //-----------------------------------------------------
        //-----------------------------------------------------
        void DialogueBoxSystem::ShowSystemConfirmDialogue(u32 in_id, const ChilliSource::DialogueBoxSystem::DialogueDelegate& in_delegate, const std::string& in_title, const std::string& in_message, const std::string& in_confirm, const std::string& in_cancel)
        {
            CS::Application::Get()->GetTaskScheduler()->ScheduleTask(CS::TaskType::k_system, [=](const CS::TaskContext& in_taskContext)
            {
                m_dialogueBoxJI->ShowSystemConfirmDialogue(in_id, in_title, in_message, in_confirm, in_cancel);
                m_activeSysConfirmDelegate = in_delegate;
            });
        }
        //-----------------------------------------------------
        //-----------------------------------------------------
        void DialogueBoxSystem::MakeToast(const std::string& in_text)
        {
            CS::Application::Get()->GetTaskScheduler()->ScheduleTask(CS::TaskType::k_system, [=](const CS::TaskContext& in_taskContext)
            {
                m_dialogueBoxJI->MakeToast(in_text);
            });
        }
        //------------------------------------------------------
        //------------------------------------------------------
        void DialogueBoxSystem::OnSystemConfirmDialogueResult(u32 in_id, ChilliSource::DialogueBoxSystem::DialogueResult in_result)
        {
            CS::Application::Get()->GetTaskScheduler()->ScheduleTask(CS::TaskType::k_system, [=](const CS::TaskContext& in_taskContext)
            {
                if (m_activeSysConfirmDelegate)
                {
                    m_activeSysConfirmDelegate(in_id, in_result);
                    m_activeSysConfirmDelegate = nullptr;
                }
            });
        }
        //-----------------------------------------------------
        //-----------------------------------------------------
        DialogueBoxSystem::~DialogueBoxSystem()
        {
        }
	}
}

#endif
<|endoftext|>


<commit_before>

#include <random>
#include "../../str_util.hpp"
#include "../../no_rt_util.h"
#include "../../tbl.hpp"
#include "../LavaFlow.hpp"

enum Slots
{
  GAUSS_IDXVERTS_OUT = 0

  //GAUSS_PARAMS_IN    = 0,
  //GAUSS_IDXVERTS_OUT = 1
};

namespace RNG
{
  using rng_t  = ::std::mt19937;
  using urng_t = ::std::unique_ptr<rng_t>;

  //extern __declspec(thread) rng_t*  m_genPtr;
  //
  //void Init(int s);
  //void Destruct();

  rng_t   gen(0);
  rng_t*  m_genPtr = &gen; //nullptr;

  void Init(int s)
  {
    //if (m_genPtr == nullptr) {
    //  m_genPtr = new rng_t(s);
    //}
  }
  void Destruct()
  {
    //if(m_genPtr != nullptr)
    //  delete m_genPtr;
  }
}

float     randomf(float lo, float hi)
{
  ::std::uniform_real_distribution<float> dis(lo, hi);
  return dis(*RNG::m_genPtr);
}

void           PrintLavaMem(LavaMem lm)
{
  if(lm.ptr)
    printf("\n addr: %llu  data addr: %llu  ref count: %llu   size bytes: %llu \n",
      (u64)(lm.ptr), (u64)(lm.data()), (u64)lm.refCount(), (u64)lm.sizeBytes() );
}
void           PrintTblMem(tbl const& t)
{
  if( !t.m_mem ){
    printf("nullptr\n");
    return;
  }

  LavaMem lm;
  lm.ptr = (void*)( (u8*)t.memStart() - 16 );
  PrintLavaMem(lm);

  //assert(lm.refCount() < 1000);
  //
  //lm.fromDataAddr( (u64)t.memStart() );
}

extern "C"
{
  const char*  InTypes[]  = {"IdxVerts",           nullptr};            // This array contains the type that each slot of the same index will accept as input.
  const char*  InNames[]  = {"Gaussian Slot In",   nullptr};            // This array contains the names of each input slot as a string that can be used by the GUI.  It will show up as a label to each slot and be used when visualizing.
  const char* OutTypes[]  = {"IdxVerts",           nullptr};            // This array contains the types that are output in each slot of the same index
  const char* OutNames[]  = {"Gaussian Slot Out",  nullptr};            // This array contains the names of each output slot as a string that can be used by the GUI.  It will show up as a label to each slot and be used when visualizing.

  void GaussConstruct()
  {
    RNG::Init(0);
  }
  void GaussDestruct()
  {
    RNG::Destruct();
  }

  uint64_t Gaussian(LavaParams const* lp, LavaFrame const* in, lava_threadQ* out) noexcept
  {
    using namespace std;

    u32 i=0;
    while( LavaNxtPckt(in, &i) )
    {
      tbl gParams = LavaTblFromPckt(lp, in, i);
      //f32     var = gParams("Variance");
      //f32      ev = gParams("Expected Value");
      //u64   verts = gParams("Vertex Count");

      f32     var = randomf(0.01f, 1.f);
      f32      ev = 0.f;  //randomf(0f, 0.2f);
      u64   verts = 512;

      tbl gcurve = LavaMakeTbl(lp);
      gcurve("type") = tbl::StrToInt("IdxVerts");
      gcurve("mode") = (u64)0; // GL_POINTS for now                                   // needs to be openGL lines - GL_LINES - 0x01

      tbl ind(verts*2 - 1, (u32)0u);
      tbl  px(verts, 0.f);
      tbl  py(verts, 0.f);
      tbl  cg(verts, 1.f);

      f32 vrecip = 1.f / verts;
      f32  coeff = 1.f / sqrtf(2*PIf*var);
      TO(verts,i){
        f32     x = ( (f32)i - (verts/2.f) ) * vrecip * 4.f;
        f32  eExp = -( (x*x)/(2.f*var) );
        f32     y = coeff * expf( eExp );
        px[i] = x + ev;
        py[i] = y;
      }
      u64 indsz = ind.size();
      for(u64 i=0; i < verts-1; ++i){
        ind[i*2]   = (u32)i;
        ind[i*2+1] = (u32)(i+1);
      }

      gcurve("positions x")  = &px;
      gcurve("positions y")  = &py;
      gcurve("colors green") = &cg;
      gcurve("colors blue")  = &cg;
      gcurve("indices")      = &ind;
      gcurve.flatten();

      out->push( LavaTblToOut(gcurve, GAUSS_IDXVERTS_OUT) );      // this demonstrates how to output a tbl into the first output slot
    }

    return 1;
  }

  LavaNode LavaNodes[] =
  {
    {
      Gaussian,                                      // function
      GaussConstruct,                                // constructor - this can be set to nullptr if not needed
      GaussDestruct,                                 // destructor  - this can also be set to nullptr
      LavaNode::FLOW,                                // node_type   - this should be eighther LavaNode::MSG (will be run even without input packets) or LavaNode::FLOW (will be run only when at least one packet is available for input)
      "Gaussian",                                    // name
      InTypes,                                       // in_types    - this can be set to nullptr instead of pointing to a list that has the first item as nullptr
      InNames,                                       // in_names    - this can be set to nullptr instead of pointing to a list that has the first item as nullptr
      OutTypes,                                      // out_types   - this can be set to nullptr instead of pointing to a list that has the first item as nullptr
      OutNames,                                      // out_names   - this can be set to nullptr instead of pointing to a list that has the first item as nullptr
      nullptr,                                       // description
      0                                              // version
    },

    LavaNodeListEnd                                  // This is a constant that has all the members of the LavaNode struct set to 0 or nullptr - it is used as a special value that ends the static list of LavaNodes. This negates the need for a separate static variable that gives the size of the list, which would be have to be kept in sync and therefore be error prone.
  };

  __declspec(dllexport) LavaNode* GetLavaNodes()
  {
    return (LavaNode*)LavaNodes;
  }
}

//
//PrintTblMem(gcurve);

//u32   verts = 8;
//
//tbl  pz(verts, 0.f);
//
//gcurve("positions z") = &pz;

//tbl inputTbl( (void*)(in->packets[i].val.value) );
//
//for(auto& kv : gaussParams){  // this loop demonstrates how to iterate through non-empty map elements
//}
<commit_msg>gaussian node packet index changed to be i - 1<commit_after>

#include <random>
#include "../../str_util.hpp"
#include "../../no_rt_util.h"
#include "../../tbl.hpp"
#include "../LavaFlow.hpp"

enum Slots
{
  GAUSS_IDXVERTS_OUT = 0

  //GAUSS_PARAMS_IN    = 0,
  //GAUSS_IDXVERTS_OUT = 1
};

namespace RNG
{
  using rng_t  = ::std::mt19937;
  using urng_t = ::std::unique_ptr<rng_t>;

  //extern __declspec(thread) rng_t*  m_genPtr;
  //
  //void Init(int s);
  //void Destruct();

  rng_t   gen(0);
  rng_t*  m_genPtr = &gen; //nullptr;

  void Init(int s)
  {
    //if (m_genPtr == nullptr) {
    //  m_genPtr = new rng_t(s);
    //}
  }
  void Destruct()
  {
    //if(m_genPtr != nullptr)
    //  delete m_genPtr;
  }
}

float     randomf(float lo, float hi)
{
  ::std::uniform_real_distribution<float> dis(lo, hi);
  return dis(*RNG::m_genPtr);
}

void           PrintLavaMem(LavaMem lm)
{
  if(lm.ptr)
    printf("\n addr: %llu  data addr: %llu  ref count: %llu   size bytes: %llu \n",
      (u64)(lm.ptr), (u64)(lm.data()), (u64)lm.refCount(), (u64)lm.sizeBytes() );
}
void           PrintTblMem(tbl const& t)
{
  if( !t.m_mem ){
    printf("nullptr\n");
    return;
  }

  LavaMem lm;
  lm.ptr = (void*)( (u8*)t.memStart() - 16 );
  PrintLavaMem(lm);

  //assert(lm.refCount() < 1000);
  //
  //lm.fromDataAddr( (u64)t.memStart() );
}

extern "C"
{
  const char*  InTypes[]  = {"IdxVerts",           nullptr};            // This array contains the type that each slot of the same index will accept as input.
  const char*  InNames[]  = {"Gaussian Slot In",   nullptr};            // This array contains the names of each input slot as a string that can be used by the GUI.  It will show up as a label to each slot and be used when visualizing.
  const char* OutTypes[]  = {"IdxVerts",           nullptr};            // This array contains the types that are output in each slot of the same index
  const char* OutNames[]  = {"Gaussian Slot Out",  nullptr};            // This array contains the names of each output slot as a string that can be used by the GUI.  It will show up as a label to each slot and be used when visualizing.

  void GaussConstruct()
  {
    RNG::Init(0);
  }
  void GaussDestruct()
  {
    RNG::Destruct();
  }

  uint64_t Gaussian(LavaParams const* lp, LavaFrame const* in, lava_threadQ* out) noexcept
  {
    using namespace std;

    u32 i=0;
    while( LavaNxtPckt(in, &i) )
    {
      tbl gParams = LavaTblFromPckt(lp, in, i-1);
      //f32     var = gParams("Variance");
      //f32      ev = gParams("Expected Value");
      //u64   verts = gParams("Vertex Count");

      f32     var = randomf(0.01f, 1.f);
      f32      ev = 0.f;  //randomf(0f, 0.2f);
      u64   verts = 512;

      tbl gcurve = LavaMakeTbl(lp);
      gcurve("type") = tbl::StrToInt("IdxVerts");
      gcurve("mode") = (u64)0; // GL_POINTS for now                                   // needs to be openGL lines - GL_LINES - 0x01

      tbl ind(verts*2 - 1, (u32)0u);
      tbl  px(verts, 0.f);
      tbl  py(verts, 0.f);
      tbl  cg(verts, 1.f);

      f32 vrecip = 1.f / verts;
      f32  coeff = 1.f / sqrtf(2*PIf*var);
      TO(verts,i){
        f32     x = ( (f32)i - (verts/2.f) ) * vrecip * 4.f;
        f32  eExp = -( (x*x)/(2.f*var) );
        f32     y = coeff * expf( eExp );
        px[i] = x + ev;
        py[i] = y;
      }
      u64 indsz = ind.size();
      for(u64 i=0; i < verts-1; ++i){
        ind[i*2]   = (u32)i;
        ind[i*2+1] = (u32)(i+1);
      }

      gcurve("positions x")  = &px;
      gcurve("positions y")  = &py;
      gcurve("colors green") = &cg;
      gcurve("colors blue")  = &cg;
      gcurve("indices")      = &ind;
      gcurve.flatten();

      out->push( LavaTblToOut(gcurve, GAUSS_IDXVERTS_OUT) );      // this demonstrates how to output a tbl into the first output slot
    }

    return 1;
  }

  LavaNode LavaNodes[] =
  {
    {
      Gaussian,                                      // function
      GaussConstruct,                                // constructor - this can be set to nullptr if not needed
      GaussDestruct,                                 // destructor  - this can also be set to nullptr
      LavaNode::FLOW,                                // node_type   - this should be eighther LavaNode::MSG (will be run even without input packets) or LavaNode::FLOW (will be run only when at least one packet is available for input)
      "Gaussian",                                    // name
      InTypes,                                       // in_types    - this can be set to nullptr instead of pointing to a list that has the first item as nullptr
      InNames,                                       // in_names    - this can be set to nullptr instead of pointing to a list that has the first item as nullptr
      OutTypes,                                      // out_types   - this can be set to nullptr instead of pointing to a list that has the first item as nullptr
      OutNames,                                      // out_names   - this can be set to nullptr instead of pointing to a list that has the first item as nullptr
      nullptr,                                       // description
      0                                              // version
    },

    LavaNodeListEnd                                  // This is a constant that has all the members of the LavaNode struct set to 0 or nullptr - it is used as a special value that ends the static list of LavaNodes. This negates the need for a separate static variable that gives the size of the list, which would be have to be kept in sync and therefore be error prone.
  };

  __declspec(dllexport) LavaNode* GetLavaNodes()
  {
    return (LavaNode*)LavaNodes;
  }
}

//
//PrintTblMem(gcurve);

//u32   verts = 8;
//
//tbl  pz(verts, 0.f);
//
//gcurve("positions z") = &pz;

//tbl inputTbl( (void*)(in->packets[i].val.value) );
//
//for(auto& kv : gaussParams){  // this loop demonstrates how to iterate through non-empty map elements
//}
<|endoftext|>


<commit_before>#include "mmd/pmx/mesh.hpp"
#include "../stream.hpp"

namespace mmd {
    namespace pmx {
        Vertex::Vertex() {}

        void Vertex::load(Fs *fs, Header *header) {
            Stream *stream = (Stream *)fs;
            position = stream->readVec3();
            normal = stream->readVec3();
            uv = stream->readVec2();
            for (int i = 0; i < header->additional; ++i) {
                addition[i] = stream->readVec4();
            }
            boneType = stream->readSByte();
            switch (boneType) {
                case 0:
                BDEF.bone[0] = stream->readIndex(header->bone);
                break;

                case 1:
                BDEF.bone[0] = stream->readIndex(header->bone);
                BDEF.bone[1] = stream->readIndex(header->bone);
                BDEF.weight[0] = stream->readFloat();
                BDEF.weight[1] = 1.0f - BDEF.weight[0];
                break;

                case 2:
                case 4:
                for (int i = 0; i < 4; ++i) {
                    BDEF.bone[i] = stream->readIndex(header->bone);
                }
                for (int i = 0; i < 4; ++i) {
                    BDEF.weight[i] = stream->readFloat();
                }
                break;

                case 3:
                SDEF.bone[0] = stream->readIndex(header->bone);
                SDEF.bone[1] = stream->readIndex(header->bone);
                SDEF.weight[0] = stream->readFloat();
                SDEF.weight[1] = 1.0f - SDEF.weight[0];
                SDEF.C = stream->readVec3();
                SDEF.R0 = stream->readVec3();
                SDEF.R1 = stream->readVec3();
                break;

                default:
                FAIL << "Invalid bone type!";
            }
            edge = stream->readFloat();
        }

        void Surface::load(Fs *fs, Header *header) {
            Stream *stream = (Stream *)fs;
            A = stream->readUIndex(header->vertex);
            B = stream->readUIndex(header->vertex);
            C = stream->readUIndex(header->vertex);
        }

        void Mesh::load(Fs *fs, Header *header) {
            LOG << "Load Mesh";
            Stream *stream = (Stream *)fs;
            int n = stream->readInt();
            vertex.resize(n);
            for (int i = 0; i < n; ++i) {
                vertex[i].load(fs, header);
            }
            n = stream->readInt() / 3;
            surface.resize(n);
            for (int i = 0; i < n; ++i) {
                surface[i].load(fs, header);
            }

            LOG << "---------------------";
            LOG << "Mesh infomation";
            LOG << "---------------------";
            LOG << "vertices: " << vertex.size();
            LOG << "surfaces: " << surface.size();
            LOG << "---------------------";
        }

    } /* pmx */
} /* mmd */
<commit_msg>solve a bug<commit_after>#include "mmd/pmx/mesh.hpp"
#include "../stream.hpp"

namespace mmd {
    namespace pmx {
        Vertex::Vertex() {}

        void Vertex::load(Fs *fs, Header *header) {
            Stream *stream = (Stream *)fs;
            position = stream->readVec3();
            normal = stream->readVec3();
            uv = stream->readVec2();
            for (int i = 0; i < header->additional; ++i) {
                addition[i] = stream->readVec4();
            }
            boneType = stream->readSByte();
            memset(&SDEF, 0, sizeof(SDEF));
            switch (boneType) {
                case 0:
                BDEF.bone[0] = stream->readIndex(header->bone);
                BDEF.weight[0] = 1.0f;
                break;

                case 1:
                BDEF.bone[0] = stream->readIndex(header->bone);
                BDEF.bone[1] = stream->readIndex(header->bone);
                BDEF.weight[0] = stream->readFloat();
                BDEF.weight[1] = 1.0f - BDEF.weight[0];
                break;

                case 2:
                case 4:
                for (int i = 0; i < 4; ++i) {
                    BDEF.bone[i] = stream->readIndex(header->bone);
                }
                for (int i = 0; i < 4; ++i) {
                    BDEF.weight[i] = stream->readFloat();
                }
                break;

                case 3:
                SDEF.bone[0] = stream->readIndex(header->bone);
                SDEF.bone[1] = stream->readIndex(header->bone);
                SDEF.weight[0] = stream->readFloat();
                SDEF.weight[1] = 1.0f - SDEF.weight[0];
                SDEF.C = stream->readVec3();
                SDEF.R0 = stream->readVec3();
                SDEF.R1 = stream->readVec3();
                break;

                default:
                FAIL << "Invalid bone type!";
            }
            edge = stream->readFloat();
        }

        void Surface::load(Fs *fs, Header *header) {
            Stream *stream = (Stream *)fs;
            A = stream->readUIndex(header->vertex);
            B = stream->readUIndex(header->vertex);
            C = stream->readUIndex(header->vertex);
        }

        void Mesh::load(Fs *fs, Header *header) {
            LOG << "Load Mesh";
            Stream *stream = (Stream *)fs;
            int n = stream->readInt();
            vertex.resize(n);
            for (int i = 0; i < n; ++i) {
                vertex[i].load(fs, header);
            }
            n = stream->readInt() / 3;
            surface.resize(n);
            for (int i = 0; i < n; ++i) {
                surface[i].load(fs, header);
            }

            LOG << "---------------------";
            LOG << "Mesh infomation";
            LOG << "---------------------";
            LOG << "vertices: " << vertex.size();
            LOG << "surfaces: " << surface.size();
            LOG << "---------------------";
        }

    } /* pmx */
} /* mmd */
<|endoftext|>


<commit_before>/*
    Copyright (C) 2014 Torbjorn Rognes

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero 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 Affero General Public License for more details.

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

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

#include "vsearch.h"

/*
   Unable to get the Mac gcc compiler v 4.2.1 produce the real
   popcnt instruction. Therefore resorting to assembly code.
*/

#define popcnt_asm(x,y)                                         \
  __asm__ __volatile__ ("popcnt %1,%0" : "=r"(y) : "r"(x));

unsigned long popcount(unsigned long x)
{
  unsigned long y;
  popcnt_asm(x,y);
  return y;
}

void pprint(__m128i x)
{
  unsigned char * p = (unsigned char *) & x;

  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
}

void pshow(char * name, __m128i x)
{
  printf("%s: ", name);
  pprint(x);
  printf("\n");
}

unsigned long popcount_128(__m128i x)
{

  //  pshow("x", x);

  __m128i mask1 = _mm_set_epi8(0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
			       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55);

  __m128i mask2 = _mm_set_epi8(0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
			       0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33);

  __m128i mask4 = _mm_set_epi8(0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
			       0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f);

  __m128i zero = _mm_setzero_si128();

  /* add together 2 bits: 0+1, 2+3, 3+4, ... 126+127 */

  __m128i a = _mm_srli_epi64(x, 1);
  __m128i b = _mm_and_si128(x, mask1);
  __m128i c = _mm_and_si128(a, mask1);
  __m128i d = _mm_add_epi64(b, c);

  //  pshow("d", d);

  /* add together 4 bits: (0+1)+(2+3), ... (124+125)+(126+127) */

  __m128i e = _mm_srli_epi64(d, 2);
  __m128i f = _mm_and_si128(d, mask2);
  __m128i g = _mm_and_si128(e, mask2);
  __m128i h = _mm_add_epi64(f, g);

  //  pshow("h", h);

  /* add together 8 bits: (0..3)+(4..7), ... (120..123)+(124..127) */

  __m128i i = _mm_srli_epi64(h, 4);
  __m128i j = _mm_add_epi64(h, i);
  __m128i k = _mm_and_si128(j, mask4);

  //  pshow("k", k);

  /* add together 8 bytes: (0..63) and (64..127) */

  __m128i l = _mm_sad_epu8(k, zero);

  //  pshow("l", l);

  /* add together 64-bit values into final 128 bit value */

  __m128i m = _mm_srli_si128(l, 8);
  __m128i n = _mm_add_epi64(m, l);

  //  pshow("n", n);

  /* return low 64 bits - return value is always in range 0 to 128 */

  unsigned long zz = (unsigned long) _mm_movepi64_pi64(n);

  //  printf("z: %lu\n", zz);

  return zz;
}
<commit_msg>Update popcount.cc<commit_after>/*
    Copyright (C) 2014 Torbjorn Rognes

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero 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 Affero General Public License for more details.

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

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

#include "vsearch.h"

/*
   Unable to get the Mac gcc compiler v 4.2.1 to produce the real
   popcnt instruction. Therefore resorting to assembly code.
*/

#define popcnt_asm(x,y)                                         \
  __asm__ __volatile__ ("popcnt %1,%0" : "=r"(y) : "r"(x));

unsigned long popcount(unsigned long x)
{
  unsigned long y;
  popcnt_asm(x,y);
  return y;
}

void pprint(__m128i x)
{
  unsigned char * p = (unsigned char *) & x;

  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
  printf("%02x", *p++);
}

void pshow(char * name, __m128i x)
{
  printf("%s: ", name);
  pprint(x);
  printf("\n");
}

unsigned long popcount_128(__m128i x)
{

  //  pshow("x", x);

  __m128i mask1 = _mm_set_epi8(0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
			       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55);

  __m128i mask2 = _mm_set_epi8(0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
			       0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33);

  __m128i mask4 = _mm_set_epi8(0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
			       0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f);

  __m128i zero = _mm_setzero_si128();

  /* add together 2 bits: 0+1, 2+3, 3+4, ... 126+127 */

  __m128i a = _mm_srli_epi64(x, 1);
  __m128i b = _mm_and_si128(x, mask1);
  __m128i c = _mm_and_si128(a, mask1);
  __m128i d = _mm_add_epi64(b, c);

  //  pshow("d", d);

  /* add together 4 bits: (0+1)+(2+3), ... (124+125)+(126+127) */

  __m128i e = _mm_srli_epi64(d, 2);
  __m128i f = _mm_and_si128(d, mask2);
  __m128i g = _mm_and_si128(e, mask2);
  __m128i h = _mm_add_epi64(f, g);

  //  pshow("h", h);

  /* add together 8 bits: (0..3)+(4..7), ... (120..123)+(124..127) */

  __m128i i = _mm_srli_epi64(h, 4);
  __m128i j = _mm_add_epi64(h, i);
  __m128i k = _mm_and_si128(j, mask4);

  //  pshow("k", k);

  /* add together 8 bytes: (0..63) and (64..127) */

  __m128i l = _mm_sad_epu8(k, zero);

  //  pshow("l", l);

  /* add together 64-bit values into final 128 bit value */

  __m128i m = _mm_srli_si128(l, 8);
  __m128i n = _mm_add_epi64(m, l);

  //  pshow("n", n);

  /* return low 64 bits - return value is always in range 0 to 128 */

  unsigned long zz = (unsigned long) _mm_movepi64_pi64(n);

  //  printf("z: %lu\n", zz);

  return zz;
}
<|endoftext|>


<commit_before>/*
Copyright (C) 2007 <SWGEmu>
This File is part of Core3.
This program 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 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 Lesser General Public License for
more details.

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

Linking Engine3 statically or dynamically with other modules
is making a combined work based on Engine3.
Thus, the terms and conditions of the GNU Lesser General Public License
cover the whole combination.

In addition, as a special exception, the copyright holders of Engine3
give you permission to combine Engine3 program with free software
programs or libraries that are released under the GNU LGPL and with
code included in the standard release of Core3 under the GNU LGPL
license (or modified versions of such code, with unchanged license).
You may copy and distribute such a system following the terms of the
GNU LGPL for Engine3 and the licenses of the other code concerned,
provided that you include the source code of that other code when
and as the GNU LGPL requires distribution of source code.

Note that people who make modified versions of Engine3 are not obligated
to grant this special exception for their modified versions;
it is their choice whether to do so. The GNU Lesser General Public License
gives permission to release a modified version without this exception;
this exception also makes it possible to release a modified version
which carries forward this exception.

*/

#include "server/zone/managers/director/ScreenPlayObserver.h"
#include "DirectorManager.h"
#include "engine/lua/LuaPanicException.h"

int ScreenPlayObserverImplementation::notifyObserverEvent(uint32 eventType, Observable* observable, ManagedObject* arg1, int64 arg2) {
	int ret = 1;

	try {
		Lua* lua = DirectorManager::instance()->getLuaInstance();

		LuaFunction startScreenPlay(lua->getLuaState(), play, key, 1);
		startScreenPlay << observable;
		startScreenPlay << arg1;
		startScreenPlay << arg2;

		startScreenPlay.callFunction();

		if (lua_gettop(lua->getLuaState()) == 0) {
			Logger::console.error("ScreenPlayObserverImplementation::notifyObserverEvent didnt return a value from " + play + ":" + key);

			assert(0 && "no return value in  ScreenPlayObserverImplementation::notifyObserverEvent");

			return 1;
		}

		assert(lua_isnumber(lua->getLuaState(), -1));

		ret = lua->getIntParameter(lua->getLuaState());

	} catch (LuaPanicException& panic) {
		Logger::console.error("Panic exception: " + panic.getMessage() + " while trying to run SceenPlayObserver: " + play + ":" + key);
	}

	//1 remove observer, 0 keep observer

	return ret;
}
<commit_msg>[added] better error printing on observer assert<commit_after>/*
Copyright (C) 2007 <SWGEmu>
This File is part of Core3.
This program 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 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 Lesser General Public License for
more details.

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

Linking Engine3 statically or dynamically with other modules
is making a combined work based on Engine3.
Thus, the terms and conditions of the GNU Lesser General Public License
cover the whole combination.

In addition, as a special exception, the copyright holders of Engine3
give you permission to combine Engine3 program with free software
programs or libraries that are released under the GNU LGPL and with
code included in the standard release of Core3 under the GNU LGPL
license (or modified versions of such code, with unchanged license).
You may copy and distribute such a system following the terms of the
GNU LGPL for Engine3 and the licenses of the other code concerned,
provided that you include the source code of that other code when
and as the GNU LGPL requires distribution of source code.

Note that people who make modified versions of Engine3 are not obligated
to grant this special exception for their modified versions;
it is their choice whether to do so. The GNU Lesser General Public License
gives permission to release a modified version without this exception;
this exception also makes it possible to release a modified version
which carries forward this exception.

*/

#include "server/zone/managers/director/ScreenPlayObserver.h"
#include "DirectorManager.h"
#include "engine/lua/LuaPanicException.h"

int ScreenPlayObserverImplementation::notifyObserverEvent(uint32 eventType, Observable* observable, ManagedObject* arg1, int64 arg2) {
	int ret = 1;

	try {
		Lua* lua = DirectorManager::instance()->getLuaInstance();

		LuaFunction startScreenPlay(lua->getLuaState(), play, key, 1);
		startScreenPlay << observable;
		startScreenPlay << arg1;
		startScreenPlay << arg2;

		startScreenPlay.callFunction();

		if (lua_gettop(lua->getLuaState()) == 0) {
			Logger::console.error("ScreenPlayObserverImplementation::notifyObserverEvent didnt return a value from " + play + ":" + key);

			assert(0 && "no return value in  ScreenPlayObserverImplementation::notifyObserverEvent");

			return 1;
		}

		if (!lua_isnumber(lua->getLuaState(), -1)) {
			assert(printf("ScreenPlayObserver %s:%s didnt return a valid value in an observer handler\n", play.toCharArray(), key.toCharArray()) && 0);
		}

		ret = lua->getIntParameter(lua->getLuaState());

	} catch (LuaPanicException& panic) {
		Logger::console.error("Panic exception: " + panic.getMessage() + " while trying to run SceenPlayObserver: " + play + ":" + key);
	}

	//1 remove observer, 0 keep observer

	return ret;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/scoped_temp_dir.h"
#include "base/test/thread_test_helper.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_profile.h"
#include "content/browser/in_process_webkit/dom_storage_context.h"
#include "content/browser/in_process_webkit/webkit_context.h"

using content::BrowserContext;
using content::BrowserThread;

typedef InProcessBrowserTest DOMStorageBrowserTest;

// In proc browser test is needed here because ClearLocalState indirectly calls
// WebKit's isMainThread through WebSecurityOrigin->SecurityOrigin.
IN_PROC_BROWSER_TEST_F(DOMStorageBrowserTest, ClearLocalState) {
  // Create test files.
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath domstorage_dir = temp_dir.path().Append(
      DOMStorageContext::kLocalStorageDirectory);
  ASSERT_TRUE(file_util::CreateDirectory(domstorage_dir));

  FilePath::StringType file_name_1(FILE_PATH_LITERAL("http_foo_0"));
  file_name_1.append(DOMStorageContext::kLocalStorageExtension);
  FilePath::StringType file_name_2(FILE_PATH_LITERAL("chrome-extension_foo_0"));
  file_name_2.append(DOMStorageContext::kLocalStorageExtension);
  FilePath temp_file_path_1 = domstorage_dir.Append(file_name_1);
  FilePath temp_file_path_2 = domstorage_dir.Append(file_name_2);

  ASSERT_EQ(1, file_util::WriteFile(temp_file_path_1, ".", 1));
  ASSERT_EQ(1, file_util::WriteFile(temp_file_path_2, "o", 1));

  // Create the scope which will ensure we run the destructor of the webkit
  // context which should trigger the clean up.
  {
    TestingProfile profile;
    WebKitContext* webkit_context = BrowserContext::GetWebKitContext(&profile);
    webkit_context->dom_storage_context()->
        set_data_path_for_testing(temp_dir.path());
    webkit_context->set_clear_local_state_on_exit(true);
  }
  // Make sure we wait until the destructor has run.
  scoped_refptr<base::ThreadTestHelper> helper(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(
              BrowserThread::WEBKIT_DEPRECATED)));
  ASSERT_TRUE(helper->Run());

  // Because we specified https for scheme to be skipped the second file
  // should survive and the first go into vanity.
  ASSERT_FALSE(file_util::PathExists(temp_file_path_1));
  ASSERT_TRUE(file_util::PathExists(temp_file_path_2));
}
<commit_msg>Mark DOMStorageBrowserTest.ClearLocalState flaky on Mac<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/scoped_temp_dir.h"
#include "base/test/thread_test_helper.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/testing_profile.h"
#include "content/browser/in_process_webkit/dom_storage_context.h"
#include "content/browser/in_process_webkit/webkit_context.h"

using content::BrowserContext;
using content::BrowserThread;

typedef InProcessBrowserTest DOMStorageBrowserTest;

#if defined(OS_MACOSX)
// http://crbug.com/115150. On Mac, failure rate is about 30% currently.
#define MAYBE_ClearLocalState FLAKY_ClearLocalState
#else
#define MAYBE_ClearLocalState ClearLocalState
#endif

// In proc browser test is needed here because ClearLocalState indirectly calls
// WebKit's isMainThread through WebSecurityOrigin->SecurityOrigin.
IN_PROC_BROWSER_TEST_F(DOMStorageBrowserTest, MAYBE_ClearLocalState) {
  // Create test files.
  ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath domstorage_dir = temp_dir.path().Append(
      DOMStorageContext::kLocalStorageDirectory);
  ASSERT_TRUE(file_util::CreateDirectory(domstorage_dir));

  FilePath::StringType file_name_1(FILE_PATH_LITERAL("http_foo_0"));
  file_name_1.append(DOMStorageContext::kLocalStorageExtension);
  FilePath::StringType file_name_2(FILE_PATH_LITERAL("chrome-extension_foo_0"));
  file_name_2.append(DOMStorageContext::kLocalStorageExtension);
  FilePath temp_file_path_1 = domstorage_dir.Append(file_name_1);
  FilePath temp_file_path_2 = domstorage_dir.Append(file_name_2);

  ASSERT_EQ(1, file_util::WriteFile(temp_file_path_1, ".", 1));
  ASSERT_EQ(1, file_util::WriteFile(temp_file_path_2, "o", 1));

  // Create the scope which will ensure we run the destructor of the webkit
  // context which should trigger the clean up.
  {
    TestingProfile profile;
    WebKitContext* webkit_context = BrowserContext::GetWebKitContext(&profile);
    webkit_context->dom_storage_context()->
        set_data_path_for_testing(temp_dir.path());
    webkit_context->set_clear_local_state_on_exit(true);
  }
  // Make sure we wait until the destructor has run.
  scoped_refptr<base::ThreadTestHelper> helper(
      new base::ThreadTestHelper(
          BrowserThread::GetMessageLoopProxyForThread(
              BrowserThread::WEBKIT_DEPRECATED)));
  ASSERT_TRUE(helper->Run());

  // Because we specified https for scheme to be skipped the second file
  // should survive and the first go into vanity.
  ASSERT_FALSE(file_util::PathExists(temp_file_path_1));
  ASSERT_TRUE(file_util::PathExists(temp_file_path_2));
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "inc\CircularTorus.h"

namespace Geometry
{

CircularTorus::CircularTorus()
	: m_topVis(true)
	, m_bottomVis(true)
{
}

CircularTorus::~CircularTorus()
{
}

void CircularTorus::subDraw()
{
	osg::ref_ptr<osg::Vec3Array> vertexArr = new osg::Vec3Array;
	osg::ref_ptr<osg::Vec3Array> normalArr = new osg::Vec3Array;
	setVertexArray(vertexArr);
	setNormalArray(normalArr, osg::Array::BIND_PER_VERTEX);
	osg::ref_ptr<osg::Vec4Array> colArr = new osg::Vec4Array();
	colArr->push_back(m_color);
	setColorArray(colArr, osg::Array::BIND_OVERALL);

	bool isFull = osg::equivalent(m_angle, 2 * M_PI, GetEpsilon());
	if (isFull)
	{
		m_angle = 2 * M_PI;
	}

	int mainCount = (int)ceil(m_angle / (2 * M_PI / getDivision()));
	double mainIncAngle = m_angle / mainCount;

	int subCount = (int)getDivision();
	double subIncAngle = 2 * M_PI / subCount;

	osg::Vec3 mainVec = m_startPnt - m_center;
	osg::Quat mainQuat(mainIncAngle, m_normal);

	osg::Vec3 torusNormal = mainVec;
	torusNormal.normalize();

	// һȦ
	osg::Vec3 faceNormal = torusNormal ^ m_normal;
	osg::Quat torusQuat(subIncAngle, faceNormal);
	osg::Vec3 subVec = torusNormal;
	double subRadius = m_startRadius;
	osg::Vec3 subCenter = m_startPnt;
	osg::Vec3 tmpSubVec = subVec * subRadius;
	for (int i = 0; i < subCount; ++i)
	{
		vertexArr->push_back(subCenter + tmpSubVec);
		tmpSubVec = torusQuat * tmpSubVec;
	}

	// м
	osg::DrawElementsUShort *pDrawEle = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, 0);
	pDrawEle->push_back(subCount - 1);
	double factor = (m_endRadius - m_startRadius) / mainCount;
	for (int i = 1; i < mainCount; ++i)
	{
		faceNormal = mainQuat * faceNormal;
		mainVec = mainQuat * mainVec;
		subVec = mainQuat * subVec;
		subCenter = m_center + mainVec;
		torusQuat.makeRotate(subIncAngle, faceNormal);
		subRadius += factor;

		tmpSubVec = subVec * subRadius;
		osg::Vec3 tangNormal = m_normal;
		for (int j = 0; j < subCount; ++j)
		{
			vertexArr->push_back(subCenter + tmpSubVec);
			tmpSubVec = torusQuat * tmpSubVec;

			int size = vertexArr->size();
			normalArr->push_back(tangNormal ^ ((*vertexArr)[size - subCount - 1] - vertexArr->back()));
			normalArr->back().normalize();
			tangNormal = torusQuat * tangNormal;

			pDrawEle->push_back(size - 1);
			pDrawEle->push_back(size - subCount - 1);
		}
	}

	// һȦ
	osg::Quat fullQuat(m_angle, m_normal);
	faceNormal = fullQuat * (torusNormal ^ m_normal);
	mainVec = fullQuat * (m_startPnt - m_center);
	subVec = fullQuat * (torusNormal * m_endRadius);
	subCenter = m_center + mainVec;

	torusQuat.makeRotate(subIncAngle, faceNormal);
	tmpSubVec = subVec;
	osg::Vec3 tangNormal = m_normal;
	for (int j = 0; j < subCount; ++j)
	{
		vertexArr->push_back(subCenter + tmpSubVec);
		tmpSubVec = torusQuat * tmpSubVec;

		int size = vertexArr->size();
		normalArr->push_back(tangNormal ^ ((*vertexArr)[size - subCount - 1] - vertexArr->back()));
		normalArr->back().normalize();
		tangNormal = torusQuat * tangNormal;

		pDrawEle->push_back(size - 1);
		pDrawEle->push_back(size - subCount - 1);
	}
	pDrawEle->push_back(vertexArr->size() - subCount);
	// һȦ
	for (int i = 0; i < subCount; ++i)
		normalArr->push_back((*normalArr)[normalArr->size() - subCount]);
	addPrimitiveSet(pDrawEle);

	if (m_topVis)
	{
		size_t first = vertexArr->size();
		size_t base = first - subCount;
		osg::Vec3 topNormal = -faceNormal;
		vertexArr->push_back(subCenter);
		normalArr->push_back(topNormal);
		for (int i = subCount - 1; i >= 0; --i)
		{
			vertexArr->push_back((*vertexArr)[base + i]);
			normalArr->push_back(topNormal);
		}
		vertexArr->push_back((*vertexArr)[vertexArr->size() - subCount]);
		normalArr->push_back(topNormal);
		addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, first, vertexArr->size() - first));
	}

	if (m_bottomVis)
	{
		size_t first = vertexArr->size();
		osg::Vec3 bottomNormal = torusNormal ^ m_normal;
		vertexArr->push_back(m_startPnt);
		normalArr->push_back(bottomNormal);
		for (int i = 0; i < subCount; ++i)
		{
			vertexArr->push_back((*vertexArr)[i]);
			normalArr->push_back(bottomNormal);
		}
		vertexArr->push_back((*vertexArr)[vertexArr->size() - subCount]);
		normalArr->push_back(bottomNormal);
		addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, first, vertexArr->size() - first));
	}
}

} // namespace Geometry<commit_msg>解决圆环中间带条线的<commit_after>#include "stdafx.h"
#include "inc\CircularTorus.h"

namespace Geometry
{

CircularTorus::CircularTorus()
	: m_topVis(true)
	, m_bottomVis(true)
{
}

CircularTorus::~CircularTorus()
{
}

void CircularTorus::subDraw()
{
	osg::ref_ptr<osg::Vec3Array> vertexArr = new osg::Vec3Array;
	osg::ref_ptr<osg::Vec3Array> normalArr = new osg::Vec3Array;
	setVertexArray(vertexArr);
	setNormalArray(normalArr, osg::Array::BIND_PER_VERTEX);
	osg::ref_ptr<osg::Vec4Array> colArr = new osg::Vec4Array();
	colArr->push_back(m_color);
	setColorArray(colArr, osg::Array::BIND_OVERALL);

	bool isFull = osg::equivalent(m_angle, 2 * M_PI, GetEpsilon());
	if (isFull)
	{
		m_angle = 2 * M_PI;
	}

	int mainCount = (int)ceil(m_angle / (2 * M_PI / getDivision()));
	double mainIncAngle = m_angle / mainCount;

	int subCount = (int)getDivision();
	double subIncAngle = 2 * M_PI / subCount;

	osg::Vec3 mainVec = m_startPnt - m_center;
	osg::Quat mainQuat(mainIncAngle, m_normal);

	osg::Vec3 torusNormal = mainVec;
	torusNormal.normalize();

	// һȦ
	osg::Vec3 faceNormal = torusNormal ^ m_normal;
	osg::Quat torusQuat(subIncAngle, -faceNormal);
	osg::Vec3 subVec = torusNormal;
	double subRadius = m_startRadius;
	osg::Vec3 subCenter = m_startPnt;
	osg::Vec3 tmpSubVec = subVec * subRadius;
	for (int i = 0; i < subCount; ++i)
	{
		vertexArr->push_back(subCenter + tmpSubVec);
		tmpSubVec = torusQuat * tmpSubVec;
	}

	// м
	osg::DrawElementsUShort *pDrawEle = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, 0);
	pDrawEle->push_back(subCount - 1);
	double factor = (m_endRadius - m_startRadius) / mainCount;
	for (int i = 1; i < mainCount; ++i)
	{
		faceNormal = mainQuat * faceNormal;
		mainVec = mainQuat * mainVec;
		subVec = mainQuat * subVec;
		subCenter = m_center + mainVec;
		torusQuat.makeRotate(subIncAngle, -faceNormal);
		subRadius += factor;

		tmpSubVec = subVec * subRadius;
		osg::Vec3 tangNormal = m_normal;
		for (int j = 0; j < subCount; ++j)
		{
			vertexArr->push_back(subCenter + tmpSubVec);
			tmpSubVec = torusQuat * tmpSubVec;

			int size = vertexArr->size();
			normalArr->push_back(tangNormal ^ ((*vertexArr)[size - subCount - 1] - vertexArr->back()));
			normalArr->back().normalize();
			tangNormal = torusQuat * tangNormal;

			pDrawEle->push_back(size - subCount - 1);
			pDrawEle->push_back(size - 1);
		}
	}

	// һȦ
	osg::Quat fullQuat(m_angle, m_normal);
	faceNormal = fullQuat * (torusNormal ^ m_normal);
	mainVec = fullQuat * (m_startPnt - m_center);
	subVec = fullQuat * (torusNormal * m_endRadius);
	subCenter = m_center + mainVec;

	torusQuat.makeRotate(subIncAngle, -faceNormal);
	tmpSubVec = subVec;
	osg::Vec3 tangNormal = m_normal;
	for (int j = 0; j < subCount; ++j)
	{
		vertexArr->push_back(subCenter + tmpSubVec);
		tmpSubVec = torusQuat * tmpSubVec;

		int size = vertexArr->size();
		normalArr->push_back(tangNormal ^ ((*vertexArr)[size - subCount - 1] - vertexArr->back()));
		normalArr->back().normalize();
		tangNormal = torusQuat * tangNormal;

		pDrawEle->push_back(size - subCount - 1);
		pDrawEle->push_back(size - 1);
	}
	pDrawEle->push_back(vertexArr->size() - subCount);
	// һȦ
	for (int i = 0; i < subCount; ++i)
		normalArr->push_back((*normalArr)[normalArr->size() - subCount]);
	addPrimitiveSet(pDrawEle);

	if (m_topVis)
	{
		size_t first = vertexArr->size();
		size_t base = first - subCount;
		osg::Vec3 topNormal = -faceNormal;
		vertexArr->push_back(subCenter);
		normalArr->push_back(topNormal);
		for (int i = 0; i < subCount; ++i)
		{
			vertexArr->push_back((*vertexArr)[base + i]);
			normalArr->push_back(topNormal);
		}
		vertexArr->push_back((*vertexArr)[vertexArr->size() - subCount]);
		normalArr->push_back(topNormal);
		addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, first, vertexArr->size() - first));
	}

	if (m_bottomVis)
	{
		size_t first = vertexArr->size();
		osg::Vec3 bottomNormal = torusNormal ^ m_normal;
		vertexArr->push_back(m_startPnt);
		normalArr->push_back(bottomNormal);
		for (int i = subCount - 1; i >= 0; --i)
		{
			vertexArr->push_back((*vertexArr)[i]);
			normalArr->push_back(bottomNormal);
		}
		vertexArr->push_back((*vertexArr)[vertexArr->size() - subCount]);
		normalArr->push_back(bottomNormal);
		addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, first, vertexArr->size() - first));
	}
}

} // namespace Geometry<|endoftext|>


<commit_before>#include "network.h"
#include <QDebug>

Network::Network(QObject *parent) :QObject(parent)
{
    my_socket = new QUdpSocket(this);
    my_socket->bind(QHostAddress::LocalHost, 1337);
    connect(my_socket, SIGNAL(readyRead()),
            this, SLOT(processPendingDatagram()));
}

void Network::sendData(QImage image)
{
    QByteArray q;
    QBuffer buffer(&q);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "PNG");
    my_socket->writeDatagram(q, QHostAddress::LocalHost, 1337);
    std::cerr << QHostAddress::LocalHost <<std::endl;
}

void Network::processPendingDatagram()
{

    while (my_socket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(my_socket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        my_socket->readDatagram(datagram.data(), datagram.size(),
                                &sender, &senderPort);
        //QImage recv_image((uchar*)datagram.data(), 240, 150, QImage::Format_RGB888);
        QImage recv_image;
        if (datagram.isNull())
            qDebug("Ures a bejovo buzi!!");
        else
            qDebug("datagram nem ures");
        recv_image.loadFromData(datagram, "PNG");

        if (recv_image.isNull())		      // Check if the image was indeed received
                qDebug("The image is null. Something failed.");
        image = recv_image;
   }
    //image = QImage("debug/images/kep.png").scaledToHeight(240).scaledToHeight(150);
}

QImage Network::get_image()
{
    return image;
}

Network::~Network()
{
    delete my_socket;
}
<commit_msg>remote networking test and it is working<commit_after>#include "network.h"
#include <QDebug>

Network::Network(QObject *parent) :QObject(parent)
{
    my_socket = new QUdpSocket(this);
    //my_socket->bind(QHostAddress::LocalHost, 1337);
    my_socket->bind(QHostAddress("192.168.254.98"), 1337);
    connect(my_socket, SIGNAL(readyRead()),
            this, SLOT(processPendingDatagram()));
}

void Network::sendData(QImage image)
{
    QByteArray q;
    QBuffer buffer(&q);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "PNG");
    //my_socket->writeDatagram(q, QHostAddress::LocalHost, 1337);
    my_socket->writeDatagram(q, QHostAddress("192.168.254.108"), 1337);
    std::cerr << QHostAddress::LocalHost <<std::endl;
}

void Network::processPendingDatagram()
{

    while (my_socket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(my_socket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        my_socket->readDatagram(datagram.data(), datagram.size(),
                                &sender, &senderPort);
        //QImage recv_image((uchar*)datagram.data(), 240, 150, QImage::Format_RGB888);
        QImage recv_image;
        if (datagram.isNull())
            qDebug("Ures a bejovo buzi!!");
        else
            qDebug("datagram nem ures");
        recv_image.loadFromData(datagram, "PNG");

        if (recv_image.isNull())		      // Check if the image was indeed received
                qDebug("The image is null. Something failed.");
        image = recv_image;
   }
    //image = QImage("debug/images/kep.png").scaledToHeight(240).scaledToHeight(150);
}

QImage Network::get_image()
{
    return image;
}

Network::~Network()
{
    delete my_socket;
}
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkImageToImageTranslationMeanSquaresRegistrationTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include "itkPhysicalImage.h"
#include "itkSimpleImageRegionIterator.h"
#include "itkImageToImageTranslationMeanSquaresRegistration.h"

/**
 *  This test uses two 2D-Gaussians (standard deviation RegionSize/2)
 *  One is shifted by 10 pixels from the other.
 *  therefore the solution of the registration is |-5 0|
 *  This test uses LevenbergMarquart Optimizer but
 *  conjugate gradient optimizer tolerances are also defined
 *  in the itkImageToImageTranslationMeanSquaresRegistration.txx file
 *  (you need to change the type of the optimizer in the header file
 *  ie itkImageToImageTranslationMeanSquaresRegistration.h)
 */

int main()
{

  /*Allocate Images*/
  typedef itk::PhysicalImage<unsigned char,2>           ReferenceType;
  typedef itk::PhysicalImage<unsigned char,2>           TargetType;

  typedef itk::ImageToImageTranslationMeanSquaresRegistration<ReferenceType,TargetType> RegistrationType;

  ReferenceType::SizeType size = {{100,100}};
  ReferenceType::IndexType index = {{0,0}};
  ReferenceType::RegionType region;
  region.SetSize( size );
  region.SetIndex( index );

  ReferenceType::Pointer imgReference = ReferenceType::New();
  imgReference->SetLargestPossibleRegion( region );
  imgReference->SetBufferedRegion( region );
  imgReference->SetRequestedRegion( region );
  imgReference->Allocate();

  TargetType::Pointer imgTarget = TargetType::New();
  imgTarget->SetLargestPossibleRegion( region );
  imgTarget->SetBufferedRegion( region );
  imgTarget->SetRequestedRegion( region );
  imgTarget->Allocate();

  /* Fill images with a 2D gaussian*/
  typedef  itk::SimpleImageRegionIterator<ReferenceType> ReferenceIteratorType;

  typedef  itk::SimpleImageRegionIterator<TargetType> TargetIteratorType;

  itk::Point<double,2> center;
  center[0] = (double)region.GetSize()[0]/2.0;
  center[1] = (double)region.GetSize()[1]/2.0;

  const double s = (double)region.GetSize()[0]/2.0;

  itk::Point<double,2>  p;
  itk::Vector<double,2> d;

  /* Set the displacement */
  itk::Vector<double,2> displacement;
  displacement[0] = 7;
  displacement[1] =	3;

  ReferenceIteratorType ri(imgReference,region);
  TargetIteratorType ti(imgTarget,region);
  ri.Begin();
  while(!ri.IsAtEnd())
  {
    p[0] = ri.GetIndex()[0];
    p[1] = ri.GetIndex()[1];
	  d = p-center;
	  d += displacement;
	  const double x = d[0];
	  const double y = d[1];
    ri.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ri;
  }

  ti.Begin();
  while(!ti.IsAtEnd())
  {
    p[0] = ti.GetIndex()[0];
    p[1] = ti.GetIndex()[1];
	d = p-center;
	const double x = d[0];
	const double y = d[1];
    ti.Set( 200.0 * exp( - ( x*x + y*y )/(s*s) ) );
    ++ti;
  }

  RegistrationType::Pointer registrationMethod = RegistrationType::New();

  registrationMethod->SetReference(imgReference);
  registrationMethod->SetTarget(imgTarget);

  registrationMethod->StartRegistration();

  std::cout << "The correct answer should be : " << std::endl;
  std::cout << -displacement << std::endl;

  return EXIT_SUCCESS;

}
<commit_msg>ENH: File renamed to include the optimization method name<commit_after><|endoftext|>


<commit_before>#include "./JPetSinogram.h"
#include <boost/numeric/ublas/matrix.hpp>
#include <vector>
#include <utility>
#include <cmath>
using namespace boost::numeric::ublas;

JPetSinogram::JPetSinogram() { }

JPetSinogram::~JPetSinogram() { }

/*! \brief Function returning vector of vectors with value of sinogram(180/views degree step and emissionMatrix.size1()/scans size) scaled to <min,max>
 *  \param emissionMatrix matrix, need to by NxN
 *  \param views number of views on object, degree step is calculated as (ang2 - ang1) / views
 *  \param scans number of scans on object, step is calculated as emissionMatrix.size(1) / scans
 *  \param fast if true use nearest neighbour interpolation instead linear interpolation in calculation (Optional, default false)
 *  \param min minimum value in returned sinogram (Optional, default 0)
 *  \param max maximum value in returned sinogram (Optional, default 255)
 *  \param ang1 start angle for projection (Optional, default 0)
 *  \param ang2 end angle for projection (Optional, default 180)
*/

std::vector<std::vector<double>> JPetSinogram::sinogram(matrix<int> emissionMatrix, int views, int scans,
                                                      bool fast, int min, int max, float ang1, float ang2) {
  assert(emissionMatrix.size1() == emissionMatrix.size2());
  assert(emissionMatrix.size1() > 0);
  assert(views > 0);
  assert(scans > 0);
  assert(min < max);
  assert(ang1 < ang2);
  int i = 0;
  std::vector<std::vector<double>> proj(views, std::vector<double>(scans)); //create vector of size views, initialize it with vector of size scans

  int x = 0, y = 0, Xcenter = 0, Ycenter = 0;

  std::unique_ptr<double[]>  sintab(new double[views]);
  std::unique_ptr<double[]>  costab(new double[views]);

  int scanNumber=0;
  int inputMatrixSize = emissionMatrix.size1();

  float phi = 0., stepsize = 0.;
  stepsize = (ang2 - ang1) / views;
  for (phi = ang1; phi < ang2; phi = phi + stepsize) {
      sintab[i] = std::sin((double) phi * M_PI / 180 - M_PI/2);
      costab[i] = std::cos((double) phi * M_PI / 180 - M_PI/2);
      i++;
  }

  Xcenter = inputMatrixSize / 2;
  Ycenter = inputMatrixSize / 2;
  i=0;
  //if no. scans is greater than the image width, then scale will be <1

  double scale = inputMatrixSize*1.42/scans;

  int N=0;
  double value = 0.;
  double weight = 0;
  double sang = std::sqrt(2)/2;
  for (phi=ang1;phi<ang2;phi=phi+stepsize){
      double a = -costab[i]/sintab[i] ;
      double aa = 1/a;
      if (std::abs(sintab[i]) > sang){
          for (scanNumber=0;scanNumber<scans;scanNumber++){
              N = scanNumber - scans/2;
              double b = (N - costab[i] - sintab[i]) / sintab[i];
              b =  b * scale;

              for (x = -Xcenter; x < Xcenter; x++){
                  if (fast == true){ //nearest neighbour interpolation
                      y = (int) std::round(a*x + b);

                      if (y >= -Xcenter && y < Xcenter )
                          value += emissionMatrix((x+Xcenter),(y+Ycenter));

                  } else {
                      y = (int) std::round(a*x + b); //linear interpolation
                      weight = std::abs((a*x + b) - std::ceil(a*x + b));

                      if (y >= -Xcenter && y+1 < Xcenter )
                          value += (1-weight) * emissionMatrix((x+Xcenter),(y+Ycenter))
                                  + weight * emissionMatrix((x+Xcenter), (y+Ycenter+1));

                  }
              } proj[i][scanNumber] = value/std::abs(sintab[i]); value=0;

          }
      }
      if (std::abs(sintab[i]) <= sang){
          for (scanNumber=0;scanNumber<scans;scanNumber++){
              N = scanNumber - scans/2;
              double bb = (N - costab[i] - sintab[i]) / costab[i];
              bb = bb * scale;
              for (y = -Ycenter; y < Ycenter; y++) {
                  if (fast ==true){ //nearest neighbour interpolation
                      x = (int) std::round(aa*y + bb);
                      if (x >= -Xcenter && x < Xcenter )
                          value += emissionMatrix(x+Xcenter, y+Ycenter);
                  } else { //linear interpolation
                      x = (int) std::round(aa*y + bb);
                      weight = std::abs((aa*y + bb) - std::ceil(aa*y + bb));

                      if (x >= -Xcenter && x+1 < Xcenter )
                          value += (1-weight) * emissionMatrix((x+Xcenter), (y+Ycenter))
                                  + weight * emissionMatrix((x+Xcenter+1), (y+Ycenter));

                  }
              } proj[i][scanNumber] = value/std::abs(costab[i]); value=0;

          }

      } i++;
  }
  i=0;

  double datamax = proj[0][0];
  double datamin = proj[0][0];
  for (unsigned int k = 0; k < proj.size(); k++ ) {
    for (unsigned int j = 0; j < proj[0].size(); j++ ) {
      if(proj[k][j] < min) proj[k][j] = min;
      if(proj[k][j] > datamax) datamax = proj[k][j];
      if(proj[k][j] < datamin) datamin = proj[k][j];
    }
  }
  for (unsigned int k = 0; k < proj.size(); k++ ) {
    for (unsigned int j = 0; j < proj[0].size(); j++ ) {
      proj[k][j] = (double) ((proj[k][j]-datamin) * max/datamax);
    }
  }

  return proj;
}<commit_msg>Add check to datamax and stepsize<commit_after>#include "./JPetSinogram.h"
#include <boost/numeric/ublas/matrix.hpp>
#include <vector>
#include <utility>
#include <cmath>
using namespace boost::numeric::ublas;

JPetSinogram::JPetSinogram() { }

JPetSinogram::~JPetSinogram() { }

/*! \brief Function returning vector of vectors with value of sinogram(180/views degree step and emissionMatrix.size1()/scans size) scaled to <min,max>
 *  \param emissionMatrix matrix, need to by NxN
 *  \param views number of views on object, degree step is calculated as (ang2 - ang1) / views
 *  \param scans number of scans on object, step is calculated as emissionMatrix.size(1) / scans
 *  \param fast if true use nearest neighbour interpolation instead linear interpolation in calculation (Optional, default false)
 *  \param min minimum value in returned sinogram (Optional, default 0)
 *  \param max maximum value in returned sinogram (Optional, default 255)
 *  \param ang1 start angle for projection (Optional, default 0)
 *  \param ang2 end angle for projection (Optional, default 180)
*/

std::vector<std::vector<double>> JPetSinogram::sinogram(matrix<int> emissionMatrix, int views, int scans,
                                                      bool fast, int min, int max, float ang1, float ang2) {
  assert(emissionMatrix.size1() == emissionMatrix.size2());
  assert(emissionMatrix.size1() > 0);
  assert(views > 0);
  assert(scans > 0);
  assert(min < max);
  assert(ang1 < ang2);
  int i = 0;
  std::vector<std::vector<double>> proj(views, std::vector<double>(scans)); //create vector of size views, initialize it with vector of size scans

  int x = 0, y = 0, Xcenter = 0, Ycenter = 0;

  std::unique_ptr<double[]>  sintab(new double[views]);
  std::unique_ptr<double[]>  costab(new double[views]);

  int scanNumber=0;
  int inputMatrixSize = emissionMatrix.size1();

  float phi = 0., stepsize = 0.;
  stepsize = (ang2 - ang1) / views;

  assert(stepsize > 0); //maybe != 0 ?

  for (phi = ang1; phi < ang2; phi = phi + stepsize) {
      sintab[i] = std::sin((double) phi * M_PI / 180 - M_PI/2);
      costab[i] = std::cos((double) phi * M_PI / 180 - M_PI/2);
      i++;
  }

  Xcenter = inputMatrixSize / 2;
  Ycenter = inputMatrixSize / 2;
  i=0;

  //if no. scans is greater than the image width, then scale will be <1
  double scale = inputMatrixSize*1.42/scans;

  int N=0;
  double value = 0.;
  double weight = 0.;
  double sang = std::sqrt(2)/2;
  for (phi=ang1;phi<ang2;phi=phi+stepsize){
      double a = -costab[i]/sintab[i];
      double aa = 1/a;
      if (std::abs(sintab[i]) > sang){
          for (scanNumber=0;scanNumber<scans;scanNumber++){
              N = scanNumber - scans/2;
              double b = (N - costab[i] - sintab[i]) / sintab[i];
              b =  b * scale;

              for (x = -Xcenter; x < Xcenter; x++){
                  if (fast == true){ //nearest neighbour interpolation
                      y = (int) std::round(a*x + b);

                      if (y >= -Xcenter && y < Xcenter )
                          value += emissionMatrix((x+Xcenter),(y+Ycenter));

                  } else {
                      y = (int) std::round(a*x + b); //linear interpolation
                      weight = std::abs((a*x + b) - std::ceil(a*x + b));

                      if (y >= -Xcenter && y+1 < Xcenter )
                          value += (1-weight) * emissionMatrix((x+Xcenter),(y+Ycenter))
                                  + weight * emissionMatrix((x+Xcenter), (y+Ycenter+1));

                  }
              } proj[i][scanNumber] = value/std::abs(sintab[i]); value=0;

          }
      }
      if (std::abs(sintab[i]) <= sang){
          for (scanNumber=0;scanNumber<scans;scanNumber++){
              N = scanNumber - scans/2;
              double bb = (N - costab[i] - sintab[i]) / costab[i];
              bb = bb * scale;
              for (y = -Ycenter; y < Ycenter; y++) {
                  if (fast ==true){ //nearest neighbour interpolation
                      x = (int) std::round(aa*y + bb);
                      if (x >= -Xcenter && x < Xcenter )
                          value += emissionMatrix(x+Xcenter, y+Ycenter);
                  } else { //linear interpolation
                      x = (int) std::round(aa*y + bb);
                      weight = std::abs((aa*y + bb) - std::ceil(aa*y + bb));

                      if (x >= -Xcenter && x+1 < Xcenter )
                          value += (1-weight) * emissionMatrix((x+Xcenter), (y+Ycenter))
                                  + weight * emissionMatrix((x+Xcenter+1), (y+Ycenter));

                  }
              } proj[i][scanNumber] = value/std::abs(costab[i]); value=0;

          }

      } i++;
  }
  i=0;

  double datamax = proj[0][0];
  double datamin = proj[0][0];
  for (unsigned int k = 0; k < proj.size(); k++ ) {
    for (unsigned int j = 0; j < proj[0].size(); j++ ) {
      if(proj[k][j] < min) proj[k][j] = min;
      if(proj[k][j] > datamax) datamax = proj[k][j];
      if(proj[k][j] < datamin) datamin = proj[k][j];
    }
  }

  if(datamax == 0.)
    datamax = 1.;

  for (unsigned int k = 0; k < proj.size(); k++ ) {
    for (unsigned int j = 0; j < proj[0].size(); j++ ) {
      proj[k][j] = (double) ((proj[k][j]-datamin) * max/datamax);
    }
  }

  return proj;
}<|endoftext|>


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

#include <system.hh>

#include "pyinterp.h"
#include "account.h"
#include "xact.h"
#include "post.h"

namespace ledger {

using namespace python;

shared_ptr<python_interpreter_t> python_session;

char * argv0;

void export_account();
void export_amount();
void export_balance();
void export_commodity();
void export_expr();
void export_format();
void export_item();
void export_journal();
void export_post();
void export_times();
void export_utils();
void export_value();
void export_xact();

void initialize_for_python()
{
  export_account();
  export_amount();
  export_balance();
  export_commodity();
  export_expr();
  export_format();
  export_item();
  export_journal();
  export_post();
  export_times();
  export_utils();
  export_value();
  export_xact();
}

struct python_run
{
  object result;

  python_run(python_interpreter_t * intepreter,
	     const string& str, int input_mode)
    : result(handle<>(borrowed(PyRun_String(str.c_str(), input_mode,
					    intepreter->main_nspace.ptr(),
					    intepreter->main_nspace.ptr())))) {}
  operator object() {
    return result;
  }
};

void python_interpreter_t::initialize()
{
  TRACE_START(python_init, 1, "Initialized Python");

  try {
    DEBUG("python.interp", "Initializing Python");

    Py_Initialize();
    assert(Py_IsInitialized());

    object main_module = python::import("__main__");
    if (! main_module)
      throw_(std::logic_error,
	     _("Python failed to initialize (couldn't find __main__)"));

    main_nspace = extract<dict>(main_module.attr("__dict__"));
    if (! main_nspace)
      throw_(std::logic_error,
	     _("Python failed to initialize (couldn't find __dict__)"));

    python::detail::init_module("ledger", &initialize_for_python);

    is_initialized = true;

    // Hack ledger.__path__ so it points to a real location
    python::object module_sys = import("sys");
    python::object sys_dict   = module_sys.attr("__dict__");

    python::list paths(sys_dict["path"]);

    bool path_initialized = false;
    int n = python::extract<int>(paths.attr("__len__")());
    for (int i = 0; i < n; i++) {
      python::extract<std::string> str(paths[i]);
      path pathname(str);
      DEBUG("python.interp", "sys.path = " << pathname);

      if (exists(pathname / "ledger" / "__init__.py")) {
	if (python::object module_ledger = import("ledger")) {
	  DEBUG("python.interp",
		"Setting ledger.__path__ = " << (pathname / "ledger"));

	  python::object ledger_dict = module_ledger.attr("__dict__");
	  python::list temp_list;
	  temp_list.append((pathname / "ledger").string());

	  ledger_dict["__path__"] = temp_list;
	} else {
	  throw_(std::logic_error,
		 _("Python failed to initialize (couldn't find ledger)"));
	}
	path_initialized = true;
	break;
      }
    }
#if defined(DEBUG_ON)
    if (! path_initialized)
      DEBUG("python.init",
	    "Ledger failed to find 'ledger/__init__.py' on the PYTHONPATH");
#endif
  }
  catch (const error_already_set&) {
    PyErr_Print();
    throw_(std::logic_error, _("Python failed to initialize"));
  }

  TRACE_FINISH(python_init, 1);
}

object python_interpreter_t::import(const string& str)
{
  if (! is_initialized)
    initialize();

  try {
    object mod = python::import(str.c_str());
    if (! mod)
      throw_(std::logic_error, _("Failed to import Python module %1") << str);

    // Import all top-level entries directly into the main namespace
    main_nspace.update(mod.attr("__dict__"));

    return mod;
  }
  catch (const error_already_set&) {
    PyErr_Print();
  }
  return object();
}

object python_interpreter_t::eval(std::istream& in, py_eval_mode_t mode)
{
  bool	 first = true;
  string buffer;
  buffer.reserve(4096);

  while (! in.eof()) {
    char buf[256];
    in.getline(buf, 255);
    if (buf[0] == '!')
      break;
    if (first)
      first = false;
    else
      buffer += "\n";
    buffer += buf;
  }

  if (! is_initialized)
    initialize();

  try {
    int input_mode = -1;
    switch (mode) {
    case PY_EVAL_EXPR:  input_mode = Py_eval_input;   break;
    case PY_EVAL_STMT:  input_mode = Py_single_input; break;
    case PY_EVAL_MULTI: input_mode = Py_file_input;   break;
    }

    return python_run(this, buffer, input_mode);
  }
  catch (const error_already_set&) {
    PyErr_Print();
    throw_(std::logic_error, _("Failed to evaluate Python code"));
  }
  return object();
}

object python_interpreter_t::eval(const string& str, py_eval_mode_t mode)
{
  if (! is_initialized)
    initialize();

  try {
    int input_mode = -1;
    switch (mode) {
    case PY_EVAL_EXPR:  input_mode = Py_eval_input;   break;
    case PY_EVAL_STMT:  input_mode = Py_single_input; break;
    case PY_EVAL_MULTI: input_mode = Py_file_input;   break;
    }

    return python_run(this, str, input_mode);
  }
  catch (const error_already_set&) {
    PyErr_Print();
    throw_(std::logic_error, _("Failed to evaluate Python code"));
  }
  return object();
}

value_t python_interpreter_t::python_command(call_scope_t& args)
{
  if (! is_initialized)
    initialize();

  char ** argv(new char *[args.size() + 1]);

  argv[0] = new char[std::strlen(argv0) + 1];
  std::strcpy(argv[0], argv0);

  for (std::size_t i = 0; i < args.size(); i++) {
    string arg = args[i].as_string();
    argv[i + 1] = new char[arg.length() + 1];
    std::strcpy(argv[i + 1], arg.c_str());
  }

  int status = Py_Main(static_cast<int>(args.size()) + 1, argv);

  for (std::size_t i = 0; i < args.size() + 1; i++)
    delete[] argv[i];
  delete[] argv;

  if (status != 0)
    throw status;

  return NULL_VALUE;
}

option_t<python_interpreter_t> *
python_interpreter_t::lookup_option(const char * p)
{
  switch (*p) {
  case 'i':
    OPT(import_);
    break;
  }
  return NULL;
}

expr_t::ptr_op_t python_interpreter_t::lookup(const symbol_t::kind_t kind,
					      const string& name)
{
  // Give our superclass first dibs on symbol definitions
  if (expr_t::ptr_op_t op = session_t::lookup(kind, name))
    return op;

  switch (kind) {
  case symbol_t::FUNCTION:
    if (is_initialized && main_nspace.has_key(name.c_str())) {
      DEBUG("python.interp", "Python lookup: " << name);

      if (python::object obj = main_nspace.get(name.c_str()))
	return WRAP_FUNCTOR(functor_t(name, obj));
    }
    break;

  case symbol_t::OPTION:
    if (option_t<python_interpreter_t> * handler = lookup_option(name.c_str()))
      return MAKE_OPT_HANDLER(python_interpreter_t, handler);
    break;

  case symbol_t::PRECOMMAND: {
    const char * p = name.c_str();
    switch (*p) {
    case 'p':
      if (is_eq(p, "python"))
	return MAKE_FUNCTOR(python_interpreter_t::python_command);
      break;
    }
  }

  default:
    break;
  }

  return NULL;
}

namespace {
  void append_value(list& lst, const value_t& value)
  {
    if (value.is_scope()) {
      const scope_t * scope = value.as_scope();
      if (const post_t * post = dynamic_cast<const post_t *>(scope))
	lst.append(ptr(post));
      else if (const xact_t * xact = dynamic_cast<const xact_t *>(scope))
	lst.append(ptr(xact));
      else if (const account_t * account =
	       dynamic_cast<const account_t *>(scope))
	lst.append(ptr(account));
      else if (const period_xact_t * period_xact =
	       dynamic_cast<const period_xact_t *>(scope))
	lst.append(ptr(period_xact));
      else if (const auto_xact_t * auto_xact =
	       dynamic_cast<const auto_xact_t *>(scope))
	lst.append(ptr(auto_xact));
      else
	throw_(std::runtime_error,
	       _("Cannot downcast scoped object to specific type"));
    } else {
      lst.append(value);
    }
  }
}

value_t python_interpreter_t::functor_t::operator()(call_scope_t& args)
{
  try {
    std::signal(SIGINT, SIG_DFL);

    if (! PyCallable_Check(func.ptr())) {
      extract<value_t> val(func);
      std::signal(SIGINT, sigint_handler);
      if (val.check())
	return val();
#if 1
      // jww (2009-02-24): Distinguish between "no return" and values with
      // unconvertable type
      return NULL_VALUE;
#else
      throw_(calc_error,
	     _("Could not evaluate Python variable '%1'") << name);
#endif
    }
    else if (args.size() > 0) {
      list arglist;
      // jww (2009-11-05): What about a single argument which is a sequence,
      // rather than a sequence of arguments?
      if (args.value().is_sequence())
	foreach (const value_t& value, args.value().as_sequence())
	  append_value(arglist, value);
      else
	append_value(arglist, args.value());

      if (PyObject * val =
	  PyObject_CallObject(func.ptr(), python::tuple(arglist).ptr())) {
	extract<value_t> xval(val);
	value_t result;
	if (xval.check()) {
	  result = xval();
	  Py_DECREF(val);
	} else {
	  Py_DECREF(val);
	  throw_(calc_error,
		 _("Could not evaluate Python variable '%1'") << name);
	}
	std::signal(SIGINT, sigint_handler);
	return result;
      }
      else if (PyErr_Occurred()) {
	PyErr_Print();
	throw_(calc_error, _("Failed call to Python function '%1'") << name);
      } else {
	assert(false);
      }
    }
    else {
      std::signal(SIGINT, sigint_handler);
      return call<value_t>(func.ptr());
    }
  }
  catch (const error_already_set&) {
    std::signal(SIGINT, sigint_handler);
    PyErr_Print();
    throw_(calc_error, _("Failed call to Python function '%1'") << name);
  }
  catch (...) {
    std::signal(SIGINT, sigint_handler);
  }
  std::signal(SIGINT, sigint_handler);

  return NULL_VALUE;
}

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

#include <system.hh>

#include "pyinterp.h"
#include "account.h"
#include "xact.h"
#include "post.h"

namespace ledger {

using namespace python;

shared_ptr<python_interpreter_t> python_session;

char * argv0;

void export_account();
void export_amount();
void export_balance();
void export_commodity();
void export_expr();
void export_format();
void export_item();
void export_journal();
void export_post();
void export_times();
void export_utils();
void export_value();
void export_xact();

void initialize_for_python()
{
  export_account();
  export_amount();
  export_balance();
  export_commodity();
  export_expr();
  export_format();
  export_item();
  export_journal();
  export_post();
  export_times();
  export_utils();
  export_value();
  export_xact();
}

struct python_run
{
  object result;

  python_run(python_interpreter_t * intepreter,
	     const string& str, int input_mode)
    : result(handle<>(borrowed(PyRun_String(str.c_str(), input_mode,
					    intepreter->main_nspace.ptr(),
					    intepreter->main_nspace.ptr())))) {}
  operator object() {
    return result;
  }
};

void python_interpreter_t::initialize()
{
  TRACE_START(python_init, 1, "Initialized Python");

  try {
    DEBUG("python.interp", "Initializing Python");

    Py_Initialize();
    assert(Py_IsInitialized());

    object main_module = python::import("__main__");
    if (! main_module)
      throw_(std::logic_error,
	     _("Python failed to initialize (couldn't find __main__)"));

    main_nspace = extract<dict>(main_module.attr("__dict__"));
    if (! main_nspace)
      throw_(std::logic_error,
	     _("Python failed to initialize (couldn't find __dict__)"));

    python::detail::init_module("ledger", &initialize_for_python);

    is_initialized = true;

    // Hack ledger.__path__ so it points to a real location
    python::object module_sys = import("sys");
    python::object sys_dict   = module_sys.attr("__dict__");

    python::list paths(sys_dict["path"]);

    bool path_initialized = false;
    int n = python::extract<int>(paths.attr("__len__")());
    for (int i = 0; i < n; i++) {
      python::extract<std::string> str(paths[i]);
      path pathname(str);
      DEBUG("python.interp", "sys.path = " << pathname);

      if (exists(pathname / "ledger" / "__init__.py")) {
	if (python::object module_ledger = import("ledger")) {
	  DEBUG("python.interp",
		"Setting ledger.__path__ = " << (pathname / "ledger"));

	  python::object ledger_dict = module_ledger.attr("__dict__");
	  python::list temp_list;
	  temp_list.append((pathname / "ledger").string());

	  ledger_dict["__path__"] = temp_list;
	} else {
	  throw_(std::logic_error,
		 _("Python failed to initialize (couldn't find ledger)"));
	}
	path_initialized = true;
	break;
      }
    }
#if defined(DEBUG_ON)
    if (! path_initialized)
      DEBUG("python.init",
	    "Ledger failed to find 'ledger/__init__.py' on the PYTHONPATH");
#endif
  }
  catch (const error_already_set&) {
    PyErr_Print();
    throw_(std::logic_error, _("Python failed to initialize"));
  }

  TRACE_FINISH(python_init, 1);
}

object python_interpreter_t::import(const string& str)
{
  if (! is_initialized)
    initialize();

  try {
    object mod = python::import(str.c_str());
    if (! mod)
      throw_(std::logic_error, _("Failed to import Python module %1") << str);

    // Import all top-level entries directly into the main namespace
    main_nspace.update(mod.attr("__dict__"));

    return mod;
  }
  catch (const error_already_set&) {
    PyErr_Print();
  }
  return object();
}

object python_interpreter_t::eval(std::istream& in, py_eval_mode_t mode)
{
  bool	 first = true;
  string buffer;
  buffer.reserve(4096);

  while (! in.eof()) {
    char buf[256];
    in.getline(buf, 255);
    if (buf[0] == '!')
      break;
    if (first)
      first = false;
    else
      buffer += "\n";
    buffer += buf;
  }

  if (! is_initialized)
    initialize();

  try {
    int input_mode = -1;
    switch (mode) {
    case PY_EVAL_EXPR:  input_mode = Py_eval_input;   break;
    case PY_EVAL_STMT:  input_mode = Py_single_input; break;
    case PY_EVAL_MULTI: input_mode = Py_file_input;   break;
    }

    return python_run(this, buffer, input_mode);
  }
  catch (const error_already_set&) {
    PyErr_Print();
    throw_(std::logic_error, _("Failed to evaluate Python code"));
  }
  return object();
}

object python_interpreter_t::eval(const string& str, py_eval_mode_t mode)
{
  if (! is_initialized)
    initialize();

  try {
    int input_mode = -1;
    switch (mode) {
    case PY_EVAL_EXPR:  input_mode = Py_eval_input;   break;
    case PY_EVAL_STMT:  input_mode = Py_single_input; break;
    case PY_EVAL_MULTI: input_mode = Py_file_input;   break;
    }

    return python_run(this, str, input_mode);
  }
  catch (const error_already_set&) {
    PyErr_Print();
    throw_(std::logic_error, _("Failed to evaluate Python code"));
  }
  return object();
}

value_t python_interpreter_t::python_command(call_scope_t& args)
{
  if (! is_initialized)
    initialize();

  char ** argv(new char *[args.size() + 1]);

  argv[0] = new char[std::strlen(argv0) + 1];
  std::strcpy(argv[0], argv0);

  for (std::size_t i = 0; i < args.size(); i++) {
    string arg = args[i].as_string();
    argv[i + 1] = new char[arg.length() + 1];
    std::strcpy(argv[i + 1], arg.c_str());
  }

  int status = Py_Main(static_cast<int>(args.size()) + 1, argv);

  for (std::size_t i = 0; i < args.size() + 1; i++)
    delete[] argv[i];
  delete[] argv;

  if (status != 0)
    throw status;

  return NULL_VALUE;
}

option_t<python_interpreter_t> *
python_interpreter_t::lookup_option(const char * p)
{
  switch (*p) {
  case 'i':
    OPT(import_);
    break;
  }
  return NULL;
}

expr_t::ptr_op_t python_interpreter_t::lookup(const symbol_t::kind_t kind,
					      const string& name)
{
  // Give our superclass first dibs on symbol definitions
  if (expr_t::ptr_op_t op = session_t::lookup(kind, name))
    return op;

  switch (kind) {
  case symbol_t::FUNCTION:
    if (is_initialized && main_nspace.has_key(name.c_str())) {
      DEBUG("python.interp", "Python lookup: " << name);

      if (python::object obj = main_nspace.get(name.c_str()))
	return WRAP_FUNCTOR(functor_t(name, obj));
    }
    break;

  case symbol_t::OPTION:
    if (option_t<python_interpreter_t> * handler = lookup_option(name.c_str()))
      return MAKE_OPT_HANDLER(python_interpreter_t, handler);
    break;

  case symbol_t::PRECOMMAND: {
    const char * p = name.c_str();
    switch (*p) {
    case 'p':
      if (is_eq(p, "python"))
	return MAKE_FUNCTOR(python_interpreter_t::python_command);
      break;
    }
  }

  default:
    break;
  }

  return NULL;
}

namespace {
  void append_value(list& lst, const value_t& value)
  {
    if (value.is_scope()) {
      const scope_t * scope = value.as_scope();
      if (const post_t * post = dynamic_cast<const post_t *>(scope))
	lst.append(ptr(post));
      else if (const xact_t * xact = dynamic_cast<const xact_t *>(scope))
	lst.append(ptr(xact));
      else if (const account_t * account =
	       dynamic_cast<const account_t *>(scope))
	lst.append(ptr(account));
      else if (const period_xact_t * period_xact =
	       dynamic_cast<const period_xact_t *>(scope))
	lst.append(ptr(period_xact));
      else if (const auto_xact_t * auto_xact =
	       dynamic_cast<const auto_xact_t *>(scope))
	lst.append(ptr(auto_xact));
      else
	throw_(std::runtime_error,
	       _("Cannot downcast scoped object to specific type"));
    } else {
      lst.append(value);
    }
  }
}

value_t python_interpreter_t::functor_t::operator()(call_scope_t& args)
{
  try {
    std::signal(SIGINT, SIG_DFL);

    if (! PyCallable_Check(func.ptr())) {
      extract<value_t> val(func);
      std::signal(SIGINT, sigint_handler);
      if (val.check())
	return val();
      return NULL_VALUE;
    }
    else if (args.size() > 0) {
      list arglist;
      // jww (2009-11-05): What about a single argument which is a sequence,
      // rather than a sequence of arguments?
      if (args.value().is_sequence())
	foreach (const value_t& value, args.value().as_sequence())
	  append_value(arglist, value);
      else
	append_value(arglist, args.value());

      if (PyObject * val =
	  PyObject_CallObject(func.ptr(), python::tuple(arglist).ptr())) {
	extract<value_t> xval(val);
	value_t result;
	if (xval.check()) {
	  result = xval();
	  Py_DECREF(val);
	} else {
	  Py_DECREF(val);
	  throw_(calc_error,
		 _("Could not evaluate Python variable '%1'") << name);
	}
	std::signal(SIGINT, sigint_handler);
	return result;
      }
      else if (PyErr_Occurred()) {
	PyErr_Print();
	throw_(calc_error, _("Failed call to Python function '%1'") << name);
      } else {
	assert(false);
      }
    }
    else {
      std::signal(SIGINT, sigint_handler);
      return call<value_t>(func.ptr());
    }
  }
  catch (const error_already_set&) {
    std::signal(SIGINT, sigint_handler);
    PyErr_Print();
    throw_(calc_error, _("Failed call to Python function '%1'") << name);
  }
  catch (...) {
    std::signal(SIGINT, sigint_handler);
  }
  std::signal(SIGINT, sigint_handler);

  return NULL_VALUE;
}

} // namespace ledger
<|endoftext|>