├── example
├── addons.make
├── bin
│ └── data
│ │ └── of.png
├── src
│ ├── main.cpp
│ ├── ofApp.h
│ └── ofApp.cpp
├── Makefile
├── Project.xcconfig
├── openFrameworks-Info.plist
├── example.xcodeproj
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ ├── example Debug.xcscheme
│ │ │ └── example Release.xcscheme
│ └── project.pbxproj
└── config.make
├── .github
└── FUNDING.yml
├── ofxaddons_thumbnail.png
├── .gitattributes
├── src
├── utils
│ ├── ofxMeshWarpManagedController.h
│ └── ofxMeshWarpManagedController.cpp
├── ofxMeshWarpIO.h
├── ofxMeshWarpIO.cpp
├── ofxMeshWarp.h
├── ofxMeshWarpController.h
├── ofxMeshWarp.cpp
└── ofxMeshWarpController.cpp
├── readme.md
└── .gitignore
/example/addons.make:
--------------------------------------------------------------------------------
1 | ofxMeshWarp
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: nariakiiwatani
4 |
--------------------------------------------------------------------------------
/example/bin/data/of.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nariakiiwatani/ofxMeshWarp/HEAD/example/bin/data/of.png
--------------------------------------------------------------------------------
/ofxaddons_thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nariakiiwatani/ofxMeshWarp/HEAD/ofxaddons_thumbnail.png
--------------------------------------------------------------------------------
/example/src/main.cpp:
--------------------------------------------------------------------------------
1 | #include "ofMain.h"
2 | #include "ofApp.h"
3 |
4 | //========================================================================
5 | int main( ){
6 | ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context
7 |
8 | // this kicks off the running of my app
9 | // can be OF_WINDOW or OF_FULLSCREEN
10 | // pass in width and height too:
11 | ofRunApp(new ofApp());
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/example/Makefile:
--------------------------------------------------------------------------------
1 | # Attempt to load a config.make file.
2 | # If none is found, project defaults in config.project.make will be used.
3 | ifneq ($(wildcard config.make),)
4 | include config.make
5 | endif
6 |
7 | # make sure the the OF_ROOT location is defined
8 | ifndef OF_ROOT
9 | OF_ROOT=$(realpath ../../..)
10 | endif
11 |
12 | # call the project makefile!
13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk
14 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # This is based on the Github .gitattributes templates
2 | # Set default behaviour, in case users don't have core.autocrlf set.
3 | * text=auto
4 |
5 | # Explicitly declare text files we want to always be normalized and converted
6 | # to native line endings on checkout.
7 | *.cpp text
8 | *.h text
9 | *.mm text
10 |
11 | # Declare files that will always have CRLF line endings on checkout.
12 | *.sln text eol=crlf
13 | *.vcxproj* text eol=crlf
14 |
15 | # Denote all files that are truly binary and should not be modified.
16 | *.png binary
17 | *.jpg binary
18 |
19 | # Exclude .patch files in apothecary from EOL normalization
20 | scripts/apothecary/**/*.patch -text
21 |
22 |
--------------------------------------------------------------------------------
/example/Project.xcconfig:
--------------------------------------------------------------------------------
1 | //THE PATH TO THE ROOT OF OUR OF PATH RELATIVE TO THIS PROJECT.
2 | //THIS NEEDS TO BE DEFINED BEFORE CoreOF.xcconfig IS INCLUDED
3 | OF_PATH = ../../..
4 |
5 | //THIS HAS ALL THE HEADER AND LIBS FOR OF CORE
6 | #include "../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig"
7 |
8 | //ICONS - NEW IN 0072
9 | ICON_NAME_DEBUG = icon-debug.icns
10 | ICON_NAME_RELEASE = icon.icns
11 | ICON_FILE_PATH = $(OF_PATH)/libs/openFrameworksCompiled/project/osx/
12 |
13 | //IF YOU WANT AN APP TO HAVE A CUSTOM ICON - PUT THEM IN YOUR DATA FOLDER AND CHANGE ICON_FILE_PATH to:
14 | //ICON_FILE_PATH = bin/data/
15 |
16 | OTHER_CFLAGS = $(OF_CORE_CFLAGS)
17 | OTHER_LDFLAGS = $(OF_CORE_LIBS) $(OF_CORE_FRAMEWORKS)
18 | HEADER_SEARCH_PATHS = $(OF_CORE_HEADERS)
19 |
--------------------------------------------------------------------------------
/example/openFrameworks-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 | ${ICON}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundlePackageType
16 | APPL
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1.0
21 |
22 |
23 |
--------------------------------------------------------------------------------
/example/src/ofApp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofMain.h"
4 | #include "ofxMeshWarp.h"
5 | #include "ofxMeshWarpManagedController.h"
6 |
7 | class ofApp : public ofBaseApp{
8 |
9 | public:
10 | void setup();
11 | void update();
12 | void draw();
13 |
14 | void keyPressed(int key);
15 | void keyReleased(int key);
16 | void mouseMoved(int x, int y );
17 | void mouseDragged(int x, int y, int button);
18 | void mousePressed(int x, int y, int button);
19 | void mouseReleased(int x, int y, int button);
20 | void mouseEntered(int x, int y);
21 | void mouseExited(int x, int y);
22 | void windowResized(int w, int h);
23 | void dragEvent(ofDragInfo dragInfo);
24 | void gotMessage(ofMessage msg);
25 | private:
26 | std::shared_ptr mesh_;
27 | ofxMeshWarpController controller_;
28 | ofTexture tex_;
29 | };
30 |
--------------------------------------------------------------------------------
/src/utils/ofxMeshWarpManagedController.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofxMeshWarpController.h"
4 | #include "ofEvents.h"
5 |
6 | namespace ofx{namespace MeshWarp{
7 | namespace Editor {
8 | class ManagedController : public ControllerBase {
9 | public:
10 | void add(std::shared_ptr target);
11 | void clear();
12 | void clearOperation();
13 |
14 | void setUVResolution(const glm::vec2 &res) { mover_.setUVResolution(res); }
15 |
16 | void setAnchorPoint(float x, float y);
17 | void setTranslation(float x, float y);
18 | void setScale(float s);
19 |
20 | void drawCustom() const;
21 |
22 | void mousePressed(ofMouseEventArgs &args);
23 | void mouseReleased(ofMouseEventArgs &args);
24 | void mouseMoved(ofMouseEventArgs &args);
25 | void mouseDragged(ofMouseEventArgs &args);
26 | void mouseScrolled(ofMouseEventArgs &args);
27 | void mouseEntered(ofMouseEventArgs &args);
28 | void mouseExited(ofMouseEventArgs &args);
29 | void keyPressed(ofKeyEventArgs &args);
30 | void keyReleased(ofKeyEventArgs &args);
31 | private:
32 | bool is_mover_active_ = false;
33 | bool is_divider_active_ = false;
34 | PointController mover_;
35 | DivideController divider_;
36 | std::vector controllers_{&mover_,÷r_};
37 | void activateMover();
38 | void activateDivider();
39 | };
40 | }
41 | }}
42 | using ofxMeshWarpController = ofx::MeshWarp::Editor::ManagedController;
43 |
--------------------------------------------------------------------------------
/src/ofxMeshWarpIO.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofxMeshWarp.h"
4 | #include "ofFileUtils.h"
5 |
6 | namespace ofx{namespace MeshWarp{
7 | namespace IO {
8 | class PointHelper {
9 | public:
10 | PointHelper(MeshPoint *p):target_(p){}
11 | void get(ofBuffer &buffer) const;
12 | int set(const char *buffer);
13 | private:
14 | MeshPoint *target_;
15 | struct PointData {
16 | glm::vec3 point;
17 | glm::vec2 coord;
18 | glm::vec3 normal;
19 | ofFloatColor color;
20 | bool is_node;
21 | };
22 | };
23 | class MeshHelper {
24 | public:
25 | MeshHelper(Mesh *m):target_(m){}
26 | void get(ofBuffer &buffer) const;
27 | int set(const char *buffer);
28 | private:
29 | Mesh *target_;
30 | struct MeshData {
31 | int divx, divy, resolution;
32 | ofVec4f uv_rect;
33 | };
34 | };
35 | class Saver {
36 | public:
37 | void addMesh(std::shared_ptr mesh);
38 | void addMeshes(std::vector> mesh);
39 | void save(const std::string &filename) const;
40 | void save(ofBuffer &buffer) const;
41 | private:
42 | std::vector> meshes_;
43 | };
44 | class Loader {
45 | public:
46 | std::vector> load(const std::string &filename) const;
47 | std::vector> load(const ofBuffer &buffer) const;
48 | std::vector> load(const char *data, std::size_t size) const;
49 | };
50 | }
51 |
52 | }}
53 | using ofxMeshWarpSave = ofx::MeshWarp::IO::Saver;
54 | using ofxMeshWarpLoad = ofx::MeshWarp::IO::Loader;
55 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # ofxMeshWarp
2 | Warping mesh points with mouse and keyboard.
3 | You can do it by code, of course.
4 |
5 | ## How to use
6 | ### code
7 | See example
8 |
9 | ### selecting points
10 | You can select/deselect point(s) by clicking on the point or making rectangle including the points.
11 | With shift key pressed, additive.
12 | With command key pressed, alternative.
13 |
14 | ### moving points
15 | You can move points' position by dragging on a selected point.
16 | With option key pressed, texcoord will be moved instead.
17 | With shift key pressed, points move according axis.
18 | You can also move by arrow keys.
19 |
20 | ### editing alpha
21 | You can edit points' alpha by scrolling Y-axis.
22 |
23 | ### switching nodal or not
24 | Each point has a property of nodal or not.
25 | By clicking on a point with option key pressed, you can switch it.
26 | If a point is nodal, you can control its position or texcoord directly.
27 | If a point is not nodal, you cannot but it will be controled by mood.
28 |
29 | ### dividing or reducing mesh points
30 | Click on a line to divide mesh.
31 | With option key pressed, reduce.
32 |
33 | _**warning**
34 | Dividing mesh allocates memory for new points but reducing doesn't free them.
35 | So if you call divide/reduce many times, you may need to call `ofxMeshWarp::gc()` on reasonable time._
36 |
37 |
38 | ## Other Features
39 | ### Save/Load
40 | See example
41 |
42 | ## Tested on
43 | - Mac OSX 10.13.6
44 | - oF 0.10.0
45 | - Xcode 9.4.1
46 |
47 | ## License
48 | MIT license.
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #########################
2 | # general
3 | #########################
4 |
5 | [Bb]uild/
6 | [Oo]bj/
7 | *.o
8 | examples/**/[Dd]ebug*/
9 | examples/**/[Rr]elease*/
10 | examples/**/gcc-debug/
11 | examples/**/gcc-release/
12 | tests/**/[Dd]ebug*/
13 | tests/**/[Rr]elease*/
14 | tests/**/gcc-debug/
15 | tests/**/gcc-release/
16 | *.mode*
17 | *.app/
18 | *.pyc
19 | .svn/
20 | *.log
21 | *.cpp.eep
22 | *.cpp.elf
23 | *.cpp.hex
24 |
25 | #########################
26 | # IDE
27 | #########################
28 |
29 | # XCode
30 | *.pbxuser
31 | *.perspective
32 | *.perspectivev3
33 | *.mode1v3
34 | *.mode2v3
35 | # XCode 4
36 | xcuserdata
37 | *.xcworkspace
38 |
39 | # Code::Blocks
40 | *.depend
41 | *.layout
42 |
43 | # Visual Studio
44 | *.sdf
45 | *.opensdf
46 | *.suo
47 | *.pdb
48 | *.ilk
49 | *.aps
50 | ipch/
51 |
52 | # Eclipse
53 | .metadata
54 | local.properties
55 | .externalToolBuilders
56 |
57 | # Android Studio
58 | .idea
59 | .gradle
60 | gradle
61 | gradlew
62 | gradlew.bat
63 |
64 | # QtCreator
65 | *.qbs.user
66 | *.pro.user
67 | *.pri
68 |
69 |
70 | #########################
71 | # operating system
72 | #########################
73 |
74 | # Linux
75 | *~
76 | # KDE
77 | .directory
78 | .AppleDouble
79 |
80 | # OSX
81 | .DS_Store
82 | *.swp
83 | *~.nib
84 | # Thumbnails
85 | ._*
86 |
87 | # Windows
88 | # Windows image file caches
89 | Thumbs.db
90 | # Folder config file
91 | Desktop.ini
92 |
93 | # Android
94 | .csettings
95 | /libs/openFrameworksCompiled/project/android/paths.make
96 |
97 | # Android Studio
98 | *.iml
99 |
100 | #########################
101 | # miscellaneous
102 | #########################
103 |
104 | .mailmap
105 |
--------------------------------------------------------------------------------
/example/src/ofApp.cpp:
--------------------------------------------------------------------------------
1 | #include "ofApp.h"
2 | #include "ofxMeshWarpIO.h"
3 | using namespace std;
4 |
5 | //--------------------------------------------------------------
6 | void ofApp::setup(){
7 | ofLoadImage(tex_, "of.png");
8 | mesh_ = make_shared();
9 | mesh_->setup(4,4,512,512);
10 | mesh_->setUVRect(ofRectangle(0, 0, tex_.getWidth(), tex_.getHeight()));
11 | controller_.add(mesh_);
12 | controller_.enable();
13 | }
14 |
15 | //--------------------------------------------------------------
16 | void ofApp::update(){
17 | ofSetWindowTitle(ofToString(ofGetFrameRate(),2));
18 | mesh_->update();
19 | }
20 |
21 | //--------------------------------------------------------------
22 | void ofApp::draw(){
23 | tex_.bind();
24 | // mesh_->drawMesh();
25 | controller_.drawFace();
26 | tex_.unbind();
27 | controller_.draw();
28 | }
29 |
30 | //--------------------------------------------------------------
31 | void ofApp::keyPressed(int key){
32 | switch(key) {
33 | case 's': {
34 | ofxMeshWarpSave saver;
35 | saver.addMesh(mesh_);
36 | saver.save("hoge.txt");
37 | } break;
38 | case 'l': {
39 | ofxMeshWarpLoad loader;
40 | vector> result = loader.load("hoge.txt");
41 | if(!result.empty()) {
42 | controller_.clear();
43 | mesh_ = result[0];
44 | controller_.add(mesh_);
45 | }
46 | } break;
47 | }
48 | }
49 |
50 | //--------------------------------------------------------------
51 | void ofApp::keyReleased(int key){
52 |
53 | }
54 |
55 | //--------------------------------------------------------------
56 | void ofApp::mouseMoved(int x, int y ){
57 |
58 | }
59 |
60 | //--------------------------------------------------------------
61 | void ofApp::mouseDragged(int x, int y, int button){
62 |
63 | }
64 |
65 | //--------------------------------------------------------------
66 | void ofApp::mousePressed(int x, int y, int button){
67 |
68 | }
69 |
70 | //--------------------------------------------------------------
71 | void ofApp::mouseReleased(int x, int y, int button){
72 |
73 | }
74 |
75 | //--------------------------------------------------------------
76 | void ofApp::mouseEntered(int x, int y){
77 |
78 | }
79 |
80 | //--------------------------------------------------------------
81 | void ofApp::mouseExited(int x, int y){
82 |
83 | }
84 |
85 | //--------------------------------------------------------------
86 | void ofApp::windowResized(int w, int h){
87 |
88 | }
89 |
90 | //--------------------------------------------------------------
91 | void ofApp::gotMessage(ofMessage msg){
92 |
93 | }
94 |
95 | //--------------------------------------------------------------
96 | void ofApp::dragEvent(ofDragInfo dragInfo){
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/src/ofxMeshWarpIO.cpp:
--------------------------------------------------------------------------------
1 | #include "ofxMeshWarpIO.h"
2 |
3 | using namespace ofx::MeshWarp;
4 | using namespace ofx::MeshWarp::IO;
5 | using namespace std;
6 |
7 | void PointHelper::get(ofBuffer &buffer) const
8 | {
9 | PointData data;
10 | data.point = target_->point();
11 | data.coord = target_->coord();
12 | data.normal = target_->normal();
13 | data.color = target_->color();
14 | data.is_node = target_->isNode();
15 | buffer.append((const char*)(&data), sizeof(PointData));
16 | }
17 | int PointHelper::set(const char *buffer)
18 | {
19 | PointData *data = (PointData*)buffer;
20 | target_->setPoint(data->point);
21 | target_->setCoord(data->coord);
22 | target_->setNormal(data->normal);
23 | target_->setColor(data->color);
24 | target_->setNodal(data->is_node);
25 | return sizeof(PointData);
26 | }
27 | void MeshHelper::get(ofBuffer &buffer) const
28 | {
29 | MeshData data;
30 | data.divx = target_->getDivX();
31 | data.divy = target_->getDivY();
32 | data.resolution = target_->getChildMeshResolution();
33 | ofRectangle uv = target_->getUVRect();
34 | data.uv_rect.set(uv.x, uv.y, uv.width, uv.height);
35 | buffer.append((const char*)(&data), sizeof(MeshData));
36 | auto points = target_->getPoints();
37 | for(auto &p : points) {
38 | PointHelper(p).get(buffer);
39 | }
40 | }
41 | int MeshHelper::set(const char *buffer)
42 | {
43 | int ret = 0;
44 | MeshData *data = (MeshData*)buffer;
45 | target_->setup(ofRectangle(0,0,1,1), data->divx, data->divy);
46 | target_->setUVRect(ofRectangle(data->uv_rect[0], data->uv_rect[1], data->uv_rect[2], data->uv_rect[3]));
47 | ret += sizeof(MeshData);
48 | auto points = target_->getPoints();
49 | for(auto &p : points) {
50 | ret += PointHelper(p).set(buffer+ret);
51 | }
52 | return ret;
53 | }
54 | void Saver::addMesh(shared_ptr mesh)
55 | {
56 | meshes_.push_back(mesh);
57 | }
58 | void Saver::addMeshes(vector> mesh)
59 | {
60 | meshes_.insert(end(meshes_), begin(mesh), end(mesh));
61 | }
62 | void Saver::save(const string &filename) const
63 | {
64 | ofBuffer buffer;
65 | save(buffer);
66 | ofBufferToFile(filename, buffer, true);
67 | }
68 | void Saver::save(ofBuffer &buffer) const
69 | {
70 | for(auto &mesh : meshes_) {
71 | MeshHelper(mesh.get()).get(buffer);
72 | }
73 | }
74 |
75 | vector> Loader::load(const string &filename) const
76 | {
77 | return load(ofBufferFromFile(filename, true));
78 | }
79 |
80 | vector> Loader::load(const ofBuffer &buffer) const
81 | {
82 | return load(buffer.getData(), buffer.size());
83 | }
84 |
85 | vector> Loader::load(const char *data, size_t size) const
86 | {
87 | vector> ret;
88 | const char *end = data+size;
89 | while(data < end) {
90 | auto mesh = make_shared();
91 | data += MeshHelper(mesh.get()).set(data);
92 | ret.push_back(mesh);
93 | }
94 | return ret;
95 | }
96 |
97 |
--------------------------------------------------------------------------------
/example/example.xcodeproj/xcshareddata/xcschemes/example Debug.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/example/example.xcodeproj/xcshareddata/xcschemes/example Release.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/src/utils/ofxMeshWarpManagedController.cpp:
--------------------------------------------------------------------------------
1 | #include "ofxMeshWarpManagedController.h"
2 | #include "ofGraphics.h"
3 |
4 | using namespace ofx::MeshWarp;
5 | using namespace ofx::MeshWarp::Editor;
6 | using namespace std;
7 |
8 | void ManagedController::clearOperation()
9 | {
10 | for_each(begin(controllers_), end(controllers_), [&](ControllerBase *t){t->clearOperation();});
11 | }
12 | void ManagedController::add(shared_ptr mesh)
13 | {
14 | ControllerBase::add(mesh);
15 | for_each(begin(controllers_), end(controllers_), [&](ControllerBase *t){t->add(mesh);});
16 | }
17 | void ManagedController::clear()
18 | {
19 | ControllerBase::clear();
20 | for_each(begin(controllers_), end(controllers_), [&](ControllerBase *t){t->clear();});
21 | }
22 | void ManagedController::drawCustom() const
23 | {
24 | if(is_mover_active_) {
25 | mover_.drawCustom();
26 | }
27 | if(is_divider_active_) {
28 | divider_.drawCustom();
29 | }
30 | }
31 |
32 | void ManagedController::setAnchorPoint(float x, float y)
33 | {
34 | ControllerBase::setAnchorPoint(x,y);
35 | for_each(begin(controllers_), end(controllers_), [&](ControllerBase *t){t->setAnchorPoint(x,y);});
36 | }
37 | void ManagedController::setTranslation(float x, float y)
38 | {
39 | ControllerBase::setTranslation(x,y);
40 | for_each(begin(controllers_), end(controllers_), [&](ControllerBase *t){t->setTranslation(x,y);});
41 | }
42 | void ManagedController::setScale(float s)
43 | {
44 | ControllerBase::setScale(s);
45 | for_each(begin(controllers_), end(controllers_), [&](ControllerBase *t){t->setScale(s);});
46 | }
47 |
48 | void ManagedController::activateMover()
49 | {
50 | is_mover_active_ = true;
51 | is_divider_active_ = false;
52 | divider_.clearOperation();
53 | }
54 | void ManagedController::activateDivider()
55 | {
56 | is_mover_active_ = false;
57 | is_divider_active_ = true;
58 | }
59 | void ManagedController::mousePressed(ofMouseEventArgs &args)
60 | {
61 | if(is_mover_active_) {
62 | mover_.mousePressed(args);
63 | }
64 | if(is_divider_active_) {
65 | divider_.mousePressed(args);
66 | }
67 | }
68 | void ManagedController::mouseReleased(ofMouseEventArgs &args)
69 | {
70 | mover_.mouseReleased(args);
71 | divider_.mouseReleased(args);
72 | if(mover_.isEditing()) {
73 | activateMover();
74 | }
75 | else {
76 | if(divider_.isEditing()) {
77 | activateDivider();
78 | }
79 | else {
80 | activateMover();
81 | }
82 | }
83 | }
84 | void ManagedController::mouseMoved(ofMouseEventArgs &args)
85 | {
86 | mover_.mouseMoved(args);
87 | if(mover_.isEditing()) {
88 | activateMover();
89 | }
90 | else {
91 | divider_.mouseMoved(args);
92 | if(divider_.isEditing()) {
93 | activateDivider();
94 | }
95 | else {
96 | activateMover();
97 | }
98 | }
99 | }
100 | void ManagedController::mouseDragged(ofMouseEventArgs &args)
101 | {
102 | if(is_mover_active_) {
103 | mover_.mouseDragged(args);
104 | }
105 | if(is_divider_active_) {
106 | divider_.mouseDragged(args);
107 | }
108 | }
109 | void ManagedController::mouseScrolled(ofMouseEventArgs &args)
110 | {
111 | if(is_mover_active_) {
112 | mover_.mouseScrolled(args);
113 | }
114 | if(is_divider_active_) {
115 | divider_.mouseScrolled(args);
116 | }
117 | }
118 | void ManagedController::mouseEntered(ofMouseEventArgs &args)
119 | {
120 | if(is_mover_active_) {
121 | mover_.mouseEntered(args);
122 | }
123 | if(is_divider_active_) {
124 | divider_.mouseEntered(args);
125 | }
126 | }
127 | void ManagedController::mouseExited(ofMouseEventArgs &args)
128 | {
129 | if(is_mover_active_) {
130 | mover_.mouseExited(args);
131 | }
132 | if(is_divider_active_) {
133 | divider_.mouseExited(args);
134 | }
135 | }
136 | void ManagedController::keyPressed(ofKeyEventArgs &args)
137 | {
138 | if(is_mover_active_) {
139 | mover_.keyPressed(args);
140 | }
141 | if(is_divider_active_) {
142 | divider_.keyPressed(args);
143 | }
144 | }
145 | void ManagedController::keyReleased(ofKeyEventArgs &args)
146 | {
147 | if(is_mover_active_) {
148 | mover_.keyReleased(args);
149 | }
150 | if(is_divider_active_) {
151 | divider_.keyReleased(args);
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/ofxMeshWarp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofConstants.h"
4 | #include "glm/vec2.hpp"
5 | #include "glm/vec3.hpp"
6 | #include "ofColor.h"
7 | #include "ofMesh.h"
8 | #include "ofRectangle.h"
9 |
10 | namespace ofx{namespace MeshWarp{
11 | class MeshPoint
12 | {
13 | public:
14 | static MeshPoint getLerped(const MeshPoint &a, const MeshPoint &b, float mix) {
15 | MeshPoint ret;
16 | ret.point_ = glm::mix(a.point_, b.point_, mix);
17 | ret.coord_ = glm::mix(a.coord_, b.coord_, mix);
18 | ret.normal_ = glm::mix(a.normal_, b.normal_, mix);
19 | ret.color_ = a.color_.getLerped(b.color_, mix);
20 | return ret;
21 | }
22 | const glm::vec3 &point() const { return point_; }
23 | const glm::vec2 &coord() const { return coord_; }
24 | const glm::vec3 &normal() const { return normal_; }
25 | const ofFloatColor &color() const { return color_; }
26 | float alpha() const { return color_.a; }
27 | bool isNode() const { return is_node_; }
28 | void setPoint(const glm::vec3 &point) { point_=point; }
29 | void setCoord(const glm::vec2 &coord) { coord_=coord; }
30 | void setNormal(const glm::vec3 &normal) { normal_=normal; }
31 | void setColor(const ofFloatColor &color) { color_=color; }
32 | void setAlpha(float alpha) { color_.a=alpha; }
33 | void setNodal(bool set) { is_node_=set; }
34 | void toggleNodal() { is_node_^=true; }
35 |
36 | private:
37 | glm::vec3 point_ = glm::vec3(0,0,0);
38 | glm::vec2 coord_ = glm::vec2(0,0);
39 | glm::vec3 normal_ = glm::vec3(0,0,1);
40 | ofFloatColor color_ = ofFloatColor::white;
41 | bool is_node_ = true;
42 | };
43 |
44 |
45 | class Mesh
46 | {
47 | public:
48 | void setup(const ofRectangle &rect, int div_x, int div_y);
49 | void setDirty() { dirty_ = true; }
50 | bool isDirty() const { return dirty_; }
51 | void update();
52 | OF_DEPRECATED_MSG("use setUVRect instead", void setTexCoordSize(float u, float v));
53 | void setUVRect(const ofRectangle &uv);
54 | void setChildMeshResolution(int resolution);
55 | void divideCol(int pos, float ratio);
56 | void divideRow(int pos, float ratio);
57 | void reduceCol(int pos);
58 | void reduceRow(int pos);
59 | void reset(const ofRectangle &rect);
60 | void drawMesh() const;
61 | void drawWireframe() const;
62 | void drawDetailedWireframe() const;
63 | std::vector getPoints();
64 | const ofMesh& getOfMesh() const { return of_mesh_; }
65 | int getDivX() const { return div_x_; }
66 | int getDivY() const { return div_y_; }
67 | const ofRectangle& getUVRect() const { return uv_rect_; }
68 | int getChildMeshResolution() const { return child_mesh_resolution_; }
69 | void gc();
70 | void setEnablePointInterpolation(bool set) { interpolate_flags_.point=set; }
71 | void setEnableCoordInterpolation(bool set) { interpolate_flags_.coord=set; }
72 | void setEnableNormalInterpolation(bool set) { interpolate_flags_.normal=set; }
73 | void setEnableColorInterpolation(bool set) { interpolate_flags_.color=set; }
74 | bool isEnabledPointInterpolation() const { return interpolate_flags_.point; }
75 | bool isEnabledCoordInterpolation() const { return interpolate_flags_.coord; }
76 | bool isEnabledNormalInterpolation() const { return interpolate_flags_.normal; }
77 | bool isEnabledColorInterpolation() const { return interpolate_flags_.color; }
78 | private:
79 | int div_x_, div_y_;
80 | ofRectangle uv_rect_ = ofRectangle(0,0,1,1);
81 | std::vector indices_;
82 | std::vector mesh_;
83 | ofMesh of_mesh_;
84 | ofIndexType getIndex(int x, int y) const { return indices_[y*div_x_+x]; }
85 | int child_mesh_resolution_ = 8;
86 | void drawChildMesh() const;
87 | Mesh makeChildMesh(int x, int y, int resolution) const;
88 | struct {
89 | bool point=true, coord=true, normal=true, color=true;
90 | } interpolate_flags_;
91 | bool isEnabledAnyInterpolation() const {
92 | return interpolate_flags_.point
93 | || interpolate_flags_.coord
94 | || interpolate_flags_.normal
95 | || interpolate_flags_.color;
96 | }
97 | std::vector> child_meshes_;
98 | bool dirty_=true;
99 | void solve();
100 | void refreshChildMeshes();
101 | };
102 | }}
103 | using ofxMeshWarp = ofx::MeshWarp::Mesh;
104 | using ofxMeshWarpPoint = ofx::MeshWarp::MeshPoint;
105 |
--------------------------------------------------------------------------------
/example/config.make:
--------------------------------------------------------------------------------
1 | ################################################################################
2 | # CONFIGURE PROJECT MAKEFILE (optional)
3 | # This file is where we make project specific configurations.
4 | ################################################################################
5 |
6 | ################################################################################
7 | # OF ROOT
8 | # The location of your root openFrameworks installation
9 | # (default) OF_ROOT = ../../..
10 | ################################################################################
11 | # OF_ROOT = ../../..
12 |
13 | ################################################################################
14 | # PROJECT ROOT
15 | # The location of the project - a starting place for searching for files
16 | # (default) PROJECT_ROOT = . (this directory)
17 | #
18 | ################################################################################
19 | # PROJECT_ROOT = .
20 |
21 | ################################################################################
22 | # PROJECT SPECIFIC CHECKS
23 | # This is a project defined section to create internal makefile flags to
24 | # conditionally enable or disable the addition of various features within
25 | # this makefile. For instance, if you want to make changes based on whether
26 | # GTK is installed, one might test that here and create a variable to check.
27 | ################################################################################
28 | # None
29 |
30 | ################################################################################
31 | # PROJECT EXTERNAL SOURCE PATHS
32 | # These are fully qualified paths that are not within the PROJECT_ROOT folder.
33 | # Like source folders in the PROJECT_ROOT, these paths are subject to
34 | # exlclusion via the PROJECT_EXLCUSIONS list.
35 | #
36 | # (default) PROJECT_EXTERNAL_SOURCE_PATHS = (blank)
37 | #
38 | # Note: Leave a leading space when adding list items with the += operator
39 | ################################################################################
40 | # PROJECT_EXTERNAL_SOURCE_PATHS =
41 |
42 | ################################################################################
43 | # PROJECT EXCLUSIONS
44 | # These makefiles assume that all folders in your current project directory
45 | # and any listed in the PROJECT_EXTERNAL_SOURCH_PATHS are are valid locations
46 | # to look for source code. The any folders or files that match any of the
47 | # items in the PROJECT_EXCLUSIONS list below will be ignored.
48 | #
49 | # Each item in the PROJECT_EXCLUSIONS list will be treated as a complete
50 | # string unless teh user adds a wildcard (%) operator to match subdirectories.
51 | # GNU make only allows one wildcard for matching. The second wildcard (%) is
52 | # treated literally.
53 | #
54 | # (default) PROJECT_EXCLUSIONS = (blank)
55 | #
56 | # Will automatically exclude the following:
57 | #
58 | # $(PROJECT_ROOT)/bin%
59 | # $(PROJECT_ROOT)/obj%
60 | # $(PROJECT_ROOT)/%.xcodeproj
61 | #
62 | # Note: Leave a leading space when adding list items with the += operator
63 | ################################################################################
64 | # PROJECT_EXCLUSIONS =
65 |
66 | ################################################################################
67 | # PROJECT LINKER FLAGS
68 | # These flags will be sent to the linker when compiling the executable.
69 | #
70 | # (default) PROJECT_LDFLAGS = -Wl,-rpath=./libs
71 | #
72 | # Note: Leave a leading space when adding list items with the += operator
73 | ################################################################################
74 |
75 | # Currently, shared libraries that are needed are copied to the
76 | # $(PROJECT_ROOT)/bin/libs directory. The following LDFLAGS tell the linker to
77 | # add a runtime path to search for those shared libraries, since they aren't
78 | # incorporated directly into the final executable application binary.
79 | # TODO: should this be a default setting?
80 | # PROJECT_LDFLAGS=-Wl,-rpath=./libs
81 |
82 | ################################################################################
83 | # PROJECT DEFINES
84 | # Create a space-delimited list of DEFINES. The list will be converted into
85 | # CFLAGS with the "-D" flag later in the makefile.
86 | #
87 | # (default) PROJECT_DEFINES = (blank)
88 | #
89 | # Note: Leave a leading space when adding list items with the += operator
90 | ################################################################################
91 | # PROJECT_DEFINES =
92 |
93 | ################################################################################
94 | # PROJECT CFLAGS
95 | # This is a list of fully qualified CFLAGS required when compiling for this
96 | # project. These CFLAGS will be used IN ADDITION TO the PLATFORM_CFLAGS
97 | # defined in your platform specific core configuration files. These flags are
98 | # presented to the compiler BEFORE the PROJECT_OPTIMIZATION_CFLAGS below.
99 | #
100 | # (default) PROJECT_CFLAGS = (blank)
101 | #
102 | # Note: Before adding PROJECT_CFLAGS, note that the PLATFORM_CFLAGS defined in
103 | # your platform specific configuration file will be applied by default and
104 | # further flags here may not be needed.
105 | #
106 | # Note: Leave a leading space when adding list items with the += operator
107 | ################################################################################
108 | # PROJECT_CFLAGS =
109 |
110 | ################################################################################
111 | # PROJECT OPTIMIZATION CFLAGS
112 | # These are lists of CFLAGS that are target-specific. While any flags could
113 | # be conditionally added, they are usually limited to optimization flags.
114 | # These flags are added BEFORE the PROJECT_CFLAGS.
115 | #
116 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE flags are only applied to RELEASE targets.
117 | #
118 | # (default) PROJECT_OPTIMIZATION_CFLAGS_RELEASE = (blank)
119 | #
120 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG flags are only applied to DEBUG targets.
121 | #
122 | # (default) PROJECT_OPTIMIZATION_CFLAGS_DEBUG = (blank)
123 | #
124 | # Note: Before adding PROJECT_OPTIMIZATION_CFLAGS, please note that the
125 | # PLATFORM_OPTIMIZATION_CFLAGS defined in your platform specific configuration
126 | # file will be applied by default and further optimization flags here may not
127 | # be needed.
128 | #
129 | # Note: Leave a leading space when adding list items with the += operator
130 | ################################################################################
131 | # PROJECT_OPTIMIZATION_CFLAGS_RELEASE =
132 | # PROJECT_OPTIMIZATION_CFLAGS_DEBUG =
133 |
134 | ################################################################################
135 | # PROJECT COMPILERS
136 | # Custom compilers can be set for CC and CXX
137 | # (default) PROJECT_CXX = (blank)
138 | # (default) PROJECT_CC = (blank)
139 | # Note: Leave a leading space when adding list items with the += operator
140 | ################################################################################
141 | # PROJECT_CXX =
142 | # PROJECT_CC =
143 |
--------------------------------------------------------------------------------
/src/ofxMeshWarpController.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "ofEvents.h"
4 | #include "ofxMeshWarp.h"
5 | #include "ofRectangle.h"
6 | #include "ofPolyline.h"
7 |
8 | namespace ofx{namespace MeshWarp{
9 | namespace Editor {
10 | class PointHelper : public std::pair {
11 | public:
12 | PointHelper(MeshPoint *p):pair(p,*p){}
13 | void setVertex(const glm::vec2 &point) { first->setPoint(glm::vec3(point,0)); }
14 | void setVertexMove(const glm::vec2 &move) { first->setPoint(second.point()+move); }
15 | void moveVertex(const glm::vec2 &move) { first->setPoint(first->point()+move); }
16 | void resetVertex() { first->setPoint(second.point()); }
17 | void setCoord(const glm::vec2 &point) { first->setCoord(point); }
18 | void setCoordMove(const glm::vec2 &move) { first->setCoord(second.coord()+move); }
19 | void moveCoord(const glm::vec2 &move) { first->setCoord(first->coord()+move); }
20 | void resetCoord() { first->setCoord(second.coord()); }
21 | void setColor(const ofFloatColor &color) { first->setColor(color); }
22 | void resetColor() { first->setColor(second.color()); }
23 | void setAlpha(float alpha) { first->setAlpha(alpha); }
24 | void addAlpha(float alpha) { first->setAlpha(first->alpha()+alpha); }
25 | void resetAlpha() { first->setAlpha(second.alpha()); }
26 | };
27 | class MeshHelper
28 | {
29 | public:
30 | MeshHelper(Mesh *m):target_(m){}
31 | MeshPoint* getHit(const glm::vec2 &test, float room, int index=0) const;
32 | std::vector getHit(const ofRectangle &test) const;
33 | std::vector getBox(int top_left_index) const;
34 | std::vector getBoxIndices(int top_left_index) const;
35 | bool isHitBox(const glm::vec2 &test, int top_left_index) const;
36 | bool isHitLine(const glm::vec2 &test, int index0, int index1, float room, float &pos) const;
37 | std::vector getColPoints(int point_index) const;
38 | std::vector getRowPoints(int point_index) const;
39 | private:
40 | Mesh *target_;
41 | };
42 |
43 | class ControllerBase {
44 | public:
45 | ControllerBase();
46 | virtual ~ControllerBase();
47 | void add(std::shared_ptr target);
48 | void enable();
49 | void disable();
50 | void setEnable(bool set) { set?enable():disable(); }
51 | bool isEnabled() const { return is_enabled_; }
52 | void clear();
53 | void draw() const;
54 | void drawFace() const;
55 |
56 | void setAnchorPoint(float x, float y) { setAnchorPoint(glm::vec2(x,y)); }
57 | void setAnchorPoint(const glm::vec2 &point) { anchor_point_ = point; }
58 | void setTranslation(float x, float y) { setTranslation(glm::vec2(x,y)); }
59 | void setTranslation(const glm::vec2 &point) { translation_ = point; }
60 | void setScale(float s) { assert(s>0); scale_ = s; }
61 |
62 | virtual bool isEditing() const { return false; }
63 |
64 | virtual void clearOperation(){};
65 |
66 | virtual void mousePressed(ofMouseEventArgs &args){}
67 | virtual void mouseReleased(ofMouseEventArgs &args){}
68 | virtual void mouseMoved(ofMouseEventArgs &args){}
69 | virtual void mouseDragged(ofMouseEventArgs &args){}
70 | virtual void mouseScrolled(ofMouseEventArgs &args){}
71 | virtual void mouseEntered(ofMouseEventArgs &args){}
72 | virtual void mouseExited(ofMouseEventArgs &args){}
73 | virtual void keyPressed(ofKeyEventArgs &args){}
74 | virtual void keyReleased(ofKeyEventArgs &args){}
75 | protected:
76 | std::set> meshes_;
77 | bool is_enabled_ = false;
78 | virtual void drawCustom() const{};
79 |
80 | glm::vec2 anchor_point_=glm::vec2(0,0);
81 | glm::vec2 translation_=glm::vec2(0,0);
82 | float scale_=1;
83 | glm::vec2 screenToLocal(glm::vec2 src) const { return (src-translation_)/scale_+anchor_point_; }
84 | glm::vec2 localToScreen(glm::vec2 src) const { return (src-anchor_point_)*scale_+translation_; }
85 | };
86 |
87 | class PointController : public ControllerBase
88 | {
89 | public:
90 | void clearOperation();
91 | void drawCustom() const;
92 | bool isEditing() const;
93 |
94 | void setUVResolution(const glm::vec2 &res) { screen_to_coord_ = res; }
95 |
96 | virtual void mousePressed(ofMouseEventArgs &args);
97 | virtual void mouseReleased(ofMouseEventArgs &args);
98 | virtual void mouseMoved(ofMouseEventArgs &args);
99 | virtual void mouseDragged(ofMouseEventArgs &args);
100 | virtual void mouseScrolled(ofMouseEventArgs &args);
101 | virtual void mouseEntered(ofMouseEventArgs &args);
102 | virtual void mouseExited(ofMouseEventArgs &args);
103 | virtual void keyPressed(ofKeyEventArgs &args);
104 | virtual void keyReleased(ofKeyEventArgs &args);
105 | protected:
106 | struct MouseOperation {
107 | MeshPoint *hover = nullptr;
108 | std::vector inside_rect;
109 | glm::vec2 pressed_pos, pos;
110 | std::vector edit;
111 | enum {
112 | STATE_NONE,
113 | STATE_GRABBING,
114 | STATE_MAKING_RECT,
115 | } pressed_state = STATE_NONE;
116 | } mouse_op_;
117 | std::set selected_;
118 | float point_size_ = 10;
119 | glm::vec2 screen_to_coord_=glm::vec2(1024.f,1024.f);
120 | float scroll_to_alpha_ = -1/100.f;
121 |
122 | bool isGrabbing() const { return mouse_op_.pressed_state==MouseOperation::STATE_GRABBING; }
123 | bool isMakingRect() const { return mouse_op_.pressed_state==MouseOperation::STATE_MAKING_RECT; }
124 | virtual bool isToggleNode() const { return ofGetKeyPressed(OF_KEY_ALT); }
125 | virtual bool isSlide() const { return ofGetKeyPressed(OF_KEY_SHIFT); }
126 | virtual bool isAdditive() const { return ofGetKeyPressed(OF_KEY_SHIFT); }
127 | virtual bool isAlternative() const { return ofGetKeyPressed(OF_KEY_COMMAND); }
128 | virtual bool isArrowKeyJump() const { return ofGetKeyPressed(OF_KEY_SHIFT); }
129 | virtual bool isEditCoord() const { return ofGetKeyPressed(OF_KEY_ALT); }
130 | virtual bool isEditVertex() const { return !ofGetKeyPressed(OF_KEY_ALT); }
131 |
132 | MeshPoint* getHit(const glm::vec2 &test) const;
133 | };
134 | class DivideController : public ControllerBase
135 | {
136 | public:
137 | void clearOperation();
138 | void drawCustom() const;
139 | bool isEditing() const;
140 |
141 | virtual void mousePressed(ofMouseEventArgs &args);
142 | virtual void mouseReleased(ofMouseEventArgs &args);
143 | virtual void mouseMoved(ofMouseEventArgs &args);
144 | virtual void mouseDragged(ofMouseEventArgs &args);
145 | virtual void mouseScrolled(ofMouseEventArgs &args);
146 | virtual void mouseEntered(ofMouseEventArgs &args);
147 | virtual void mouseExited(ofMouseEventArgs &args);
148 | virtual void keyPressed(ofKeyEventArgs &args);
149 | virtual void keyReleased(ofKeyEventArgs &args);
150 | protected:
151 | float line_hit_size_ = 10;
152 | struct HitInfo {
153 | Mesh *mesh = nullptr;
154 | int area_index = -1;
155 | int line_index_0 = -1, line_index_1 = -1;
156 | float pos_intersection = -1;
157 | bool isArea() const { return area_index; }
158 | bool isLine() const { return line_index_0 != -1 && line_index_1 != -1; }
159 | bool isLineX() const { return isLine() && abs(line_index_0-line_index_1)==1; }
160 | bool isLineY() const { return isLine() && !isLineX(); }
161 | } hit_info_;
162 |
163 | virtual bool isDivide() const { return !ofGetKeyPressed(OF_KEY_ALT); }
164 | virtual bool isReduce() const { return ofGetKeyPressed(OF_KEY_ALT); }
165 | HitInfo getHitInfo(const glm::vec2 &test) const;
166 | };
167 | }
168 | }}
169 | using ofxMeshWarpControllerBase = ofx::MeshWarp::Editor::ControllerBase;
170 | using ofxMeshWarpPointController = ofx::MeshWarp::Editor::PointController;
171 | using ofxMeshWarpMeshDivider = ofx::MeshWarp::Editor::DivideController;
172 |
--------------------------------------------------------------------------------
/src/ofxMeshWarp.cpp:
--------------------------------------------------------------------------------
1 | #include "ofxMeshWarp.h"
2 | #include "ofTexture.h"
3 | #include
4 |
5 | using namespace ofx::MeshWarp;
6 | using namespace std;
7 |
8 | void Mesh::setup(const ofRectangle &rect, int div_x, int div_y)
9 | {
10 | if(div_x < 1 || div_y < 1) {
11 | ofLogError(__FILE__, "div_x and div_y must be bigger than 1");
12 | return;
13 | }
14 | div_x_ = div_x;
15 | div_y_ = div_y;
16 | reset(rect);
17 | of_mesh_.setMode(OF_PRIMITIVE_TRIANGLES);
18 | }
19 | void Mesh::update()
20 | {
21 | if(dirty_) {
22 | solve();
23 | }
24 | }
25 | void Mesh::setTexCoordSize(float u, float v)
26 | {
27 | setUVRect(ofRectangle(0,0,u,v));
28 | }
29 | void Mesh::setUVRect(const ofRectangle &rect)
30 | {
31 | uv_rect_ = rect;
32 | setDirty();
33 | }
34 | void Mesh::setChildMeshResolution(int resolution)
35 | {
36 | child_mesh_resolution_ = resolution;
37 | setDirty();
38 | }
39 | void Mesh::divideCol(int pos, float ratio)
40 | {
41 | if(pos < 0 || div_x_-1 <= pos) {
42 | ofLogError(__FILE__, "index out of bounds: %d", pos);
43 | return;
44 | }
45 | auto indices = indices_;
46 | auto it = begin(indices)+pos+1;
47 | for(int y = 0; y < div_y_; ++y) {
48 | MeshPoint &a = mesh_[getIndex(pos,y)];
49 | MeshPoint &b = mesh_[getIndex(pos+1,y)];
50 | MeshPoint point = MeshPoint(MeshPoint::getLerped(a, b, ratio));
51 | it = indices.insert(it, mesh_.size());
52 | mesh_.push_back(point);
53 | if(y < div_y_-1) {
54 | it += div_x_+1;
55 | }
56 | }
57 | indices_ = indices;
58 | ++div_x_;
59 | setDirty();
60 | }
61 | void Mesh::divideRow(int pos, float ratio)
62 | {
63 | if(pos < 0 || div_y_-1 <= pos) {
64 | ofLogError(__FILE__, "index out of bounds: %d", pos);
65 | return;
66 | }
67 | auto indices = indices_;
68 | auto it = begin(indices)+(pos+1)*div_x_;
69 | for(int x = 0; x < div_x_; ++x) {
70 | MeshPoint &a = mesh_[getIndex(x,pos)];
71 | MeshPoint &b = mesh_[getIndex(x,pos+1)];
72 | MeshPoint point = MeshPoint(MeshPoint::getLerped(a, b, ratio));
73 | it = indices.insert(it, (ofIndexType)mesh_.size())+1;
74 | mesh_.push_back(point);
75 | }
76 | indices_ = indices;
77 | ++div_y_;
78 | setDirty();
79 | }
80 | void Mesh::reduceCol(int pos)
81 | {
82 | if(div_x_ <= 2) {
83 | ofLogError(__FILE__, "cannot reduce col anymore.");
84 | return;
85 | }
86 | if(pos < 0 || div_x_ <= pos) {
87 | ofLogError(__FILE__, "index out of bounds: %d", pos);
88 | return;
89 | }
90 | for(int i = div_y_; --i >= 0;) {
91 | int index = i*div_x_+pos;
92 | indices_.erase(begin(indices_)+index);
93 | }
94 | --div_x_;
95 | setDirty();
96 | }
97 | void Mesh::reduceRow(int pos)
98 | {
99 | if(div_y_ <= 2) {
100 | ofLogError(__FILE__, "cannot reduce row anymore.");
101 | return;
102 | }
103 | if(pos < 0 || div_y_ <= pos) {
104 | ofLogError(__FILE__, "index out of bounds: %d", pos);
105 | return;
106 | }
107 | auto from = begin(indices_)+pos*div_x_;
108 | auto to = from+div_x_;
109 | indices_.erase(from, to);
110 | --div_y_;
111 | setDirty();
112 | }
113 | void Mesh::reset(const ofRectangle &rect)
114 | {
115 | int num = div_x_*div_y_;
116 | mesh_.resize(num);
117 | for(int i = 0; i < num; ++i) {
118 | MeshPoint &point = mesh_[i];
119 | glm::vec2 coord = glm::vec2(i%div_x_,i/div_x_)/glm::vec2(div_x_-1,div_y_-1);
120 | point.setCoord(coord);
121 | point.setPoint(rect.position + glm::vec3(coord*glm::vec2(rect.getWidth(),rect.getHeight()), 0));
122 | }
123 | indices_.resize(num);
124 | iota(begin(indices_), end(indices_), 0);
125 | setDirty();
126 | }
127 | void Mesh::solve()
128 | {
129 | if(!isEnabledAnyInterpolation()) {
130 | return;
131 | }
132 | auto solveFlameX = [&](int y) {
133 | vector work;
134 | work.clear();
135 | work.push_back(&mesh_[getIndex(0,y)]);
136 | for(int x = 1; x < div_x_; ++x) {
137 | MeshPoint *p1 = &mesh_[getIndex(x,y)];
138 | if(p1->isNode() || x == div_x_-1) {
139 | if(work.size() > 1) {
140 | MeshPoint *p0 = work[0];
141 | for(size_t w = 1, num = work.size(); w < num; ++w) {
142 | MeshPoint lerped = MeshPoint::getLerped(*p0, *p1, w/(float)num);
143 | if(isEnabledPointInterpolation()) work[w]->setPoint(lerped.point());
144 | if(isEnabledCoordInterpolation()) work[w]->setCoord(lerped.coord());
145 | if(isEnabledNormalInterpolation()) work[w]->setNormal(lerped.normal());
146 | if(isEnabledColorInterpolation()) work[w]->setColor(lerped.color());
147 | }
148 | }
149 | work.clear();
150 | }
151 | work.push_back(p1);
152 | }
153 | };
154 | auto solveFlameY = [&](int x) {
155 | vector work;
156 | work.clear();
157 | work.push_back(&mesh_[getIndex(x,0)]);
158 | for(int y = 1; y < div_y_; ++y) {
159 | MeshPoint *p1 = &mesh_[getIndex(x,y)];
160 | if(p1->isNode() || y == div_y_-1) {
161 | if(work.size() > 1) {
162 | MeshPoint *p0 = work[0];
163 | for(size_t w = 1, num = work.size(); w < num; ++w) {
164 | MeshPoint lerped = MeshPoint::getLerped(*p0, *p1, w/(float)num);
165 | if(isEnabledPointInterpolation()) work[w]->setPoint(lerped.point());
166 | if(isEnabledCoordInterpolation()) work[w]->setCoord(lerped.coord());
167 | if(isEnabledNormalInterpolation()) work[w]->setNormal(lerped.normal());
168 | if(isEnabledColorInterpolation()) work[w]->setColor(lerped.color());
169 | }
170 | }
171 | work.clear();
172 | }
173 | work.push_back(p1);
174 | }
175 | };
176 | auto solveInternal = [&](int x, int y) {
177 | assert(0 < x && x < div_x_-1 && 0 < y && y < div_y_-1);
178 | auto getDistanceToNode = [&](int x, int y, int diff_x, int diff_y) mutable ->pair {
179 | int ret = 0;
180 | while(0 < x && x < div_x_-1 && 0 < y && y < div_y_-1) {
181 | x += diff_x; y += diff_y;
182 | ++ret;
183 | if(mesh_[getIndex(x,y)].isNode()) break;
184 | }
185 | assert(ret>0);
186 | return make_pair(&mesh_[getIndex(x,y)],ret);
187 | };
188 | map around{
189 | getDistanceToNode(x,y, -1,-1),
190 | getDistanceToNode(x,y, -1, 0),
191 | getDistanceToNode(x,y, -1, 1),
192 | getDistanceToNode(x,y, 1,-1),
193 | getDistanceToNode(x,y, 1, 0),
194 | getDistanceToNode(x,y, 1,+1),
195 | getDistanceToNode(x,y, 0,-1),
196 | getDistanceToNode(x,y, 0,+1),
197 | };
198 | float inv_sum = [&around]()->float{float ret=0;for(auto &p:around)ret+=1/(float)p.second;return ret;}();
199 | auto ratio = [&around,inv_sum](int self)->float {
200 | return ofMap(1/(float)self, 0, inv_sum, 0, 1, false);
201 | };
202 | MeshPoint &dst = mesh_[getIndex(x,y)];
203 | if(isEnabledPointInterpolation()) {
204 | glm::vec3 point = [&around,&ratio](){glm::vec3 ret;for(auto &p:around)ret+=p.first->point()*ratio(p.second);return ret;}();
205 | dst.setPoint(point);
206 | }
207 | if(isEnabledCoordInterpolation()) {
208 | glm::vec2 coord = [&around,&ratio](){glm::vec2 ret;for(auto &p:around)ret+=p.first->coord()*ratio(p.second);return ret;}();
209 | dst.setCoord(coord);
210 | }
211 | if(isEnabledNormalInterpolation()) {
212 | glm::vec3 normal = [&around,&ratio](){glm::vec3 ret;for(auto &p:around)ret+=p.first->normal()*ratio(p.second);return ret;}();
213 | dst.setNormal(normal);
214 | }
215 | if(isEnabledColorInterpolation()) {
216 | ofVec4f color = [&around,&ratio]() {
217 | ofVec4f ret;
218 | for(auto &p:around) {
219 | auto color = p.first->color();
220 | ret += ofVec4f(color[0], color[1], color[2], color[3])*ratio(p.second);
221 | }
222 | return ret;
223 | }();
224 | dst.setColor(ofFloatColor(color[0],color[1],color[2],color[3]));
225 | }
226 | };
227 | solveFlameX(0);
228 | solveFlameX(div_y_-1);
229 | solveFlameY(0);
230 | solveFlameY(div_x_-1);
231 | for(int y = 1; y < div_y_-1; ++y) {
232 | for(int x = 1; x < div_x_-1; ++x) {
233 | if(!mesh_[getIndex(x,y)].isNode()) {
234 | solveInternal(x,y);
235 | }
236 | }
237 | }
238 | if(child_mesh_resolution_ > 1) {
239 | refreshChildMeshes();
240 | }
241 |
242 | of_mesh_.clear();
243 | for(auto &p :mesh_) {
244 | glm::vec2 coord = p.coord();
245 | coord.x =ofMap(coord.x, 0, 1, uv_rect_.getLeft(), uv_rect_.getRight());
246 | coord.y =ofMap(coord.y, 0, 1, uv_rect_.getTop(), uv_rect_.getBottom());
247 | of_mesh_.addTexCoord(coord);
248 | of_mesh_.addColor(p.color());
249 | of_mesh_.addNormal(p.normal());
250 | of_mesh_.addVertex(p.point());
251 | }
252 | for(int y = 0; y < div_y_-1; ++y) {
253 | for(int x = 0; x < div_x_-1; ++x) {
254 | of_mesh_.addIndex(getIndex(x ,y ));
255 | of_mesh_.addIndex(getIndex(x ,y+1));
256 | of_mesh_.addIndex(getIndex(x+1,y ));
257 | of_mesh_.addIndex(getIndex(x+1,y ));
258 | of_mesh_.addIndex(getIndex(x ,y+1));
259 | of_mesh_.addIndex(getIndex(x+1,y+1));
260 | }
261 | }
262 |
263 | dirty_ = false;
264 | }
265 |
266 | void Mesh::gc()
267 | {
268 | if(mesh_.size() == indices_.size()) {
269 | ofLogNotice(__FILE__, "no need for gc-ing");
270 | return;
271 | }
272 | vector neu;
273 | for(auto &i : indices_) {
274 | neu.push_back(mesh_[i]);
275 | }
276 | neu.swap(mesh_);
277 | iota(begin(indices_), end(indices_), 0);
278 | dirty_ = true;
279 | }
280 |
281 | vector Mesh::getPoints()
282 | {
283 | vector ret;
284 | for(int y = 0; y < div_y_; ++y) {
285 | for(int x = 0; x < div_x_; ++x) {
286 | ret.push_back(&mesh_[getIndex(x,y)]);
287 | }
288 | }
289 | return ret;
290 | }
291 |
292 | void Mesh::drawMesh() const
293 | {
294 | if(child_mesh_resolution_ > 1) {
295 | drawChildMesh();
296 | }
297 | else {
298 | of_mesh_.draw();
299 | }
300 | }
301 |
302 | Mesh Mesh::makeChildMesh(int x, int y, int resolution) const
303 | {
304 | Mesh mesh;
305 | mesh.setChildMeshResolution(1);
306 | mesh.setUVRect(uv_rect_);
307 | mesh.setup(ofRectangle(0,0,1,1), resolution, resolution);
308 | auto isCorner = [resolution](int x, int y) {
309 | return (x==0||x==resolution-1)&&(y==0||y==resolution-1);
310 | };
311 | #ifndef OFXMESHWARP_USE_OLD_CHILDMESH
312 | const MeshPoint *quad[2][2] = {
313 | {&mesh_[getIndex(x,y)], &mesh_[getIndex(x,y+1)]},
314 | {&mesh_[getIndex(x+1,y)], &mesh_[getIndex(x+1,y+1)]}
315 | };
316 | for(int iy = 0; iy < resolution; ++iy) {
317 | float ry = iy/(float)(resolution-1);
318 | MeshPoint cp[2] = {MeshPoint::getLerped(*quad[0][0], *quad[0][1], ry), MeshPoint::getLerped(*quad[1][0], *quad[1][1], ry)};
319 | for(int ix = 0; ix < resolution; ++ix) {
320 | float rx = ix/(float)(resolution-1);
321 | mesh.mesh_[mesh.getIndex(ix,iy)] = MeshPoint::getLerped(cp[0], cp[1], rx);
322 | }
323 | }
324 | mesh.update();
325 | #else
326 | mesh.mesh_[mesh.getIndex(0,0)] = mesh_[getIndex(x,y)];
327 | mesh.mesh_[mesh.getIndex(resolution-1,0)] = mesh_[getIndex(x+1,y)];
328 | mesh.mesh_[mesh.getIndex(0,resolution-1)] = mesh_[getIndex(x,y+1)];
329 | mesh.mesh_[mesh.getIndex(resolution-1,resolution-1)] = mesh_[getIndex(x+1,y+1)];
330 | for(int iy = 0; iy < resolution; ++iy) {
331 | for(int ix = 0; ix < resolution; ++ix) {
332 | mesh.mesh_[mesh.getIndex(ix,iy)].setNodal(isCorner(ix,iy));
333 | }
334 | }
335 | mesh.solve();
336 | #endif
337 | return mesh;
338 | }
339 | void Mesh::drawChildMesh() const
340 | {
341 | if(child_mesh_resolution_ < 2) {
342 | ofLogWarning(__FILE__, "child mesh resolution should be more than 2: %d", child_mesh_resolution_);
343 | return;
344 | }
345 | for(int x = 0; x < div_x_-1; ++x) {
346 | for(int y = 0; y < div_y_-1; ++y) {
347 | child_meshes_[x][y].drawMesh();
348 | }
349 | }
350 | }
351 | void Mesh::drawWireframe() const
352 | {
353 | for(int y = 0; y < div_y_; ++y) {
354 | ofMesh mesh;
355 | mesh.setMode(OF_PRIMITIVE_LINE_STRIP);
356 | for(int x = 0; x < div_x_; ++x) {
357 | mesh.addVertex(mesh_[getIndex(x,y)].point());
358 | }
359 | mesh.draw();
360 | }
361 | for(int x = 0; x < div_x_; ++x) {
362 | ofMesh mesh;
363 | mesh.setMode(OF_PRIMITIVE_LINE_STRIP);
364 | for(int y = 0; y < div_y_; ++y) {
365 | mesh.addVertex(mesh_[getIndex(x,y)].point());
366 | }
367 | mesh.draw();
368 | }
369 | }
370 | void Mesh::drawDetailedWireframe() const
371 | {
372 | if(child_mesh_resolution_ > 1) {
373 | for(int x = 0; x < div_x_-1; ++x) {
374 | for(int y = 0; y < div_y_-1; ++y) {
375 | child_meshes_[x][y].drawWireframe();
376 | }
377 | }
378 | }
379 | else {
380 | drawWireframe();
381 | }
382 | }
383 |
384 | void Mesh::refreshChildMeshes()
385 | {
386 | child_meshes_.resize(div_x_-1);
387 | for(int x = 0; x < div_x_-1; ++x) {
388 | child_meshes_[x].resize(div_y_-1);
389 | for(int y = 0; y < div_y_-1; ++y) {
390 | child_meshes_[x][y] = makeChildMesh(x, y, child_mesh_resolution_);
391 | }
392 | }
393 | }
394 |
395 |
--------------------------------------------------------------------------------
/src/ofxMeshWarpController.cpp:
--------------------------------------------------------------------------------
1 | #include "ofxMeshWarpController.h"
2 | #include "ofGraphics.h"
3 | #include "glm/vec3.hpp"
4 |
5 | using namespace ofx::MeshWarp;
6 | using namespace ofx::MeshWarp::Editor;
7 | using namespace std;
8 |
9 | ControllerBase::ControllerBase()
10 | {
11 | // enable();
12 | }
13 | ControllerBase::~ControllerBase()
14 | {
15 | disable();
16 | }
17 | void ControllerBase::enable()
18 | {
19 | if(!is_enabled_) {
20 | ofRegisterMouseEvents(this);
21 | ofRegisterKeyEvents(this);
22 | is_enabled_ = true;
23 | }
24 | }
25 | void ControllerBase::disable()
26 | {
27 | if(is_enabled_) {
28 | ofUnregisterMouseEvents(this);
29 | ofUnregisterKeyEvents(this);
30 | is_enabled_ = false;
31 | clearOperation();
32 | }
33 | }
34 | void ControllerBase::add(shared_ptr mesh)
35 | {
36 | meshes_.insert(mesh);
37 | }
38 | void ControllerBase::clear()
39 | {
40 | clearOperation();
41 | meshes_.clear();
42 | }
43 | void ControllerBase::draw() const
44 | {
45 | ofPushMatrix();
46 | ofTranslate(translation_);
47 | ofScale(scale_, scale_);
48 | ofTranslate(-anchor_point_);
49 | for(auto &mesh : meshes_) {
50 | mesh->drawWireframe();
51 | }
52 | drawCustom();
53 | ofPopMatrix();
54 | }
55 | void ControllerBase::drawFace() const
56 | {
57 | ofPushMatrix();
58 | ofTranslate(translation_);
59 | ofScale(scale_, scale_);
60 | ofTranslate(-anchor_point_);
61 | for(auto &mesh : meshes_) {
62 | mesh->drawMesh();
63 | }
64 | ofPopMatrix();
65 | }
66 | // ==========
67 | void PointController::clearOperation()
68 | {
69 | mouse_op_.hover = nullptr;
70 | mouse_op_.inside_rect.clear();
71 | mouse_op_.edit.clear();
72 | selected_.clear();
73 | mouse_op_.pressed_state = MouseOperation::STATE_NONE;
74 | }
75 | void PointController::drawCustom() const
76 | {
77 | auto drawCircle = [&](MeshPoint* p, float size_add=0) {
78 | float size = point_size_*(p->isNode()?1:0.5f)+size_add;
79 | ofDrawCircle(p->point(), size/scale_);
80 | };
81 | ofPushStyle();
82 | ofSetColor(ofColor::green);
83 | ofNoFill();
84 | for(auto &mesh : meshes_) {
85 | auto points = mesh->getPoints();
86 | for(auto &p : points) {
87 | drawCircle(p);
88 | }
89 | }
90 | ofSetColor(ofColor::green);
91 | ofFill();
92 | if(mouse_op_.hover) {
93 | drawCircle(mouse_op_.hover, 2);
94 | }
95 | for(auto &p : mouse_op_.inside_rect) {
96 | drawCircle(p, 2);
97 | }
98 | ofSetColor(ofColor::red);
99 | ofFill();
100 | for(auto &p : selected_) {
101 | drawCircle(p);
102 | }
103 | for(auto &p : mouse_op_.edit) {
104 | drawCircle(p.first);
105 | }
106 | if(isMakingRect()) {
107 | ofFill();
108 | ofSetColor(ofColor::white, 128);
109 | ofDrawRectangle(ofRectangle(mouse_op_.pressed_pos, mouse_op_.pos));
110 | }
111 | ofPopStyle();
112 | }
113 |
114 | bool PointController::isEditing() const
115 | {
116 | return mouse_op_.hover!=nullptr || isGrabbing() || isMakingRect();
117 | }
118 | void PointController::mousePressed(ofMouseEventArgs &args)
119 | {
120 | glm::vec2 local = screenToLocal(args);
121 | mouse_op_.pressed_pos = local;
122 | mouse_op_.pressed_state = MouseOperation::STATE_NONE;
123 | switch(args.button) {
124 | case OF_MOUSE_BUTTON_LEFT:
125 | if(mouse_op_.hover) {
126 | mouse_op_.pressed_state = MouseOperation::STATE_GRABBING;
127 | }
128 | else {
129 | mouse_op_.pressed_state = MouseOperation::STATE_MAKING_RECT;
130 | }
131 | break;
132 | case OF_MOUSE_BUTTON_MIDDLE:
133 | if(mouse_op_.hover) {
134 | mouse_op_.pressed_state = MouseOperation::STATE_GRABBING;
135 | }
136 | break;
137 | }
138 | switch(mouse_op_.pressed_state) {
139 | case MouseOperation::STATE_GRABBING: {
140 | const auto &it = selected_.insert(mouse_op_.hover);
141 | if(it.second) {
142 | if(!isAlternative() && !isAdditive()) {
143 | selected_.clear();
144 | selected_.insert(mouse_op_.hover);
145 | }
146 | }
147 | else {
148 | if(isAlternative()) {
149 | selected_.erase(mouse_op_.hover);
150 | mouse_op_.pressed_state = MouseOperation::STATE_NONE;
151 | }
152 | }
153 | if(isToggleNode()) {
154 | bool set = !mouse_op_.hover->isNode();
155 | mouse_op_.hover->setNodal(set);
156 | for(auto &p : selected_) {
157 | p->setNodal(set);
158 | }
159 | mouse_op_.pressed_state = MouseOperation::STATE_NONE;
160 | for(auto &m : meshes_) {
161 | m->setDirty();
162 | }
163 | }
164 | else if(isGrabbing()) {
165 | for(auto &p : selected_) {
166 | mouse_op_.edit.push_back(p);
167 | }
168 | mouse_op_.hover = nullptr;
169 | }
170 | } break;
171 | default:
172 | break;
173 | }
174 | }
175 | void PointController::mouseReleased(ofMouseEventArgs &args)
176 | {
177 | glm::vec2 local = screenToLocal(args);
178 | if(isMakingRect()) {
179 | if(!isAlternative() && !isAdditive()) {
180 | selected_.clear();
181 | }
182 | for(auto &p : mouse_op_.inside_rect) {
183 | const auto &it = selected_.insert(p);
184 | if(isAlternative() && !it.second) {
185 | selected_.erase(it.first);
186 | }
187 | }
188 | mouse_op_.inside_rect.clear();
189 | }
190 | else {
191 | mouse_op_.edit.clear();
192 | }
193 | mouse_op_.pressed_state = MouseOperation::STATE_NONE;
194 | mouse_op_.hover = getHit(local);
195 | }
196 | void PointController::mouseMoved(ofMouseEventArgs &args)
197 | {
198 | glm::vec2 local = screenToLocal(args);
199 | mouse_op_.pos = local;
200 | mouse_op_.hover = getHit(local);
201 | }
202 | MeshPoint* PointController::getHit(const glm::vec2 &test) const
203 | {
204 | for(auto &mesh : meshes_) {
205 | MeshHelper m(mesh.get());
206 | if(MeshPoint *hover = m.getHit(test, point_size_/scale_)) {
207 | return hover;
208 | }
209 | }
210 | return nullptr;
211 | }
212 |
213 | void PointController::mouseDragged(ofMouseEventArgs &args)
214 | {
215 | glm::vec2 local = screenToLocal(args);
216 | mouse_op_.pos = local;
217 | if(isMakingRect()) {
218 | mouse_op_.inside_rect.clear();
219 | ofRectangle rect(mouse_op_.pressed_pos, local);
220 | for(auto &mesh : meshes_) {
221 | const auto &hit = MeshHelper(mesh.get()).getHit(rect);
222 | mouse_op_.inside_rect.insert(end(mouse_op_.inside_rect), begin(hit), end(hit));
223 | }
224 | }
225 | else if(isGrabbing()) {
226 | glm::vec2 delta = local-mouse_op_.pressed_pos;
227 | if(isSlide()) {
228 | delta.x = abs(delta.x)isNode()) {
234 | if(isEditVertex()) {
235 | work.setVertexMove(delta);
236 | work.resetCoord();
237 | }
238 | if(isEditCoord()) {
239 | work.setCoordMove(delta/screen_to_coord_);
240 | work.resetVertex();
241 | }
242 | moved_any = true;
243 | }
244 | }
245 | if(moved_any) {
246 | for(auto &m : meshes_) {
247 | m->setDirty();
248 | }
249 | }
250 | }
251 | }
252 | void PointController::mouseScrolled(ofMouseEventArgs &args)
253 | {
254 | float delta = args.scrollY*scroll_to_alpha_;
255 | bool moved_any = false;
256 | for(auto &p : selected_) {
257 | if(p->isNode()) {
258 | float alpha = ofClamp(p->alpha()+delta, 0, ofFloatColor::limit());
259 | PointHelper(p).setAlpha(alpha);
260 | moved_any = true;
261 | }
262 | }
263 | if(moved_any) {
264 | for(auto &m : meshes_) {
265 | m->setDirty();
266 | }
267 | }
268 | }
269 | void PointController::mouseEntered(ofMouseEventArgs &args)
270 | {
271 | }
272 | void PointController::mouseExited(ofMouseEventArgs &args)
273 | {
274 | }
275 | void PointController::keyPressed(ofKeyEventArgs &args)
276 | {
277 | glm::vec2 delta;
278 | switch(args.key) {
279 | case OF_KEY_UP: delta = glm::vec2(0,-1)/scale_; break;
280 | case OF_KEY_DOWN: delta = glm::vec2(0, 1)/scale_; break;
281 | case OF_KEY_LEFT: delta = glm::vec2(-1,0)/scale_; break;
282 | case OF_KEY_RIGHT: delta = glm::vec2(1, 0)/scale_; break;
283 | }
284 | if(glm::length2(delta) > 0) {
285 | bool moved_any = false;
286 | for(auto &p : selected_) {
287 | if(p->isNode()) {
288 | if(isEditVertex()) {
289 | PointHelper(p).moveVertex(delta*(isArrowKeyJump()?10:1));
290 | }
291 | if(isEditCoord()){
292 | PointHelper(p).moveCoord(delta*(isArrowKeyJump()?10:1)/screen_to_coord_);
293 | }
294 | moved_any = true;
295 | }
296 | }
297 | if(moved_any) {
298 | for(auto &m : meshes_) {
299 | m->setDirty();
300 | }
301 | }
302 | mouse_op_.hover = getHit(mouse_op_.pos);
303 | }
304 | }
305 | void PointController::keyReleased(ofKeyEventArgs &args)
306 | {
307 | }
308 |
309 | // ==========
310 | void DivideController::clearOperation()
311 | {
312 | hit_info_ = HitInfo();
313 | }
314 | void DivideController::drawCustom() const
315 | {
316 | for(auto &mesh : meshes_) {
317 | mesh->drawWireframe();
318 | }
319 | if(hit_info_.mesh) {
320 | const auto &points = hit_info_.mesh->getPoints();
321 | ofMesh mesh;
322 | mesh.setMode(OF_PRIMITIVE_LINE_STRIP);
323 | ofPushStyle();
324 | if(isDivide()) {
325 | if(hit_info_.isLineX()) {
326 | const auto &points0 = MeshHelper(hit_info_.mesh).getColPoints(hit_info_.line_index_0);
327 | const auto &points1 = MeshHelper(hit_info_.mesh).getColPoints(hit_info_.line_index_1);
328 | assert(points0.size() == points1.size());
329 | ofSetColor(ofColor::green);
330 | for(size_t i = 0, num = points0.size(); i < num; ++i) {
331 | glm::vec3 p = glm::mix(points0[i]->point(), points1[i]->point(), hit_info_.pos_intersection);
332 | mesh.addVertex(p);
333 | }
334 | glEnd();
335 | }
336 | if(hit_info_.isLineY()) {
337 | const auto &points0 = MeshHelper(hit_info_.mesh).getRowPoints(hit_info_.line_index_0);
338 | const auto &points1 = MeshHelper(hit_info_.mesh).getRowPoints(hit_info_.line_index_1);
339 | assert(points0.size() == points1.size());
340 | ofSetColor(ofColor::green);
341 | for(size_t i = 0, num = points0.size(); i < num; ++i) {
342 | glm::vec3 p = glm::mix(points0[i]->point(), points1[i]->point(), hit_info_.pos_intersection);
343 | mesh.addVertex(p);
344 | }
345 | }
346 | }
347 | if(isReduce()) {
348 | if(hit_info_.isLineX()) {
349 | const auto &points = MeshHelper(hit_info_.mesh).getRowPoints(hit_info_.line_index_0);
350 | ofSetColor(ofColor::red);
351 | for(auto &p : points) {
352 | mesh.addVertex(p->point());
353 | }
354 | }
355 | if(hit_info_.isLineY()) {
356 | const auto &points = MeshHelper(hit_info_.mesh).getColPoints(hit_info_.line_index_0);
357 | ofSetColor(ofColor::red);
358 | for(auto &p : points) {
359 | mesh.addVertex(p->point());
360 | }
361 | }
362 | }
363 | if(mesh.getNumVertices() > 0) {
364 | mesh.draw();
365 | }
366 | ofPopStyle();
367 | }
368 | }
369 |
370 | bool DivideController::isEditing() const
371 | {
372 | return hit_info_.isLine();
373 | }
374 |
375 | void DivideController::mousePressed(ofMouseEventArgs &args)
376 | {
377 | glm::vec2 local = screenToLocal(args);
378 | bool dirty = false;
379 | if(isDivide()) {
380 | if(hit_info_.isLineX()) {
381 | hit_info_.mesh->divideCol(hit_info_.line_index_0%hit_info_.mesh->getDivX(), hit_info_.pos_intersection);
382 | dirty = true;
383 | }
384 | if(hit_info_.isLineY()) {
385 | hit_info_.mesh->divideRow(hit_info_.line_index_0/hit_info_.mesh->getDivX(), hit_info_.pos_intersection);
386 | dirty = true;
387 | }
388 | }
389 | if(isReduce()) {
390 | if(hit_info_.isLineX()) {
391 | hit_info_.mesh->reduceRow(hit_info_.line_index_0/hit_info_.mesh->getDivX());
392 | dirty = true;
393 | }
394 | if(hit_info_.isLineY()) {
395 | hit_info_.mesh->reduceCol(hit_info_.line_index_0%hit_info_.mesh->getDivX());
396 | dirty = true;
397 | }
398 | }
399 | if(dirty) {
400 | hit_info_.mesh->setDirty();
401 | hit_info_ = getHitInfo(local);
402 | }
403 | }
404 | void DivideController::mouseReleased(ofMouseEventArgs &args)
405 | {
406 | }
407 | void DivideController::mouseMoved(ofMouseEventArgs &args)
408 | {
409 | glm::vec2 local = screenToLocal(args);
410 | hit_info_ = getHitInfo(local);
411 | }
412 | void DivideController::mouseDragged(ofMouseEventArgs &args)
413 | {
414 | }
415 | void DivideController::mouseScrolled(ofMouseEventArgs &args)
416 | {
417 | }
418 | void DivideController::mouseEntered(ofMouseEventArgs &args)
419 | {
420 | }
421 | void DivideController::mouseExited(ofMouseEventArgs &args)
422 | {
423 | }
424 | void DivideController::keyPressed(ofKeyEventArgs &args)
425 | {
426 | }
427 | void DivideController::keyReleased(ofKeyEventArgs &args)
428 | {
429 | }
430 | DivideController::HitInfo DivideController::getHitInfo(const glm::vec2 &test) const
431 | {
432 | HitInfo info;
433 | bool is_hit = false;
434 | for(auto &m : meshes_) {
435 | const auto &points = m->getPoints();
436 | int div_x = m->getDivX();
437 | int div_y = m->getDivY();
438 | for(int y = 0; y < div_y-1; ++y) {
439 | for(int x = 0; x < div_x-1; ++x) {
440 | int index = y*div_x+x;
441 | if(MeshHelper(m.get()).isHitBox(test, index)) {
442 | info.mesh = m.get();
443 | info.area_index = index;
444 | is_hit = true;
445 | }
446 | }
447 | }
448 | }
449 | if(is_hit) {
450 | const auto &indices = MeshHelper(info.mesh).getBoxIndices(info.area_index);
451 | assert(indices.size() == 4);
452 | auto check = [this,&info,&test](int index0, int index1) {
453 | if(MeshHelper(info.mesh).isHitLine(test, index0, index1, line_hit_size_/scale_, info.pos_intersection)) {
454 | info.line_index_0 = index0; info.line_index_1 = index1;
455 | return true;
456 | }
457 | return false;
458 | };
459 | if(check(indices[0], indices[1])) return info;
460 | if(check(indices[0], indices[2])) return info;
461 | if(check(indices[1], indices[3])) return info;
462 | if(check(indices[2], indices[3])) return info;
463 | }
464 | return info;
465 | }
466 |
467 |
468 | // ==========
469 | MeshPoint* MeshHelper::getHit(const glm::vec2 &test, float room, int index) const
470 | {
471 | const vector &points = target_->getPoints();
472 | for(auto &p : points) {
473 | if(index < 0) {
474 | return nullptr;
475 | }
476 | if(glm::distance2(glm::vec3(test,0), p->point()) < room*room && index-- == 0) {
477 | return p;
478 | }
479 | }
480 | return nullptr;
481 | }
482 | vector MeshHelper::getHit(const ofRectangle &test) const
483 | {
484 | vector ret;
485 | const vector &points = target_->getPoints();
486 | for(auto &p : points) {
487 | if(test.inside(p->point())) {
488 | ret.push_back(p);
489 | }
490 | }
491 | return ret;
492 | }
493 | vector MeshHelper::getBox(int top_left_index) const
494 | {
495 | vector ret;
496 | auto indices = getBoxIndices(top_left_index);
497 | const auto &points = target_->getPoints();
498 | for(auto i : indices) {
499 | ret.emplace_back(points[i]);
500 | }
501 | return ret;
502 | }
503 | vector MeshHelper::getBoxIndices(int top_left_index) const
504 | {
505 | vector ret;;
506 | if(top_left_index+1 % target_->getDivX()+1 == 0) {
507 | ofLogWarning(__FILE__, "cannot get box with edge index(right)");
508 | return ret;
509 | }
510 | if(top_left_index >= (target_->getDivX()+1)*target_->getDivY()) {
511 | ofLogWarning(__FILE__, "cannot get box with edge index(bottom)");
512 | return ret;
513 | }
514 | ret.emplace_back(top_left_index);
515 | ret.emplace_back(top_left_index+1);
516 | ret.emplace_back(top_left_index+target_->getDivX());
517 | ret.emplace_back(top_left_index+target_->getDivX()+1);
518 | return ret;
519 | }
520 | bool MeshHelper::isHitBox(const glm::vec2 &test, int top_left_index) const
521 | {
522 | const auto &box = getBox(top_left_index);
523 | assert(box.size() == 4);
524 | ofPolyline poly;
525 | poly.addVertex(box[0]->point());
526 | poly.addVertex(box[1]->point());
527 | poly.addVertex(box[3]->point());
528 | poly.addVertex(box[2]->point());
529 | return poly.inside(test.x, test.y);
530 | }
531 | bool MeshHelper::isHitLine(const glm::vec2 &test, int index0, int index1, float room, float &pos) const
532 | {
533 | const auto &points = target_->getPoints();
534 | const glm::vec3 &pivot = points[index0]->point();
535 | const glm::vec3 &anchor = points[index1]->point();
536 | float angle = atan2((test-pivot).y, (test-pivot).x)-atan2((anchor-pivot).y, (anchor-pivot).x);
537 | glm::vec3 alternative = glm::rotate(glm::vec3(test,0)-pivot, -angle*2, glm::vec3(0,0,1)) + pivot;
538 | glm::vec3 intersection = (glm::vec3(test,0)+alternative)/2.f;
539 | if(pivot.x == anchor.x) {
540 | pos = ofMap(intersection.y, pivot.y, anchor.y, 0, 1, false);
541 | }
542 | else {
543 | pos = ofMap(intersection.x, pivot.x, anchor.x, 0, 1, false);
544 | }
545 | if(0<=pos&&pos<=1) {
546 | return glm::distance2(glm::vec3(test,0), intersection) < room*room;
547 | }
548 | return false;
549 | }
550 |
551 | vector MeshHelper::getColPoints(int point_index) const
552 | {
553 | vector ret;
554 | int div_x = target_->getDivX();
555 | const auto &points = target_->getPoints();
556 | for(size_t index = point_index%div_x, num = points.size(); index < num; index += div_x) {
557 | ret.emplace_back(points[index]);
558 | }
559 | return ret;
560 | }
561 | vector MeshHelper::getRowPoints(int point_index) const
562 | {
563 | vector ret;
564 | int div_x = target_->getDivX();
565 | int start = (point_index/div_x)*div_x;
566 | const auto &points = target_->getPoints();
567 | for(int index = start; index < start+div_x; ++index) {
568 | ret.emplace_back(points[index]);
569 | }
570 | return ret;
571 | }
572 |
--------------------------------------------------------------------------------
/example/example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 26E644D906B096668B202176 /* ofxMeshWarpIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FB422832F3529653C73969F /* ofxMeshWarpIO.cpp */; };
11 | 495E638BFCE697B5EBA4F9AF /* ofxMeshWarpManagedController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 96F5A2E6283D0BECD5078F6A /* ofxMeshWarpManagedController.cpp */; };
12 | 96C4B5F7DFEE9AF547996035 /* ofxMeshWarpController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F3E52D9101DBB3C5FC82AA7 /* ofxMeshWarpController.cpp */; };
13 | C3670937900D24095EF91E8F /* ofxMeshWarp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2833749CEB2CD821978836F4 /* ofxMeshWarp.cpp */; };
14 | E4328149138ABC9F0047C5CB /* openFrameworksDebug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E4328148138ABC890047C5CB /* openFrameworksDebug.a */; };
15 | E4B69E200A3A1BDC003C02F2 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4B69E1D0A3A1BDC003C02F2 /* main.cpp */; };
16 | E4B69E210A3A1BDC003C02F2 /* ofApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4B69E1E0A3A1BDC003C02F2 /* ofApp.cpp */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | E4328147138ABC890047C5CB /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */;
23 | proxyType = 2;
24 | remoteGlobalIDString = E4B27C1510CBEB8E00536013;
25 | remoteInfo = openFrameworks;
26 | };
27 | E4EEB9AB138B136A00A80321 /* PBXContainerItemProxy */ = {
28 | isa = PBXContainerItemProxy;
29 | containerPortal = E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */;
30 | proxyType = 1;
31 | remoteGlobalIDString = E4B27C1410CBEB8E00536013;
32 | remoteInfo = openFrameworks;
33 | };
34 | /* End PBXContainerItemProxy section */
35 |
36 | /* Begin PBXCopyFilesBuildPhase section */
37 | E4C2427710CC5ABF004149E2 /* CopyFiles */ = {
38 | isa = PBXCopyFilesBuildPhase;
39 | buildActionMask = 2147483647;
40 | dstPath = "";
41 | dstSubfolderSpec = 10;
42 | files = (
43 | );
44 | runOnlyForDeploymentPostprocessing = 0;
45 | };
46 | /* End PBXCopyFilesBuildPhase section */
47 |
48 | /* Begin PBXFileReference section */
49 | 1F3E52D9101DBB3C5FC82AA7 /* ofxMeshWarpController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ofxMeshWarpController.cpp; path = ../../../addons/ofxMeshWarp/src/ofxMeshWarpController.cpp; sourceTree = SOURCE_ROOT; };
50 | 1FB422832F3529653C73969F /* ofxMeshWarpIO.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ofxMeshWarpIO.cpp; path = ../../../addons/ofxMeshWarp/src/ofxMeshWarpIO.cpp; sourceTree = SOURCE_ROOT; };
51 | 2833749CEB2CD821978836F4 /* ofxMeshWarp.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ofxMeshWarp.cpp; path = ../../../addons/ofxMeshWarp/src/ofxMeshWarp.cpp; sourceTree = SOURCE_ROOT; };
52 | 5AC8E8B8114B873122F9E155 /* ofxMeshWarpController.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ofxMeshWarpController.h; path = ../../../addons/ofxMeshWarp/src/ofxMeshWarpController.h; sourceTree = SOURCE_ROOT; };
53 | 79D11F0DBD55DA42C3B11349 /* ofxMeshWarpIO.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ofxMeshWarpIO.h; path = ../../../addons/ofxMeshWarp/src/ofxMeshWarpIO.h; sourceTree = SOURCE_ROOT; };
54 | 8B1E350E285B120E0743B2F6 /* ofxMeshWarp.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ofxMeshWarp.h; path = ../../../addons/ofxMeshWarp/src/ofxMeshWarp.h; sourceTree = SOURCE_ROOT; };
55 | 96F5A2E6283D0BECD5078F6A /* ofxMeshWarpManagedController.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ofxMeshWarpManagedController.cpp; path = ../../../addons/ofxMeshWarp/src/utils/ofxMeshWarpManagedController.cpp; sourceTree = SOURCE_ROOT; };
56 | AFD9861C6BE5D89A568CB54F /* ofxMeshWarpManagedController.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; name = ofxMeshWarpManagedController.h; path = ../../../addons/ofxMeshWarp/src/utils/ofxMeshWarpManagedController.h; sourceTree = SOURCE_ROOT; };
57 | E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = openFrameworksLib.xcodeproj; path = ../../../libs/openFrameworksCompiled/project/osx/openFrameworksLib.xcodeproj; sourceTree = SOURCE_ROOT; };
58 | E4B69B5B0A3A1756003C02F2 /* exampleDebug.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = exampleDebug.app; sourceTree = BUILT_PRODUCTS_DIR; };
59 | E4B69E1D0A3A1BDC003C02F2 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = src/main.cpp; sourceTree = SOURCE_ROOT; };
60 | E4B69E1E0A3A1BDC003C02F2 /* ofApp.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; name = ofApp.cpp; path = src/ofApp.cpp; sourceTree = SOURCE_ROOT; };
61 | E4B69E1F0A3A1BDC003C02F2 /* ofApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ofApp.h; path = src/ofApp.h; sourceTree = SOURCE_ROOT; };
62 | E4B6FCAD0C3E899E008CF71C /* openFrameworks-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "openFrameworks-Info.plist"; sourceTree = ""; };
63 | E4EB691F138AFCF100A09F29 /* CoreOF.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = CoreOF.xcconfig; path = ../../../libs/openFrameworksCompiled/project/osx/CoreOF.xcconfig; sourceTree = SOURCE_ROOT; };
64 | E4EB6923138AFD0F00A09F29 /* Project.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Project.xcconfig; sourceTree = ""; };
65 | /* End PBXFileReference section */
66 |
67 | /* Begin PBXFrameworksBuildPhase section */
68 | E4B69B590A3A1756003C02F2 /* Frameworks */ = {
69 | isa = PBXFrameworksBuildPhase;
70 | buildActionMask = 2147483647;
71 | files = (
72 | E4328149138ABC9F0047C5CB /* openFrameworksDebug.a in Frameworks */,
73 | );
74 | runOnlyForDeploymentPostprocessing = 0;
75 | };
76 | /* End PBXFrameworksBuildPhase section */
77 |
78 | /* Begin PBXGroup section */
79 | 0EC69C5488FE32328D061788 /* ofxMeshWarp */ = {
80 | isa = PBXGroup;
81 | children = (
82 | 5E921ED3A52D6154CEB1DEC0 /* src */,
83 | );
84 | name = ofxMeshWarp;
85 | sourceTree = "";
86 | };
87 | 5E921ED3A52D6154CEB1DEC0 /* src */ = {
88 | isa = PBXGroup;
89 | children = (
90 | 1FB422832F3529653C73969F /* ofxMeshWarpIO.cpp */,
91 | FDFE70AFF13C04452EC28D6A /* utils */,
92 | 2833749CEB2CD821978836F4 /* ofxMeshWarp.cpp */,
93 | 5AC8E8B8114B873122F9E155 /* ofxMeshWarpController.h */,
94 | 79D11F0DBD55DA42C3B11349 /* ofxMeshWarpIO.h */,
95 | 1F3E52D9101DBB3C5FC82AA7 /* ofxMeshWarpController.cpp */,
96 | 8B1E350E285B120E0743B2F6 /* ofxMeshWarp.h */,
97 | );
98 | name = src;
99 | sourceTree = "";
100 | };
101 | 6948EE371B920CB800B5AC1A /* local_addons */ = {
102 | isa = PBXGroup;
103 | children = (
104 | );
105 | name = local_addons;
106 | sourceTree = "";
107 | };
108 | BB4B014C10F69532006C3DED /* addons */ = {
109 | isa = PBXGroup;
110 | children = (
111 | 0EC69C5488FE32328D061788 /* ofxMeshWarp */,
112 | );
113 | name = addons;
114 | sourceTree = "";
115 | };
116 | E4328144138ABC890047C5CB /* Products */ = {
117 | isa = PBXGroup;
118 | children = (
119 | E4328148138ABC890047C5CB /* openFrameworksDebug.a */,
120 | );
121 | name = Products;
122 | sourceTree = "";
123 | };
124 | E4B69B4A0A3A1720003C02F2 = {
125 | isa = PBXGroup;
126 | children = (
127 | E4B6FCAD0C3E899E008CF71C /* openFrameworks-Info.plist */,
128 | E4EB6923138AFD0F00A09F29 /* Project.xcconfig */,
129 | E4B69E1C0A3A1BDC003C02F2 /* src */,
130 | E4EEC9E9138DF44700A80321 /* openFrameworks */,
131 | BB4B014C10F69532006C3DED /* addons */,
132 | 6948EE371B920CB800B5AC1A /* local_addons */,
133 | E4B69B5B0A3A1756003C02F2 /* exampleDebug.app */,
134 | );
135 | sourceTree = "";
136 | };
137 | E4B69E1C0A3A1BDC003C02F2 /* src */ = {
138 | isa = PBXGroup;
139 | children = (
140 | E4B69E1D0A3A1BDC003C02F2 /* main.cpp */,
141 | E4B69E1E0A3A1BDC003C02F2 /* ofApp.cpp */,
142 | E4B69E1F0A3A1BDC003C02F2 /* ofApp.h */,
143 | );
144 | path = src;
145 | sourceTree = SOURCE_ROOT;
146 | };
147 | E4EEC9E9138DF44700A80321 /* openFrameworks */ = {
148 | isa = PBXGroup;
149 | children = (
150 | E4EB691F138AFCF100A09F29 /* CoreOF.xcconfig */,
151 | E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */,
152 | );
153 | name = openFrameworks;
154 | sourceTree = "";
155 | };
156 | FDFE70AFF13C04452EC28D6A /* utils */ = {
157 | isa = PBXGroup;
158 | children = (
159 | AFD9861C6BE5D89A568CB54F /* ofxMeshWarpManagedController.h */,
160 | 96F5A2E6283D0BECD5078F6A /* ofxMeshWarpManagedController.cpp */,
161 | );
162 | name = utils;
163 | sourceTree = "";
164 | };
165 | /* End PBXGroup section */
166 |
167 | /* Begin PBXNativeTarget section */
168 | E4B69B5A0A3A1756003C02F2 /* example */ = {
169 | isa = PBXNativeTarget;
170 | buildConfigurationList = E4B69B5F0A3A1757003C02F2 /* Build configuration list for PBXNativeTarget "example" */;
171 | buildPhases = (
172 | E4B69B580A3A1756003C02F2 /* Sources */,
173 | E4B69B590A3A1756003C02F2 /* Frameworks */,
174 | E4B6FFFD0C3F9AB9008CF71C /* ShellScript */,
175 | E4C2427710CC5ABF004149E2 /* CopyFiles */,
176 | 8466F1851C04CA0E00918B1C /* ShellScript */,
177 | );
178 | buildRules = (
179 | );
180 | dependencies = (
181 | E4EEB9AC138B136A00A80321 /* PBXTargetDependency */,
182 | );
183 | name = example;
184 | productName = myOFApp;
185 | productReference = E4B69B5B0A3A1756003C02F2 /* exampleDebug.app */;
186 | productType = "com.apple.product-type.application";
187 | };
188 | /* End PBXNativeTarget section */
189 |
190 | /* Begin PBXProject section */
191 | E4B69B4C0A3A1720003C02F2 /* Project object */ = {
192 | isa = PBXProject;
193 | attributes = {
194 | LastUpgradeCheck = 0930;
195 | };
196 | buildConfigurationList = E4B69B4D0A3A1720003C02F2 /* Build configuration list for PBXProject "example" */;
197 | compatibilityVersion = "Xcode 3.2";
198 | developmentRegion = English;
199 | hasScannedForEncodings = 0;
200 | knownRegions = (
201 | English,
202 | Japanese,
203 | French,
204 | German,
205 | );
206 | mainGroup = E4B69B4A0A3A1720003C02F2;
207 | productRefGroup = E4B69B4A0A3A1720003C02F2;
208 | projectDirPath = "";
209 | projectReferences = (
210 | {
211 | ProductGroup = E4328144138ABC890047C5CB /* Products */;
212 | ProjectRef = E4328143138ABC890047C5CB /* openFrameworksLib.xcodeproj */;
213 | },
214 | );
215 | projectRoot = "";
216 | targets = (
217 | E4B69B5A0A3A1756003C02F2 /* example */,
218 | );
219 | };
220 | /* End PBXProject section */
221 |
222 | /* Begin PBXReferenceProxy section */
223 | E4328148138ABC890047C5CB /* openFrameworksDebug.a */ = {
224 | isa = PBXReferenceProxy;
225 | fileType = archive.ar;
226 | path = openFrameworksDebug.a;
227 | remoteRef = E4328147138ABC890047C5CB /* PBXContainerItemProxy */;
228 | sourceTree = BUILT_PRODUCTS_DIR;
229 | };
230 | /* End PBXReferenceProxy section */
231 |
232 | /* Begin PBXShellScriptBuildPhase section */
233 | 8466F1851C04CA0E00918B1C /* ShellScript */ = {
234 | isa = PBXShellScriptBuildPhase;
235 | buildActionMask = 12;
236 | files = (
237 | );
238 | inputPaths = (
239 | );
240 | outputPaths = (
241 | );
242 | runOnlyForDeploymentPostprocessing = 0;
243 | shellPath = /bin/sh;
244 | shellScript = "echo \"$GCC_PREPROCESSOR_DEFINITIONS\";\nAPPSTORE=`expr \"$GCC_PREPROCESSOR_DEFINITIONS\" : \".*APPSTORE=\\([0-9]*\\)\"`\nif [ -z \"$APPSTORE\" ] ; then\necho \"Note: Not copying bin/data to App Package or doing App Code signing. Use AppStore target for AppStore distribution\";\nelse\n# Copy bin/data into App/Resources\nrsync -avz --exclude='.DS_Store' \"${SRCROOT}/bin/data/\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/data/\"\n\n# ---- Code Sign App Package ----\n\n# WARNING: You may have to run Clean in Xcode after changing CODE_SIGN_IDENTITY!\n\n# Verify that $CODE_SIGN_IDENTITY is set\nif [ -z \"${CODE_SIGN_IDENTITY}\" ] ; then\necho \"CODE_SIGN_IDENTITY needs to be set for framework code-signing\"\nexit 0\nfi\n\nif [ -z \"${CODE_SIGN_ENTITLEMENTS}\" ] ; then\necho \"CODE_SIGN_ENTITLEMENTS needs to be set for framework code-signing!\"\n\nif [ \"${CONFIGURATION}\" = \"Release\" ] ; then\nexit 1\nelse\n# Code-signing is optional for non-release builds.\nexit 0\nfi\nfi\n\nITEMS=\"\"\n\nFRAMEWORKS_DIR=\"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\necho \"$FRAMEWORKS_DIR\"\nif [ -d \"$FRAMEWORKS_DIR\" ] ; then\nFRAMEWORKS=$(find \"${FRAMEWORKS_DIR}\" -depth -type d -name \"*.framework\" -or -name \"*.dylib\" -or -name \"*.bundle\" | sed -e \"s/\\(.*framework\\)/\\1\\/Versions\\/A\\//\")\nRESULT=$?\nif [[ $RESULT != 0 ]] ; then\nexit 1\nfi\n\nITEMS=\"${FRAMEWORKS}\"\nfi\n\nLOGINITEMS_DIR=\"${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Library/LoginItems/\"\nif [ -d \"$LOGINITEMS_DIR\" ] ; then\nLOGINITEMS=$(find \"${LOGINITEMS_DIR}\" -depth -type d -name \"*.app\")\nRESULT=$?\nif [[ $RESULT != 0 ]] ; then\nexit 1\nfi\n\nITEMS=\"${ITEMS}\"$'\\n'\"${LOGINITEMS}\"\nfi\n\n# Prefer the expanded name, if available.\nCODE_SIGN_IDENTITY_FOR_ITEMS=\"${EXPANDED_CODE_SIGN_IDENTITY_NAME}\"\nif [ \"${CODE_SIGN_IDENTITY_FOR_ITEMS}\" = \"\" ] ; then\n# Fall back to old behavior.\nCODE_SIGN_IDENTITY_FOR_ITEMS=\"${CODE_SIGN_IDENTITY}\"\nfi\n\necho \"Identity:\"\necho \"${CODE_SIGN_IDENTITY_FOR_ITEMS}\"\n\necho \"Entitlements:\"\necho \"${CODE_SIGN_ENTITLEMENTS}\"\n\necho \"Found:\"\necho \"${ITEMS}\"\n\n# Change the Internal Field Separator (IFS) so that spaces in paths will not cause problems below.\nSAVED_IFS=$IFS\nIFS=$(echo -en \"\\n\\b\")\n\n# Loop through all items.\nfor ITEM in $ITEMS;\ndo\necho \"Signing '${ITEM}'\"\ncodesign --force --verbose --sign \"${CODE_SIGN_IDENTITY_FOR_ITEMS}\" --entitlements \"${CODE_SIGN_ENTITLEMENTS}\" \"${ITEM}\"\nRESULT=$?\nif [[ $RESULT != 0 ]] ; then\necho \"Failed to sign '${ITEM}'.\"\nIFS=$SAVED_IFS\nexit 1\nfi\ndone\n\n# Restore $IFS.\nIFS=$SAVED_IFS\n\nfi\n";
245 | };
246 | E4B6FFFD0C3F9AB9008CF71C /* ShellScript */ = {
247 | isa = PBXShellScriptBuildPhase;
248 | buildActionMask = 2147483647;
249 | files = (
250 | );
251 | inputPaths = (
252 | );
253 | outputPaths = (
254 | );
255 | runOnlyForDeploymentPostprocessing = 0;
256 | shellPath = /bin/sh;
257 | shellScript = "mkdir -p \"$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Resources/\"\n# Copy default icon file into App/Resources\nrsync -aved \"$ICON_FILE\" \"$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Resources/\"\n# Copy libfmod and change install directory for fmod to run\nrsync -aved \"$OF_PATH/libs/fmodex/lib/osx/libfmodex.dylib\" \"$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/\";\ninstall_name_tool -change @executable_path/libfmodex.dylib @executable_path/../Frameworks/libfmodex.dylib \"$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME\";\n\necho \"$GCC_PREPROCESSOR_DEFINITIONS\";\n";
258 | };
259 | /* End PBXShellScriptBuildPhase section */
260 |
261 | /* Begin PBXSourcesBuildPhase section */
262 | E4B69B580A3A1756003C02F2 /* Sources */ = {
263 | isa = PBXSourcesBuildPhase;
264 | buildActionMask = 2147483647;
265 | files = (
266 | E4B69E200A3A1BDC003C02F2 /* main.cpp in Sources */,
267 | E4B69E210A3A1BDC003C02F2 /* ofApp.cpp in Sources */,
268 | 26E644D906B096668B202176 /* ofxMeshWarpIO.cpp in Sources */,
269 | 495E638BFCE697B5EBA4F9AF /* ofxMeshWarpManagedController.cpp in Sources */,
270 | C3670937900D24095EF91E8F /* ofxMeshWarp.cpp in Sources */,
271 | 96C4B5F7DFEE9AF547996035 /* ofxMeshWarpController.cpp in Sources */,
272 | );
273 | runOnlyForDeploymentPostprocessing = 0;
274 | };
275 | /* End PBXSourcesBuildPhase section */
276 |
277 | /* Begin PBXTargetDependency section */
278 | E4EEB9AC138B136A00A80321 /* PBXTargetDependency */ = {
279 | isa = PBXTargetDependency;
280 | name = openFrameworks;
281 | targetProxy = E4EEB9AB138B136A00A80321 /* PBXContainerItemProxy */;
282 | };
283 | /* End PBXTargetDependency section */
284 |
285 | /* Begin XCBuildConfiguration section */
286 | 99FA3DBB1C7456C400CFA0EE /* AppStore */ = {
287 | isa = XCBuildConfiguration;
288 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */;
289 | buildSettings = {
290 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
291 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
292 | CLANG_WARN_BOOL_CONVERSION = YES;
293 | CLANG_WARN_COMMA = YES;
294 | CLANG_WARN_CONSTANT_CONVERSION = YES;
295 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
296 | CLANG_WARN_EMPTY_BODY = YES;
297 | CLANG_WARN_ENUM_CONVERSION = YES;
298 | CLANG_WARN_INFINITE_RECURSION = YES;
299 | CLANG_WARN_INT_CONVERSION = YES;
300 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
301 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
302 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
303 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
304 | CLANG_WARN_STRICT_PROTOTYPES = YES;
305 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
306 | CLANG_WARN_UNREACHABLE_CODE = YES;
307 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
308 | CONFIGURATION_BUILD_DIR = "$(SRCROOT)/bin/";
309 | COPY_PHASE_STRIP = YES;
310 | DEAD_CODE_STRIPPING = YES;
311 | ENABLE_STRICT_OBJC_MSGSEND = YES;
312 | GCC_AUTO_VECTORIZATION = YES;
313 | GCC_ENABLE_SSE3_EXTENSIONS = YES;
314 | GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES;
315 | GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
316 | GCC_NO_COMMON_BLOCKS = YES;
317 | GCC_OPTIMIZATION_LEVEL = 3;
318 | "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "DISTRIBUTION=1";
319 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
320 | GCC_UNROLL_LOOPS = YES;
321 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
322 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
323 | GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO;
324 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
325 | GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = NO;
326 | GCC_WARN_UNDECLARED_SELECTOR = YES;
327 | GCC_WARN_UNINITIALIZED_AUTOS = NO;
328 | GCC_WARN_UNUSED_FUNCTION = YES;
329 | GCC_WARN_UNUSED_VALUE = NO;
330 | GCC_WARN_UNUSED_VARIABLE = NO;
331 | HEADER_SEARCH_PATHS = (
332 | "$(OF_CORE_HEADERS)",
333 | src,
334 | ../../../addons/ofxMeshWarp/src,
335 | ../../../addons/ofxMeshWarp/src/utils,
336 | );
337 | MACOSX_DEPLOYMENT_TARGET = 10.9;
338 | OTHER_CPLUSPLUSFLAGS = (
339 | "-D__MACOSX_CORE__",
340 | "-mtune=native",
341 | );
342 | SDKROOT = macosx;
343 | };
344 | name = AppStore;
345 | };
346 | 99FA3DBC1C7456C400CFA0EE /* AppStore */ = {
347 | isa = XCBuildConfiguration;
348 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */;
349 | buildSettings = {
350 | CLANG_ENABLE_OBJC_WEAK = YES;
351 | COMBINE_HIDPI_IMAGES = YES;
352 | COPY_PHASE_STRIP = YES;
353 | FRAMEWORK_SEARCH_PATHS = "$(inherited)";
354 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
355 | GCC_MODEL_TUNING = NONE;
356 | "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "APPSTORE=1";
357 | HEADER_SEARCH_PATHS = (
358 | "$(OF_CORE_HEADERS)",
359 | src,
360 | ../../../addons/ofxMeshWarp/src,
361 | ../../../addons/ofxMeshWarp/src/utils,
362 | );
363 | ICON = "$(ICON_NAME_RELEASE)";
364 | ICON_FILE = "$(ICON_FILE_PATH)$(ICON)";
365 | INFOPLIST_FILE = "openFrameworks-Info.plist";
366 | INSTALL_PATH = /Applications;
367 | LIBRARY_SEARCH_PATHS = "$(inherited)";
368 | PRODUCT_BUNDLE_IDENTIFIER = cc.openFrameworks.ofapp;
369 | PRODUCT_NAME = "$(TARGET_NAME)";
370 | WRAPPER_EXTENSION = app;
371 | baseConfigurationReference = E4EB6923138AFD0F00A09F29;
372 | };
373 | name = AppStore;
374 | };
375 | E4B69B4E0A3A1720003C02F2 /* Debug */ = {
376 | isa = XCBuildConfiguration;
377 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */;
378 | buildSettings = {
379 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
380 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
381 | CLANG_WARN_BOOL_CONVERSION = YES;
382 | CLANG_WARN_COMMA = YES;
383 | CLANG_WARN_CONSTANT_CONVERSION = YES;
384 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
385 | CLANG_WARN_EMPTY_BODY = YES;
386 | CLANG_WARN_ENUM_CONVERSION = YES;
387 | CLANG_WARN_INFINITE_RECURSION = YES;
388 | CLANG_WARN_INT_CONVERSION = YES;
389 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
390 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
391 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
392 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
393 | CLANG_WARN_STRICT_PROTOTYPES = YES;
394 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
395 | CLANG_WARN_UNREACHABLE_CODE = YES;
396 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
397 | CONFIGURATION_BUILD_DIR = "$(SRCROOT)/bin/";
398 | COPY_PHASE_STRIP = NO;
399 | DEAD_CODE_STRIPPING = YES;
400 | ENABLE_STRICT_OBJC_MSGSEND = YES;
401 | ENABLE_TESTABILITY = YES;
402 | GCC_AUTO_VECTORIZATION = YES;
403 | GCC_ENABLE_SSE3_EXTENSIONS = YES;
404 | GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES;
405 | GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
406 | GCC_NO_COMMON_BLOCKS = YES;
407 | GCC_OPTIMIZATION_LEVEL = 0;
408 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
409 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
410 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
411 | GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO;
412 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
413 | GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = NO;
414 | GCC_WARN_UNDECLARED_SELECTOR = YES;
415 | GCC_WARN_UNINITIALIZED_AUTOS = NO;
416 | GCC_WARN_UNUSED_FUNCTION = YES;
417 | GCC_WARN_UNUSED_VALUE = NO;
418 | GCC_WARN_UNUSED_VARIABLE = NO;
419 | HEADER_SEARCH_PATHS = (
420 | "$(OF_CORE_HEADERS)",
421 | src,
422 | ../../../addons/ofxMeshWarp/src,
423 | ../../../addons/ofxMeshWarp/src/utils,
424 | );
425 | MACOSX_DEPLOYMENT_TARGET = 10.9;
426 | ONLY_ACTIVE_ARCH = YES;
427 | OTHER_CPLUSPLUSFLAGS = (
428 | "-D__MACOSX_CORE__",
429 | "-mtune=native",
430 | );
431 | SDKROOT = macosx;
432 | };
433 | name = Debug;
434 | };
435 | E4B69B4F0A3A1720003C02F2 /* Release */ = {
436 | isa = XCBuildConfiguration;
437 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */;
438 | buildSettings = {
439 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
440 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
441 | CLANG_WARN_BOOL_CONVERSION = YES;
442 | CLANG_WARN_COMMA = YES;
443 | CLANG_WARN_CONSTANT_CONVERSION = YES;
444 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
445 | CLANG_WARN_EMPTY_BODY = YES;
446 | CLANG_WARN_ENUM_CONVERSION = YES;
447 | CLANG_WARN_INFINITE_RECURSION = YES;
448 | CLANG_WARN_INT_CONVERSION = YES;
449 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
450 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
451 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
452 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
453 | CLANG_WARN_STRICT_PROTOTYPES = YES;
454 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
455 | CLANG_WARN_UNREACHABLE_CODE = YES;
456 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
457 | CONFIGURATION_BUILD_DIR = "$(SRCROOT)/bin/";
458 | COPY_PHASE_STRIP = YES;
459 | DEAD_CODE_STRIPPING = YES;
460 | ENABLE_STRICT_OBJC_MSGSEND = YES;
461 | GCC_AUTO_VECTORIZATION = YES;
462 | GCC_ENABLE_SSE3_EXTENSIONS = YES;
463 | GCC_ENABLE_SUPPLEMENTAL_SSE3_INSTRUCTIONS = YES;
464 | GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
465 | GCC_NO_COMMON_BLOCKS = YES;
466 | GCC_OPTIMIZATION_LEVEL = 3;
467 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
468 | GCC_UNROLL_LOOPS = YES;
469 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
470 | GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
471 | GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO;
472 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
473 | GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL = NO;
474 | GCC_WARN_UNDECLARED_SELECTOR = YES;
475 | GCC_WARN_UNINITIALIZED_AUTOS = NO;
476 | GCC_WARN_UNUSED_FUNCTION = YES;
477 | GCC_WARN_UNUSED_VALUE = NO;
478 | GCC_WARN_UNUSED_VARIABLE = NO;
479 | HEADER_SEARCH_PATHS = (
480 | "$(OF_CORE_HEADERS)",
481 | src,
482 | ../../../addons/ofxMeshWarp/src,
483 | ../../../addons/ofxMeshWarp/src/utils,
484 | );
485 | MACOSX_DEPLOYMENT_TARGET = 10.9;
486 | OTHER_CPLUSPLUSFLAGS = (
487 | "-D__MACOSX_CORE__",
488 | "-mtune=native",
489 | );
490 | SDKROOT = macosx;
491 | };
492 | name = Release;
493 | };
494 | E4B69B600A3A1757003C02F2 /* Debug */ = {
495 | isa = XCBuildConfiguration;
496 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */;
497 | buildSettings = {
498 | CLANG_ENABLE_OBJC_WEAK = YES;
499 | COMBINE_HIDPI_IMAGES = YES;
500 | COPY_PHASE_STRIP = NO;
501 | FRAMEWORK_SEARCH_PATHS = "$(inherited)";
502 | GCC_DYNAMIC_NO_PIC = NO;
503 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
504 | GCC_MODEL_TUNING = NONE;
505 | HEADER_SEARCH_PATHS = (
506 | "$(OF_CORE_HEADERS)",
507 | src,
508 | ../../../addons/ofxMeshWarp/src,
509 | ../../../addons/ofxMeshWarp/src/utils,
510 | );
511 | ICON = "$(ICON_NAME_DEBUG)";
512 | ICON_FILE = "$(ICON_FILE_PATH)$(ICON)";
513 | INFOPLIST_FILE = "openFrameworks-Info.plist";
514 | INSTALL_PATH = /Applications;
515 | LIBRARY_SEARCH_PATHS = "$(inherited)";
516 | PRODUCT_BUNDLE_IDENTIFIER = cc.openFrameworks.ofapp;
517 | PRODUCT_NAME = "$(TARGET_NAME)Debug";
518 | WRAPPER_EXTENSION = app;
519 | };
520 | name = Debug;
521 | };
522 | E4B69B610A3A1757003C02F2 /* Release */ = {
523 | isa = XCBuildConfiguration;
524 | baseConfigurationReference = E4EB6923138AFD0F00A09F29 /* Project.xcconfig */;
525 | buildSettings = {
526 | CLANG_ENABLE_OBJC_WEAK = YES;
527 | COMBINE_HIDPI_IMAGES = YES;
528 | COPY_PHASE_STRIP = YES;
529 | FRAMEWORK_SEARCH_PATHS = "$(inherited)";
530 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
531 | GCC_MODEL_TUNING = NONE;
532 | HEADER_SEARCH_PATHS = (
533 | "$(OF_CORE_HEADERS)",
534 | src,
535 | ../../../addons/ofxMeshWarp/src,
536 | ../../../addons/ofxMeshWarp/src/utils,
537 | );
538 | ICON = "$(ICON_NAME_RELEASE)";
539 | ICON_FILE = "$(ICON_FILE_PATH)$(ICON)";
540 | INFOPLIST_FILE = "openFrameworks-Info.plist";
541 | INSTALL_PATH = /Applications;
542 | LIBRARY_SEARCH_PATHS = "$(inherited)";
543 | PRODUCT_BUNDLE_IDENTIFIER = cc.openFrameworks.ofapp;
544 | PRODUCT_NAME = "$(TARGET_NAME)";
545 | WRAPPER_EXTENSION = app;
546 | baseConfigurationReference = E4EB6923138AFD0F00A09F29;
547 | };
548 | name = Release;
549 | };
550 | /* End XCBuildConfiguration section */
551 |
552 | /* Begin XCConfigurationList section */
553 | E4B69B4D0A3A1720003C02F2 /* Build configuration list for PBXProject "example" */ = {
554 | isa = XCConfigurationList;
555 | buildConfigurations = (
556 | E4B69B4E0A3A1720003C02F2 /* Debug */,
557 | E4B69B4F0A3A1720003C02F2 /* Release */,
558 | 99FA3DBB1C7456C400CFA0EE /* AppStore */,
559 | );
560 | defaultConfigurationIsVisible = 0;
561 | defaultConfigurationName = Release;
562 | };
563 | E4B69B5F0A3A1757003C02F2 /* Build configuration list for PBXNativeTarget "example" */ = {
564 | isa = XCConfigurationList;
565 | buildConfigurations = (
566 | E4B69B600A3A1757003C02F2 /* Debug */,
567 | E4B69B610A3A1757003C02F2 /* Release */,
568 | 99FA3DBC1C7456C400CFA0EE /* AppStore */,
569 | );
570 | defaultConfigurationIsVisible = 0;
571 | defaultConfigurationName = Release;
572 | };
573 | /* End XCConfigurationList section */
574 | };
575 | rootObject = E4B69B4C0A3A1720003C02F2 /* Project object */;
576 | }
577 |
--------------------------------------------------------------------------------