#include "ofTessellator.h"
#include "tesselator.h"
#include "ofPolyline.h"
#include "ofMesh.h"
using namespace std;
void * memAllocator( void *userData, unsigned int size ){
return malloc(size);
}
void * memReallocator( void *userData, void* ptr, unsigned int size ){
return realloc(ptr,size);
}
void memFree( void *userData, void *ptr ){
free (ptr);
}
ofTessellator::ofTessellator()
: cacheTess(nullptr)
{
init();
}
ofTessellator::~ofTessellator(){
tessDeleteTess(cacheTess);
}
ofTessellator::ofTessellator(const ofTessellator & mom)
: cacheTess(nullptr)
{
if(&mom != this){
if(cacheTess) tessDeleteTess(cacheTess);
init();
}
}
ofTessellator & ofTessellator::operator=(const ofTessellator & mom){
if(&mom != this){
if(cacheTess) tessDeleteTess(cacheTess);
init();
}
return *this;
}
void ofTessellator::init(){
tessAllocator.memalloc = memAllocator;
tessAllocator.memrealloc = memReallocator;
tessAllocator.memfree = memFree;
tessAllocator.meshEdgeBucketSize=0;
tessAllocator.meshVertexBucketSize=0;
tessAllocator.meshFaceBucketSize=0;
tessAllocator.dictNodeBucketSize=0;
tessAllocator.regionBucketSize=0;
tessAllocator.extraVertices=0;
cacheTess = tessNewTess( &tessAllocator );
}
void ofTessellator::tessellateToMesh( const ofPolyline& src, ofPolyWindingMode polyWindingMode, ofMesh& dstmesh, bool bIs2D){
ofPolyline& polyline = const_cast<ofPolyline&>(src);
tessAddContour( cacheTess, bIs2D?2:3, &polyline.getVertices()[0], sizeof(glm::vec3), polyline.size());
performTessellation( polyWindingMode, dstmesh, bIs2D );
}
void ofTessellator::tessellateToMesh( const vector<ofPolyline>& src, ofPolyWindingMode polyWindingMode, ofMesh & dstmesh, bool bIs2D ) {
for ( int i=0; i<(int)src.size(); ++i ) {
if (src[i].size() > 0) {
ofPolyline& polyline = const_cast<ofPolyline&>(src[i]);
tessAddContour(cacheTess, bIs2D ? 2 : 3, &polyline.getVertices()[0].x, sizeof(glm::vec3), polyline.size());
}
}
performTessellation( polyWindingMode, dstmesh, bIs2D );
}
void ofTessellator::tessellateToPolylines( const ofPolyline& src, ofPolyWindingMode polyWindingMode, vector<ofPolyline>& dstpoly, bool bIs2D){
if (src.size() > 0) {
ofPolyline& polyline = const_cast<ofPolyline&>(src);
tessAddContour(cacheTess, bIs2D ? 2 : 3, &polyline.getVertices()[0], sizeof(glm::vec3), polyline.size());
}
performTessellation( polyWindingMode, dstpoly, bIs2D );
}
void ofTessellator::tessellateToPolylines( const vector<ofPolyline>& src, ofPolyWindingMode polyWindingMode, vector<ofPolyline>& dstpoly, bool bIs2D ) {
for ( int i=0; i<(int)src.size(); ++i ) {
if (src[i].size() > 0) {
ofPolyline& polyline = const_cast<ofPolyline&>(src[i]);
tessAddContour(cacheTess, bIs2D ? 2 : 3, &polyline.getVertices()[0].x, sizeof(glm::vec3), polyline.size());
}
}
performTessellation( polyWindingMode, dstpoly, bIs2D );
}
void ofTessellator::performTessellation(ofPolyWindingMode polyWindingMode, ofMesh& dstmesh, bool bIs2D ) {
if (!tessTesselate(cacheTess, polyWindingMode, TESS_POLYGONS, 3, 3, 0)){
ofLogError("ofTessellator") << "performTessellation(): mesh polygon tessellation failed, winding mode " << polyWindingMode;
return;
}
int numVertices = tessGetVertexCount( cacheTess );
int numIndices = tessGetElementCount( cacheTess )*3;
dstmesh.clear();
dstmesh.addVertices((ofDefaultVertexType*)tessGetVertices(cacheTess),numVertices);
dstmesh.addIndices((ofIndexType*)tessGetElements(cacheTess),numIndices);
dstmesh.setMode(OF_PRIMITIVE_TRIANGLES);
}
void ofTessellator::performTessellation(ofPolyWindingMode polyWindingMode, vector<ofPolyline>& dstpoly, bool bIs2D ) {
if (!tessTesselate(cacheTess, polyWindingMode, TESS_BOUNDARY_CONTOURS, 0, 3, 0)){
ofLogError("ofTessellator") << "performTesselation(): polyline boundary contours tessellation failed, winding mode " << polyWindingMode;
return;
}
const ofDefaultVertexType* verts = (ofDefaultVertexType*)tessGetVertices(cacheTess);
const TESSindex* elems = tessGetElements(cacheTess);
const int nelems = tessGetElementCount(cacheTess);
dstpoly.resize(nelems);
for (int i = 0; i < nelems; ++i)
{
int b = elems[i*2];
int n = elems[i*2+1];
dstpoly[i].clear();
dstpoly[i].addVertices(&verts[b],n);
dstpoly[i].setClosed(true);
}
}
Comments