├── .gitignore ├── README.md ├── example ├── main.cpp ├── ofApp.cpp └── ofApp.h ├── pictures ├── Mac (1).png ├── Mac (2).png ├── Mac (3).png ├── Windows (1).jpg ├── Windows (2).jpg └── Windows (3).jpg └── src ├── ofxTriangular.cpp ├── ofxTriangular.h ├── ofxTriangularType.cpp ├── ofxTriangularType.h ├── triangle.cpp └── triangle.h /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | obj/ 3 | 4 | *.swp 5 | README~ 6 | .gitignore~ 7 | *.out 8 | *.exe 9 | *.tlog 10 | *.obj 11 | *.pdb 12 | *.idb 13 | *.sdf 14 | *.ilk 15 | *.log 16 | *.lastbuildstate 17 | *.sln 18 | *.suo 19 | *.vcxproj 20 | *.filters 21 | *.user 22 | *.make 23 | *.rc 24 | *.dll 25 | *.exp 26 | *.lib 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ofxTrianglular 2 | 3 | Easy to subdivide a complex 2d shape to triangles.
4 | 5 | Support ```OSX```(Xcode 6.0) ```Windows```(Visual Studio 2012), and ```Linux```(QtCreator, Ubuntu, Thanks for [icq4ever](https://github.com/icq4ever)).
6 | 7 | Based on ```Jonathan Richard Shewchuk```'s [triangle library]( http://www.cs.cmu.edu/~quake/triangle.html)
8 | 9 | --- 10 | 11 | ### How to bulid 12 | 13 | * Based on [OpenFrameworks](http://openframeworks.cc/), only need [ofxTriangular](https://github.com/BentleyBlanks/ofxTrianglular), no other dependencies
14 | 15 | 16 | * To bulid example you need to include [ofxUI](https://github.com/rezaali/ofxUI) and [ofxXmlSettings](https://github.com/openframeworks/openFrameworks/tree/master/addons/ofxXmlSettings) in projectGenerator or added manually. 17 | 18 | 19 | * Replace the defalut project's ```ofApp.cpp``` + ```ofApp.h``` + ```main.cpp```
20 | 21 | --- 22 | 23 | ### Screenshots 24 | 25 | #### OSX 26 | 27 | ![image](https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/master/pictures/Mac%20(1).png) 28 | 29 | #### Windows 30 | 31 | ![image](https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/master/pictures/Windows%20(1).jpg) 32 | 33 | #### Linux 34 | 35 | ![screenshot_Linux](https://cloud.githubusercontent.com/assets/530796/12534737/160ac166-c2a9-11e5-8576-92796b94cf6b.png) 36 | 37 | (Thanks for [icq4ever](https://github.com/icq4ever)) 38 | 39 | --- 40 | 41 | ### Getting Started 42 | 43 | Simplest way to init ```ofxTriangular```. 44 | 45 | ``` c 46 | // set a boundary made by ofPolyline 47 | ofPolyline polyline 48 | 49 | triangular.setBoundary(polyline); 50 | ``` 51 | 52 | If your 2d shape include some holes in it. 53 | 54 | ``` c 55 | // set a hole made by ofPolyline 56 | 57 | // one ofxHole connect one point inside it. 58 | ofxHole hole; 59 | vector holes; 60 | 61 | // only if point(x, y) was inside the hole that you want to add. 62 | if(holeline.inside(x, y)) 63 | { 64 | hole.set(holeline, ofPoint(x, y)); 65 | holes.push_back(hole); 66 | } 67 | 68 | triangular.setHoles(holes); 69 | ``` 70 | 71 | Subdivide complex 2d shape to triangles. 72 | 73 | ``` c 74 | // generate the triangle collections 75 | 76 | triangles = triangular.triangulate(); 77 | ``` 78 | 79 | If you want to render the triangle that ofxTriangular generated. 80 | 81 | ``` c 82 | // loop all of it if needed 83 | for(int i=0; i
94 | * Don't support advanced features like ```iteration```, ```constraint```. etc(haven't open the ```API``` yet).

95 | * Under some certain circumstances, ```Debug``` is much easier to crash than the ```Release```.
96 | 97 | --- 98 | 99 | #### Extreme Cases 100 | 101 | Only in some exreme cases (complex nested boundary) that ofxTriangular runs on Windows was easier to crash than the OSX. 102 | 103 | #### OSX 104 | 105 | ![image](https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/master/pictures/Mac%20(2).png) 106 | 107 | ![image](https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/master/pictures/Mac%20(3).png) 108 | 109 | #### Windows 110 | 111 | ![image](https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/master/pictures/Windows%20(1).jpg) 112 | 113 | ![image](https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/master/pictures/Windows%20(2).jpg) 114 | 115 | 116 | --- 117 | 118 | ## Author 119 | 120 | ``` c 121 | int 官某某 = Bingo; 122 | 123 | char[] 个人博客 = "http://bentleyblanks.github.io"; 124 | ``` -------------------------------------------------------------------------------- /example/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(960,640,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/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup(){ 6 | 7 | sketchMode = 0; 8 | bClear = false; 9 | 10 | // polyline.addVertex(0, 0); 11 | // polyline.addVertex(100, 0); 12 | // polyline.addVertex(100, 400); 13 | // polyline.addVertex(0, 400); 14 | // 15 | // holeline.addVertex(20, 100); 16 | // holeline.addVertex(80, 100); 17 | // holeline.addVertex(80, 200); 18 | // holeline.addVertex(20, 200); 19 | 20 | // segments.push_back(ofxSegment(ofPoint(20, 300), ofPoint(80, 350))); 21 | // segments.push_back(ofxSegment(ofPoint(80, 300), ofPoint(20, 350))); 22 | 23 | // 暂不开放 24 | //triangular.setSegments(segments); 25 | 26 | canvas = new ofxUISuperCanvas("canvas"); 27 | 28 | vector radioName; 29 | radioName.push_back("Boundary"); 30 | radioName.push_back("Holes"); 31 | radioName.push_back("PointInsideHole"); 32 | 33 | canvas->addRadio("Radio", radioName); 34 | canvas->addSpacer(); 35 | canvas->addButton("Clear", false); 36 | canvas->addButton("Generate", false); 37 | slider = canvas->addSlider("tesselationSlider", 100, 700, 600); 38 | 39 | // 细分默认值 40 | triangular.setLevelOfTesselation(slider->getValue()); 41 | 42 | canvas->setPosition(ofGetWidth() - canvas->getRect()->getWidth(), 0); 43 | 44 | ofAddListener(canvas->newGUIEvent, this, &ofApp::guiEvent); 45 | } 46 | 47 | //-------------------------------------------------------------- 48 | void ofApp::update(){ 49 | 50 | } 51 | 52 | //-------------------------------------------------------------- 53 | void ofApp::draw(){ 54 | ofPushStyle(); 55 | ofSetColor(20, 20, 200); 56 | 57 | if(polyline.size() != 0) 58 | polyline.draw(); 59 | 60 | if(holeline.size() != 0) 61 | holeline.draw(); 62 | 63 | for(int i=0; igetValue()); 90 | 91 | triangles = triangular.triangulate(); 92 | 93 | for(int i=0; i holes; 29 | ofxTriangular triangular; 30 | vector triangles; 31 | vector segments; 32 | 33 | ofxUISuperCanvas *canvas; 34 | ofxUISlider *slider; 35 | 36 | bool bClear; 37 | 38 | // 手绘 39 | bool bMouseDown; 40 | 41 | int sketchMode; 42 | }; 43 | -------------------------------------------------------------------------------- /pictures/Mac (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/37716634a21a5f86d1628226ddc7882962f8a96d/pictures/Mac (1).png -------------------------------------------------------------------------------- /pictures/Mac (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/37716634a21a5f86d1628226ddc7882962f8a96d/pictures/Mac (2).png -------------------------------------------------------------------------------- /pictures/Mac (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/37716634a21a5f86d1628226ddc7882962f8a96d/pictures/Mac (3).png -------------------------------------------------------------------------------- /pictures/Windows (1).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/37716634a21a5f86d1628226ddc7882962f8a96d/pictures/Windows (1).jpg -------------------------------------------------------------------------------- /pictures/Windows (2).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/37716634a21a5f86d1628226ddc7882962f8a96d/pictures/Windows (2).jpg -------------------------------------------------------------------------------- /pictures/Windows (3).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/37716634a21a5f86d1628226ddc7882962f8a96d/pictures/Windows (3).jpg -------------------------------------------------------------------------------- /src/ofxTriangular.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxTriangular.h" 2 | 3 | ofxTriangular::ofxTriangular() 4 | { 5 | levelOfTesselation = 10.0; 6 | } 7 | 8 | void ofxTriangular::updatePointlists() 9 | { 10 | // 在无小孔前提下点集数量预设为边界 11 | input.numberofpoints = boundary.getVertices().size(); 12 | 13 | for(int i=0; i temp = boundary.getVertices(); 33 | // 外壳 34 | for(int i=0; i 0) 64 | segmentIndex += holes[holes.size()-1].getBoundary().getVertices().size(); 65 | 66 | // 段约束 67 | for(int i=0; i0号点 -> [0]号段终点 点[0] = [0][1] 110 | // 0->1号点 -> [1]号段终点 点[1] = [2][3] 111 | // 1->2号点 -> [2]号段终点 点[2] = [4][5] 112 | // 2->3号点 -> [3]号段终点 点[3] = [6][7] 113 | 114 | // 外壳段初始化 115 | // 起始点序号 116 | int startIndex = 0; 117 | for(int i=0; i<2 * boundary.getVertices().size(); i++) 118 | { 119 | // 起始点处初始化起始点 | 结尾处连接形成封闭折线 120 | if(i == 0 || i == boundary.getVertices().size() * 2 - 1) 121 | input.segmentlist[i] = startIndex; 122 | else 123 | input.segmentlist[i] = startIndex + (i + 1) / 2; 124 | } 125 | 126 | 127 | // 小孔段初始化 128 | startIndex = boundary.getVertices().size(); 129 | int holeIndex = 2 * boundary.getVertices().size(); 130 | vector holeSegment; 131 | for(int i=0; i 9 [16] -> [17] 161 | // 9 -> 8 [18] -> [19] 162 | // 来回闭合 163 | for(int i=0; i& ofxTriangular::triangulate() 175 | { 176 | updatePointlists(); 177 | 178 | if(input.numberofpoints == 0) 179 | { 180 | cout << "输入参数的点数为0 无法进行三角形细分" << endl; 181 | return triangles; 182 | } 183 | 184 | input.numberofregions = 0; 185 | input.regionlist = NULL; 186 | 187 | 188 | // 小孔 189 | input.numberofholes = holes.size(); 190 | input.holelist = (REAL *) malloc(input.numberofholes * 2 * sizeof(REAL)); 191 | for(int i=0; ilevelOfTesselation = levelOfTesselation; 279 | } 280 | 281 | 282 | void ofxTriangular::setBoundary(ofPolyline boundary) 283 | { 284 | this->boundary = boundary; 285 | } 286 | 287 | void ofxTriangular::setSegments(vector segments) 288 | { 289 | this->segments = segments; 290 | } 291 | 292 | void ofxTriangular::setHoles(vector holes) 293 | { 294 | this->holes = holes; 295 | } 296 | 297 | void ofxTriangular::clearBoundary() 298 | { 299 | boundary.clear(); 300 | } 301 | 302 | void ofxTriangular::clearSegments() 303 | { 304 | segments.clear(); 305 | } 306 | 307 | void ofxTriangular::clearHoles() 308 | { 309 | holes.clear(); 310 | } -------------------------------------------------------------------------------- /src/ofxTriangular.h: -------------------------------------------------------------------------------- 1 | #ifndef OFX_TRIANGULAR_H 2 | #define OFX_TRIANGULAR_H 3 | 4 | #include 5 | #include "ofxTriangularType.h" 6 | #include "triangle.h" 7 | 8 | class ofxTriangular 9 | { 10 | public: 11 | ofxTriangular(); 12 | 13 | // 根据给定的属性来完成三角形细分 14 | vector& triangulate(); 15 | 16 | // …Ë∂®Õº–Œœ∏∑÷µ»º∂ 17 | void setLevelOfTesselation(double levelOfTesselation); 18 | 19 | void setBoundary(ofPolyline boundary); 20 | 21 | void setHoles(vector holes); 22 | 23 | void clearBoundary(); 24 | 25 | void clearSegments(); 26 | 27 | void clearHoles(); 28 | 29 | private: 30 | void updatePointlists(); 31 | 32 | void updateSegmentlists(); 33 | 34 | // 线段约束目前并不完善 暂不开启 35 | void setSegments(vector segments); 36 | 37 | // 外部轮廓 38 | ofPolyline boundary; 39 | // 线段约束线 40 | vector segments; 41 | // 小孔 42 | vector holes; 43 | 44 | //  ‰»Î  ‰≥ˆ VoronoiÕºΩ‚ 45 | struct triangulateio input, output, vorout; 46 | // ”√”⁄÷–º‰π˝∂…º∆À„ 47 | struct triangulateio mid; 48 | 49 | vector triangles; 50 | 51 | // œ∏∑÷µ»º∂ 52 | double levelOfTesselation; 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/ofxTriangularType.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BentleyBlanks/ofxTrianglular/37716634a21a5f86d1628226ddc7882962f8a96d/src/ofxTriangularType.cpp -------------------------------------------------------------------------------- /src/ofxTriangularType.h: -------------------------------------------------------------------------------- 1 | #ifndef OFX_TRIANGULARTYPE_H 2 | #define OFX_TRIANGULARTYPE_H 3 | 4 | #include 5 | 6 | class ofxTriangle 7 | { 8 | public: 9 | ofxTriangle(); 10 | ofxTriangle(ofPoint a, ofPoint b, ofPoint c); 11 | 12 | // ≤ªª·∂‘»˝Ω«–Œ»˝∏ˆµ„ «∑Òπ≤œflΩ¯––ºÏ≤È 13 | void set(ofPoint a, ofPoint b, ofPoint c); 14 | 15 | // drawœ‡πÿ 16 | void setFill(bool fill); 17 | 18 | void setColor(ofColor color); 19 | 20 | void draw(); 21 | 22 | private: 23 | ofPoint a, b, c; 24 | 25 | ofColor color; 26 | bool fill; 27 | }; 28 | 29 | 30 | class ofxHole 31 | { 32 | public: 33 | ofxHole(); 34 | ofxHole(ofPolyline boundary, ofPoint pointInsideHole); 35 | 36 | void set(ofPolyline boundary, ofPoint pointInsideHole); 37 | 38 | // get 39 | ofPolyline getBoundary(); 40 | 41 | ofPoint getPointInsideHole(); 42 | private: 43 | ofPoint pointInsideHole; 44 | ofPolyline boundary; 45 | }; 46 | 47 | class ofxSegment 48 | { 49 | public: 50 | ofxSegment(); 51 | ofxSegment(ofPoint start, ofPoint end); 52 | 53 | void set(ofPoint start, ofPoint end); 54 | 55 | ofPoint getStart(); 56 | ofPoint getEnd(); 57 | 58 | void draw(); 59 | 60 | private: 61 | // 约束线起始点 和 末点 62 | ofPoint start, end; 63 | }; 64 | #endif 65 | -------------------------------------------------------------------------------- /src/triangle.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* */ 3 | /* (triangle.h) */ 4 | /* */ 5 | /* Include file for programs that call Triangle. */ 6 | /* */ 7 | /* Accompanies Triangle Version 1.6 */ 8 | /* July 28, 2005 */ 9 | /* */ 10 | /* Copyright 1996, 2005 */ 11 | /* Jonathan Richard Shewchuk */ 12 | /* 2360 Woolsey #H */ 13 | /* Berkeley, California 94705-1927 */ 14 | /* jrs@cs.berkeley.edu */ 15 | /* */ 16 | /*****************************************************************************/ 17 | 18 | /*****************************************************************************/ 19 | /* */ 20 | /* How to call Triangle from another program */ 21 | /* */ 22 | /* */ 23 | /* If you haven't read Triangle's instructions (run "triangle -h" to read */ 24 | /* them), you won't understand what follows. */ 25 | /* */ 26 | /* Triangle must be compiled into an object file (triangle.o) with the */ 27 | /* TRILIBRARY symbol defined (generally by using the -DTRILIBRARY compiler */ 28 | /* switch). The makefile included with Triangle will do this for you if */ 29 | /* you run "make trilibrary". The resulting object file can be called via */ 30 | /* the procedure triangulate(). */ 31 | /* */ 32 | /* If the size of the object file is important to you, you may wish to */ 33 | /* generate a reduced version of triangle.o. The REDUCED symbol gets rid */ 34 | /* of all features that are primarily of research interest. Specifically, */ 35 | /* the -DREDUCED switch eliminates Triangle's -i, -F, -s, and -C switches. */ 36 | /* The CDT_ONLY symbol gets rid of all meshing algorithms above and beyond */ 37 | /* constrained Delaunay triangulation. Specifically, the -DCDT_ONLY switch */ 38 | /* eliminates Triangle's -r, -q, -a, -u, -D, -Y, -S, and -s switches. */ 39 | /* */ 40 | /* IMPORTANT: These definitions (TRILIBRARY, REDUCED, CDT_ONLY) must be */ 41 | /* made in the makefile or in triangle.c itself. Putting these definitions */ 42 | /* in this file (triangle.h) will not create the desired effect. */ 43 | /* */ 44 | /* */ 45 | /* The calling convention 约定 for triangulate() follows. */ 46 | /* */ 47 | /* void triangulate(triswitches, in, out, vorout) */ 48 | /* char *triswitches; */ 49 | /* struct triangulateio *in; */ 50 | /* struct triangulateio *out; */ 51 | /* struct triangulateio *vorout; */ 52 | /* */ 53 | /* `triswitches' is a string containing the command line switches you wish */ 54 | /* to invoke. No initial dash is required. Some suggestions: */ 55 | /* */ 56 | /* - You'll probably find it convenient to use the `z' switch so that */ 57 | /* points (and other items) are numbered from zero. This simplifies */ 58 | /* indexing, because the first item of any type always starts at index */ 59 | /* [0] of the corresponding array, whether that item's number is zero or */ 60 | /* one. */ 61 | /* - You'll probably want to use the `Q' (quiet) switch in your final code, */ 62 | /* but you can take advantage of Triangle's printed output (including the */ 63 | /* `V' switch) while debugging. */ 64 | /* - If you are not using the `q', `a', `u', `D', `j', or `s' switches, */ 65 | /* then the output points will be identical to the input points, except */ 66 | /* possibly for the boundary markers. If you don't need the boundary */ 67 | /* markers, you should use the `N' (no nodes output) switch to save */ 68 | /* memory. (If you do need boundary markers, but need to save memory, a */ 69 | /* good nasty trick is to set out->pointlist equal to in->pointlist */ 70 | /* before calling triangulate(), so that Triangle overwrites the input */ 71 | /* points with identical copies.) */ 72 | /* - The `I' (no iteration numbers) and `g' (.off file output) switches */ 73 | /* have no effect when Triangle is compiled with TRILIBRARY defined. */ 74 | /* */ 75 | /* `in', `out', and `vorout' are descriptions of the input, the output, */ 76 | /* and the Voronoi output. If the `v' (Voronoi output) switch is not used, */ 77 | /* `vorout' may be NULL. `in' and `out' may never be NULL. */ 78 | /* */ 79 | /* Certain fields of the input and output structures must be initialized, */ 80 | /* as described below. */ 81 | /* */ 82 | /*****************************************************************************/ 83 | 84 | /*****************************************************************************/ 85 | /* */ 86 | /* The `triangulateio' structure. */ 87 | /* */ 88 | /* Used to pass data into and out of the triangulate() procedure. */ 89 | /* */ 90 | /* */ 91 | /* Arrays are used to store points, triangles, markers, and so forth. In */ 92 | /* all cases, the first item in any array is stored starting at index [0]. */ 93 | /* However, that item is item number `1' unless the `z' switch is used, in */ 94 | /* which case it is item number `0'. Hence, you may find it easier to */ 95 | /* index points (and triangles in the neighbor list) if you use the `z' */ 96 | /* switch. Unless, of course, you're calling Triangle from a Fortran */ 97 | /* program. */ 98 | /* */ 99 | /* Description of fields (except the `numberof' fields, which are obvious): */ 100 | /* */ 101 | /* `pointlist': An array of point coordinates. The first point's x */ 102 | /* coordinate is at index [0] and its y coordinate at index [1], followed */ 103 | /* by the coordinates of the remaining points. Each point occupies two */ 104 | /* REALs. */ 105 | /* `pointattributelist': An array of point attributes. Each point's */ 106 | /* attributes occupy `numberofpointattributes' REALs. */ 107 | /* `pointmarkerlist': An array of point markers; one int per point. */ 108 | /* */ 109 | /* `trianglelist': An array of triangle corners. The first triangle's */ 110 | /* first corner is at index [0], followed by its other two corners in */ 111 | /* counterclockwise order, followed by any other nodes if the triangle */ 112 | /* represents a nonlinear element. Each triangle occupies */ 113 | /* `numberofcorners' ints. */ 114 | /* `triangleattributelist': An array of triangle attributes. Each */ 115 | /* triangle's attributes occupy `numberoftriangleattributes' REALs. */ 116 | /* `trianglearealist': An array of triangle area constraints; one REAL per */ 117 | /* triangle. Input only. */ 118 | /* `neighborlist': An array of triangle neighbors; three ints per */ 119 | /* triangle. Output only. */ 120 | /* */ 121 | /* `segmentlist': An array of segment endpoints. The first segment's */ 122 | /* endpoints are at indices [0] and [1], followed by the remaining */ 123 | /* segments. Two ints per segment. */ 124 | /* `segmentmarkerlist': An array of segment markers; one int per segment. */ 125 | /* */ 126 | /* `holelist': An array of holes. The first hole's x and y coordinates */ 127 | /* are at indices [0] and [1], followed by the remaining holes. Two */ 128 | /* REALs per hole. Input only, although the pointer is copied to the */ 129 | /* output structure for your convenience. */ 130 | /* */ 131 | /* `regionlist': An array of regional attributes and area constraints. */ 132 | /* The first constraint's x and y coordinates are at indices [0] and [1], */ 133 | /* followed by the regional attribute at index [2], followed by the */ 134 | /* maximum area at index [3], followed by the remaining area constraints. */ 135 | /* Four REALs per area constraint. Note that each regional attribute is */ 136 | /* used only if you select the `A' switch, and each area constraint is */ 137 | /* used only if you select the `a' switch (with no number following), but */ 138 | /* omitting one of these switches does not change the memory layout. */ 139 | /* Input only, although the pointer is copied to the output structure for */ 140 | /* your convenience. */ 141 | /* */ 142 | /* `edgelist': An array of edge endpoints. The first edge's endpoints are */ 143 | /* at indices [0] and [1], followed by the remaining edges. Two ints per */ 144 | /* edge. Output only. */ 145 | /* `edgemarkerlist': An array of edge markers; one int per edge. Output */ 146 | /* only. */ 147 | /* `normlist': An array of normal vectors, used for infinite rays in */ 148 | /* Voronoi diagrams. The first normal vector's x and y magnitudes are */ 149 | /* at indices [0] and [1], followed by the remaining vectors. For each */ 150 | /* finite edge in a Voronoi diagram, the normal vector written is the */ 151 | /* zero vector. Two REALs per edge. Output only. */ 152 | /* */ 153 | /* */ 154 | /* Any input fields that Triangle will examine must be initialized. */ 155 | /* Furthermore, for each output array that Triangle will write to, you */ 156 | /* must either provide space by setting the appropriate pointer to point */ 157 | /* to the space you want the data written to, or you must initialize the */ 158 | /* pointer to NULL, which tells Triangle to allocate space for the results. */ 159 | /* The latter option is preferable, because Triangle always knows exactly */ 160 | /* how much space to allocate. The former option is provided mainly for */ 161 | /* people who need to call Triangle from Fortran code, though it also makes */ 162 | /* possible some nasty space-saving tricks, like writing the output to the */ 163 | /* same arrays as the input. */ 164 | /* */ 165 | /* Triangle will not free() any input or output arrays, including those it */ 166 | /* allocates itself; that's up to you. You should free arrays allocated by */ 167 | /* Triangle by calling the trifree() procedure defined below. (By default, */ 168 | /* trifree() just calls the standard free() library procedure, but */ 169 | /* applications that call triangulate() may replace trimalloc() and */ 170 | /* trifree() in triangle.c to use specialized memory allocators.) */ 171 | /* */ 172 | /* Here's a guide to help you decide which fields you must initialize */ 173 | /* before you call triangulate(). */ 174 | /* */ 175 | /* `in': */ 176 | /* */ 177 | /* - `pointlist' must always point to a list of points; `numberofpoints' */ 178 | /* and `numberofpointattributes' must be properly set. */ 179 | /* `pointmarkerlist' must either be set to NULL (in which case all */ 180 | /* markers default to zero), or must point to a list of markers. If */ 181 | /* `numberofpointattributes' is not zero, `pointattributelist' must */ 182 | /* point to a list of point attributes. */ 183 | /* - If the `r' switch is used, `trianglelist' must point to a list of */ 184 | /* triangles, and `numberoftriangles', `numberofcorners', and */ 185 | /* `numberoftriangleattributes' must be properly set. If */ 186 | /* `numberoftriangleattributes' is not zero, `triangleattributelist' */ 187 | /* must point to a list of triangle attributes. If the `a' switch is */ 188 | /* used (with no number following), `trianglearealist' must point to a */ 189 | /* list of triangle area constraints. `neighborlist' may be ignored. */ 190 | /* - If the `p' switch is used, `segmentlist' must point to a list of */ 191 | /* segments, `numberofsegments' must be properly set, and */ 192 | /* `segmentmarkerlist' must either be set to NULL (in which case all */ 193 | /* markers default to zero), or must point to a list of markers. */ 194 | /* - If the `p' switch is used without the `r' switch, then */ 195 | /* `numberofholes' and `numberofregions' must be properly set. If */ 196 | /* `numberofholes' is not zero, `holelist' must point to a list of */ 197 | /* holes. If `numberofregions' is not zero, `regionlist' must point to */ 198 | /* a list of region constraints. */ 199 | /* - If the `p' switch is used, `holelist', `numberofholes', */ 200 | /* `regionlist', and `numberofregions' is copied to `out'. (You can */ 201 | /* nonetheless get away with not initializing them if the `r' switch is */ 202 | /* used.) */ 203 | /* - `edgelist', `edgemarkerlist', `normlist', and `numberofedges' may be */ 204 | /* ignored. */ 205 | /* */ 206 | /* `out': */ 207 | /* */ 208 | /* - `pointlist' must be initialized (NULL or pointing to memory) unless */ 209 | /* the `N' switch is used. `pointmarkerlist' must be initialized */ 210 | /* unless the `N' or `B' switch is used. If `N' is not used and */ 211 | /* `in->numberofpointattributes' is not zero, `pointattributelist' must */ 212 | /* be initialized. */ 213 | /* - `trianglelist' must be initialized unless the `E' switch is used. */ 214 | /* `neighborlist' must be initialized if the `n' switch is used. If */ 215 | /* the `E' switch is not used and (`in->numberofelementattributes' is */ 216 | /* not zero or the `A' switch is used), `elementattributelist' must be */ 217 | /* initialized. `trianglearealist' may be ignored. */ 218 | /* - `segmentlist' must be initialized if the `p' or `c' switch is used, */ 219 | /* and the `P' switch is not used. `segmentmarkerlist' must also be */ 220 | /* initialized under these circumstances unless the `B' switch is used. */ 221 | /* - `edgelist' must be initialized if the `e' switch is used. */ 222 | /* `edgemarkerlist' must be initialized if the `e' switch is used and */ 223 | /* the `B' switch is not. */ 224 | /* - `holelist', `regionlist', `normlist', and all scalars may be ignored.*/ 225 | /* */ 226 | /* `vorout' (only needed if `v' switch is used): */ 227 | /* */ 228 | /* - `pointlist' must be initialized. If `in->numberofpointattributes' */ 229 | /* is not zero, `pointattributelist' must be initialized. */ 230 | /* `pointmarkerlist' may be ignored. */ 231 | /* - `edgelist' and `normlist' must both be initialized. */ 232 | /* `edgemarkerlist' may be ignored. */ 233 | /* - Everything else may be ignored. */ 234 | /* */ 235 | /* After a call to triangulate(), the valid fields of `out' and `vorout' */ 236 | /* will depend, in an obvious way, on the choice of switches used. Note */ 237 | /* that when the `p' switch is used, the pointers `holelist' and */ 238 | /* `regionlist' are copied from `in' to `out', but no new space is */ 239 | /* allocated; be careful that you don't free() the same array twice. On */ 240 | /* the other hand, Triangle will never copy the `pointlist' pointer (or any */ 241 | /* others); new space is allocated for `out->pointlist', or if the `N' */ 242 | /* switch is used, `out->pointlist' remains uninitialized. */ 243 | /* */ 244 | /* All of the meaningful `numberof' fields will be properly set; for */ 245 | /* instance, `numberofedges' will represent the number of edges in the */ 246 | /* triangulation whether or not the edges were written. If segments are */ 247 | /* not used, `numberofsegments' will indicate the number of boundary edges. */ 248 | /* */ 249 | /*****************************************************************************/ 250 | #ifndef JONATHAN_TRIANGLE_H 251 | #define JONATHAN_TRIANGLE_H 252 | 253 | #ifdef _cplusplus 254 | extern "C"{ 255 | #endif 256 | 257 | #define ANSI_DECLARATORS 258 | #define VOID int 259 | 260 | #ifdef SINGLE 261 | #define REAL float 262 | #else /* not SINGLE */ 263 | #define REAL double 264 | #endif /* not SINGLE */ 265 | 266 | struct triangulateio { 267 | REAL *pointlist; /* In / out */ 268 | REAL *pointattributelist; /* In / out */ 269 | int *pointmarkerlist; /* In / out */ 270 | int numberofpoints; /* In / out */ 271 | int numberofpointattributes; /* In / out */ 272 | 273 | int *trianglelist; /* In / out */ 274 | REAL *triangleattributelist; /* In / out */ 275 | REAL *trianglearealist; /* In only */ 276 | int *neighborlist; /* Out only */ 277 | int numberoftriangles; /* In / out */ 278 | int numberofcorners; /* In / out */ 279 | int numberoftriangleattributes; /* In / out */ 280 | 281 | int *segmentlist; /* In / out */ 282 | int *segmentmarkerlist; /* In / out */ 283 | int numberofsegments; /* In / out */ 284 | 285 | REAL *holelist; /* In / pointer to array copied out */ 286 | int numberofholes; /* In / copied out */ 287 | 288 | REAL *regionlist; /* In / pointer to array copied out */ 289 | int numberofregions; /* In / copied out */ 290 | 291 | int *edgelist; /* Out only */ 292 | int *edgemarkerlist; /* Not used with Voronoi diagram; out only */ 293 | REAL *normlist; /* Used only with Voronoi diagram; out only */ 294 | int numberofedges; /* Out only */ 295 | }; 296 | 297 | #ifdef ANSI_DECLARATORS 298 | void triangulate(char *, struct triangulateio *, struct triangulateio *, 299 | struct triangulateio *); 300 | void trifree(VOID *memptr); 301 | #else /* not ANSI_DECLARATORS */ 302 | void triangulate(); 303 | void trifree(); 304 | #endif /* not ANSI_DECLARATORS */ 305 | 306 | #ifdef _cplusplus 307 | } 308 | #endif 309 | 310 | #endif --------------------------------------------------------------------------------