ofxPDF便利な使い方

##概要
> satoruhigaさんが作られたopenFrameworksのAddon ofxPDFの(私が個人的に)便利だなあと思った使い方について紹介します。
ここで適当なpathだけの状態のpdfがあればいいのですが、ない場合Illustratorで作成する方法を、この記事の最後に載せておくのでそちらを参照してください。以降、そのようなpdfがあることを前提に紹介します。
またここで解説するサンプルプロジェクトはgithubで公開しています。
https://github.com/Hiroki11x/openFrameworksSample/tree/master/ofxPDF_Sample

##下整備
>まずはじめに、ofxPDFのaddonをof_0.9.~/addons/内に用意します。
https://github.com/satoruhiga/ofxPDF

> そのaddonを追加したプロジェクトを作ります。(既存のプロジェクトに追加でも大丈夫です)
<img width="612" alt="スクリーンショット 2016-05-02 19.28.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/7b5bba64-aa01-20bf-9290-1ad40572712c.png">

##ofxPDFのみを使ったサンプルの作成
> ofApp.hにofxPDFをincludeし、メンバ変数も宣言しておきます。

```ofApp.h
#pragma once

#include "ofMain.h"
#include "ofxPDF.h"
class ofApp : public ofBaseApp{
private:
    ofxPDF mPDF;
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);
    
};
```

> 次に、ofApp.cpp内に、pdfのロード、描画命令を記述します。

```ofApp.cpp
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    mPDF.load("sample.pdf");
}

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

}

//--------------------------------------------------------------
void ofApp::draw(){
    mPDF.draw();
}
```
> ここで記述したものはaddon内のsampleと同じものです。
実行結果は以下のとおり

> ![スクリーンショット 2016-05-02 20.10.16.png](https://qiita-image-store.s3.amazonaws.com/0/56510/9df96bd8-2fed-8767-da62-2e12da2aed25.png)

> 次に、このPDFのpathをofPathを用いて書く方法を紹介します。ofPathで書くことにより、線の太さ色、さらにはアニメーションなど様々なことができるようになります。

##ofPathを用いた拡張
> ofApp.hにofPath型のメンバ変数を新たに宣言しておきます。

```ofApp.h
#pragma once

#include "ofMain.h"
#include "ofxPDF.h"
class ofApp : public ofBaseApp{
private:
    ofxPDF mPDF;
    ofPath mPath;
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);
    
};
```


> 次に、ofApp.cpp内に、pdfからpathのロード、pathの描画命令を記述します。


```ofApp.cpp
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    mPDF.load("sample.pdf");

    mPath.setFilled(false);
    mPath.setStrokeWidth(5);
    mPath.setStrokeHexColor(0x0022ff);
    for (int i = 0; i < mPDF.getNumPath(); i++){
        ofPath& path = mPDF.getPathAt(i);
        mPath.append(path);
    }
    mPath.close();
}

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

}

//--------------------------------------------------------------
void ofApp::draw(){
    mPath.draw();
}
```

> これで実行すると以下のようになります
![スクリーンショット 2016-05-02 20.22.54.png](https://qiita-image-store.s3.amazonaws.com/0/56510/6a02bbc7-ac4d-88f3-f805-1ef07dae23b2.png)

##ofPolylineを用いたアニメーション
> 次に先ほどのPDFをアニメーションさせて描画させます。
まずはofApp.hにofPolyline型のvectorを宣言します。また、pathのアニメーションを描画する関数drawAnimation()も宣言します。

```ofApp.h
#pragma once

#include "ofMain.h"
#include "ofxPDF.h"
class ofApp : public ofBaseApp{
private:
    ofxPDF mPDF;
//    ofPath mPath; //<-今回は使わない
    vector<ofPolyline> polys;
public:
    void setup();
    void update();
    void draw();
    void drawAnimation();

    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);
    
};
```

> ofApp.cppにsetupでのPolylineへのpathのpush_back、また関数drawAnimation()の宣言を以下のようにしました。


```ofApp.cpp
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    mPDF.load("sample.pdf");

    /* ofPathは今回使わない
    mPath.setFilled(false);
    mPath.setStrokeWidth(15);
    mPath.setStrokeHexColor(0x0022ff);
    for (int i = 0; i < mPDF.getNumPath(); i++){
        ofPath& path = mPDF.getPathAt(i);
        mPath.append(path);
    }
    mPath.close();
     */

    // PDFのパスを順番に取り出し、細かく分けたやつをpolysにpush_backしていく
    for (int i = 0; i < mPDF.getNumPath(); i++){
        ofPath& path = mPDF.getPathAt(i);
        const vector<ofPolyline > &tmpPoly = path.getOutline();
        for (int k = 0; k < tmpPoly.size(); k++){
            polys.push_back(tmpPoly[k]);
        }
    }
}

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

}

//--------------------------------------------------------------
void ofApp::draw(){
//    mPath.draw();
    drawAnimation();
}

//--------------------------------------------------------------
void ofApp::drawAnimation(){
    ofPolyline tmpPoly;
    float animation_time = fmodf(ofGetElapsedTimef(), 1) * 4;
    for (int k = 0; k < polys.size(); k++){
        tmpPoly = polys.at(k).getResampledByCount(100);
        int target_size = polys.size() * animation_time;
        tmpPoly.resize(target_size);
        tmpPoly.draw();
    }
}
```

> これを実行すると、次のようになります。


> ![movie.gif](https://qiita-image-store.s3.amazonaws.com/0/56510/3d9b05cc-5d3f-4652-2b63-ac421c501ecf.gif)


##応用例
> 他にも、このパスの座標を用いてparticleのアニメーションが作れたり、そのpath上をオブジェクトが動いたりします、例えば以下のようなのもofxPDFを用いて作りました。

> ![mov.gif](https://github.com/Hiroki11x/openFrameworksSample/blob/master/openFrameworks_Abe_Birthday/movie.gif?raw=true)
> ![gif0](https://media.giphy.com/media/3oz8xzfMy0JNcZG4Kc/giphy.gif)
> ofxPDFの紹介は以上です、以降Illustratorでpathだけのpdfを作成する方法を紹介します。

##Illustratorでのpathだけのpdfの作成方法
> 以下の5stepで出来ます！簡単です！

> ###01
> Illustratorを開き新規作成
<img width="1440" alt="スクリーンショット 2016-05-02 19.42.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/6d1903a9-bdee-d02b-a3cb-0dcaa19902bd.png">

> ###02
> 適当な描画したいものを作る
<img width="1440" alt="スクリーンショット 2016-05-02 19.45.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/d2fa3841-a7ed-3da8-22ec-157388f29856.png">

> ###03
> アウトライン化できるものはアウトライン化(文字とか)
<img width="1440" alt="スクリーンショット 2016-05-02 19.47.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/520b2169-c0b0-5f27-ac3b-678489a82ba4.png">

> ###04
> 図形などの最初からpathのオブジェクトは塗りをなくす
<img width="1440" alt="スクリーンショット 2016-05-02 19.48.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/1318308a-eca3-6ad9-7805-05ca5ffab0b9.png">

> ###05
> 最後にPDFで書き出しを選択
<img width="1440" alt="スクリーンショット 2016-05-02 19.48.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/e5dc2780-060d-685a-2df9-c5ac2c0c371f.png">
以上となります。