python in openFrameworks(c++)

openFrameworks(c++)の中でpythonを実行する.

この記事は, 偉大なる先駆者様の記事を試させていただいた, というだけの個人的な備忘録です.

当該記事はつい先ほど投稿された @Hzikajr さんの記事
http://qiita.com/Hzikajr/items/afe73cb287af5ab90265
です.
こんな僕の記事よりもぜひそちらを読まれるべき.
というか読んでください.
この僕の記事には重要なポイントは載ってないです.

pyenvはこちらを参考にしました:
http://www.python-izm.com/contents/basis/pyenv.shtml

個人的にpythonとoFの連携に苦しんでいたので大変助かりました.
テストは @Hzikajr さんと全く同じ環境です.
satoruhigaさんのofxPy
https://github.com/satoruhiga/ofxPy
のexampleの一部も試しました.

print('hello from test_script.py')

def my_fn():
    print ('hello from python function')

def my_fn2(theta):
    import math
    a = math.sin(theta * math.pi)
    return a

def get_random():
    import random
    return (random.random(), random.random())

def size_expression(t):
    import math
    return abs(math.sin(t * math.pi) + math.sin(t * math.pi * 1.5))
#pragma once

#include "ofMain.h"
#include "ofxPy.h"

class ofApp : public ofBaseApp{

    public:
        void setup();
        void update();
        void draw();

        void keyPressed(int key);
        void keyReleased(int key);
        void mouseMoved(int x, int y );
        void mouseDragged(int x, int y, int button);
        void mousePressed(int x, int y, int button);
        void mouseReleased(int x, int y, int button);
        void mouseEntered(int x, int y);
        void mouseExited(int x, int y);
        void windowResized(int w, int h);
        void dragEvent(ofDragInfo dragInfo);
        void gotMessage(ofMessage msg);

    ofxPy::Context  python;
};
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

    putenv((char *)"PYTHONHOME=/Users/ksumiya/.pyenv/versions/anaconda3-4.3.1");
    python.setup();

    ofSetFrameRate(60);
    ofSetVerticalSync(true);
    ofBackground(0);

    // append data/python to PYTHONPATH
    python.appendPath(ofToDataPath("python"));

    // import and call python script function
    python.exec("import test_script; test_script.my_fn()");

}

//--------------------------------------------------------------
void ofApp::update(){
    ofSetWindowTitle(ofToString(ofGetFrameRate()));
}

//--------------------------------------------------------------
void ofApp::draw(){
    // get tuple return value
    auto v = python.eval<ofxPy::tuple>("test_script.get_random()");

    // unpack and cast array-like object
    float x = ofxPy::get<float>(v, 0) * ofGetWidth();
    float y = ofxPy::get<float>(v, 1) * ofGetHeight();
    ofDrawRectangle(x, y, 10, 10);

    // get function and call with argument
    float s = python.eval("test_script.size_expression").call(ofGetElapsedTimef()).cast<float>();
    ofDrawCircle(ofGetMouseX(), ofGetMouseY(), s * 50);

    float a = python.eval("test_script.my_fn2").call(0.25).cast<float>();
    string msg;
    msg += ofToString(1/a) + "\n";
    ofSetColor(255);
    ofDrawBitmapString(msg, 100, 100);

}

僕が足したのはmy_fn2の部分だけ.
結果として, 1/sin(pi/4) なので, sqrt(2)となり, 1.414...がでます.

先駆者様, 偉大だ…