//-------------------------------------------------------------- //Universal function which sets normals for the triangle mesh void setNormals( ofMesh &mesh ){ int nV = mesh.getNumVertices();//640 int nT = mesh.getNumIndices() / 3;//213 vector<ofPoint> norm( nV ); for (int t=0; t<nT; t++) { int i1 = mesh.getIndex( 3 * t ); int i2 = mesh.getIndex( 3 * t + 1 ); int i3 = mesh.getIndex( 641 ); const ofPoint &v1 = mesh.getVertex( i1 ); const ofPoint &v2 = mesh.getVertex( i2 ); const ofPoint &v3 = mesh.getVertex( i3 ); //Compute the triangle's normal ofPoint dir = ( (v2 - v1).crossed( v3 - v1 ) ).normalized(); norm[ i1 ] += dir; norm[ i2 ] += dir; norm[ i3 ] += dir; } //Normalize the normal's length for (int i=0; i<nV; i++) { norm[i].normalize(); } //Set the normals to mesh mesh.clearNormals(); mesh.addNormals( norm ); }
void PyramidBrush::setNormals(ofMesh& mesh) { int nV = mesh.getNumVertices(); int nT = mesh.getNumIndices() / 3; vector<ofPoint> norm(nV); for(int t=0; t < nT; t++) { int i1 = mesh.getIndex(3*t); int i2 = mesh.getIndex(3*t + 1); int i3 = mesh.getIndex(3*t + 2); const ofPoint &v1 = mesh.getVertex(i1); const ofPoint &v2 = mesh.getVertex(i2); const ofPoint &v3 = mesh.getVertex(i3); ofPoint dir = ( (v2 - v1).crossed(v3 - v1)).normalized(); norm[i1] += dir; norm[i2] += dir; norm[i3] += dir; } for(int i = 0; i < nV; i++) { norm[i].normalize(); } mesh.clearNormals(); mesh.addNormals(norm); }
//Universal function which sets normals for the triangle mesh void ofxOcean::setNormals( ofMesh &mesh ){ //The number of the vertices int nV = mesh.getNumVertices(); //The number of the triangles int nT = mesh.getNumIndices() / 3; vector<ofPoint> norm( nV ); //Array for the normals //Scan all the triangles. For each triangle add its //normal to norm's vectors of triangle's vertices for (int t=0; t<nT; t++) { //Get indices of the triangle t int i1 = mesh.getIndex( 3 * t ); int i2 = mesh.getIndex( 3 * t + 1 ); int i3 = mesh.getIndex( 3 * t + 2 ); //Get vertices of the triangle const ofPoint &v1 = mesh.getVertex( i1 ); const ofPoint &v2 = mesh.getVertex( i2 ); const ofPoint &v3 = mesh.getVertex( i3 ); //Compute the triangle's normal ofPoint dir = ( (v2 - v1).getCrossed( v3 - v1 ) ).getNormalized(); //Accumulate it to norm array for i1, i2, i3 norm[ i1 ] += dir; norm[ i2 ] += dir; norm[ i3 ] += dir; } //Normalize the normal's length for (int i=0; i<nV; i++) { norm[i].normalize(); } //Set the normals to mesh mesh.clearNormals(); mesh.addNormals( norm ); }
void MeshHelper::fuseNeighbours( ofMesh& outputMesh, const ofMesh& sourceMesh, float fuseDistance ) { //@todo tex coords, normals assert( sourceMesh.getMode() == OF_PRIMITIVE_TRIANGLES ); if ( fuseDistance < 0 ) { // fuse close-enough vertices // first define 'close enough' as 1/10000 of smallest dimension of the bounding box width/height/depth ofVec3f tlb, brf; // top left back, bottom right front calculateAABoundingBox( sourceMesh, tlb, brf ); float minDimension = min(brf.x-tlb.x,min(brf.y-tlb.y, brf.z-tlb.z)); fuseDistance = minDimension * 0.00001f; } // now fuse map<int,int> fused; vector<ofVec3f> vertices; for ( int i=0; i<sourceMesh.getNumVertices(); i++ ) { const ofVec3f& vertex = sourceMesh.getVertex(i); //vertex.rotate(10, 10, 10); bool didFuse = false; for ( int j=0; j<vertices.size(); j++ ) { if ( (vertex-vertices[j]).length()<fuseDistance ) { // fuse i to j fused[i] = j; didFuse = true; break; } } if ( !didFuse ) { vertices.push_back( vertex ); fused[i] = vertices.size()-1; } } // build the output mesh outputMesh.clear(); outputMesh.addVertices(vertices); if ( sourceMesh.getNumIndices() > 0 ) { // walk through indices to build up the new mesh const vector<ofIndexType>& indices = sourceMesh.getIndices(); for ( int i=0; i<indices.size(); i+=3 ) { assert( fused.find( indices[i] ) != fused.end() ); assert( fused.find( indices[i+1] ) != fused.end() ); assert( fused.find( indices[i+2] ) != fused.end() ); outputMesh.addTriangle( fused[indices[i]], fused[indices[i+1]], fused[indices[i+2]] ); } } else { // triangles are just triples of vertices for ( int i=0; i<sourceMesh.getNumVertices(); i+=3 ) { outputMesh.addTriangle( fused[i], fused[i+1], fused[i+2] ); } } ofLogNotice("MeshHelper") << "fuseNeighbours: input " << sourceMesh.getNumVertices() << " vertices/" << sourceMesh.getNumIndices() << " indices, output " << outputMesh.getNumVertices() << " vertices/" << outputMesh.getNumIndices() << " indices"; }
void MeshHelper::fuseNeighbours( ofMesh& mesh, float fuseDistance ) { //@todo tex coords, normals assert( mesh.getMode() == OF_PRIMITIVE_TRIANGLES ); int oldNumVerts = mesh.getNumVertices(); int oldNumIndices = mesh.getNumIndices(); if ( fuseDistance < 0 ) { // fuse close-enough vertices // first define 'close enough' as 1/10000 of smallest dimension of the bounding box width/height/depth ofVec3f tlb, brf; // top left back, bottom right front calculateAABoundingBox( mesh, tlb, brf ); float minDimension = min(brf.x-tlb.x,min(brf.y-tlb.y, brf.z-tlb.z)); fuseDistance = minDimension * 0.00001f; } // now fuse map<ofIndexType,ofIndexType> fused; vector<ofVec3f> newVertices; vector<ofIndexType> remove; for ( ofIndexType i=0; i<mesh.getNumVertices(); i++ ) { const ofVec3f& vertex = mesh.getVertex(i); // look at all the earlier vertices bool didFuse = false; for ( ofIndexType j=0; j<newVertices.size(); j++ ) { if ( (vertex-newVertices[j]).length()<fuseDistance ) { // fuse i to j fused[i] = j; remove.push_back(i); didFuse = true; break; } } if ( !didFuse ) { newVertices.push_back( vertex ); fused[i] = newVertices.size()-1; } } // update indices for ( int i=0; i<mesh.getNumIndices(); i++ ) { ofIndexType originalIndex = mesh.getIndex(i); assert( fused.find( originalIndex ) != fused.end() ); if ( fused.find(originalIndex) != fused.end() ) { mesh.getIndices()[i] = fused[originalIndex]; } } // remove the fused for ( int i=remove.size()-1; i>=0; i-- ) { mesh.removeVertex( remove[i] ); } ofLogNotice("MeshHelper") << "fuseNeighbours inplace: input " << oldNumVerts << " vertices/" << oldNumIndices << " indices, output " << mesh.getNumVertices() << " vertices/" << mesh.getNumIndices() << " indices"; }
ofMesh ofxFfd::deformMesh(ofMesh mesh){ ofMesh dst; dst.append(mesh); for ( int i=0; i<mesh.getNumVertices(); i++ ) { ofVec3f vec = mesh.getVertex(i); dst.setVertex(i, deform(vec)); } return dst; }
ofVec3f getCentroid(ofMesh& mesh){ ofVec3f sum; for(int i=0;i<mesh.getNumVertices();i++){ sum+=mesh.getVertex(i); } sum/=mesh.getNumVertices(); return sum; }
void update() { int n = mesh.getNumVertices(); int start = ofMap(mouseX, 0, ofGetWidth(), 0, n, true); controlPoints.clear(); controlPoints.setMode(OF_PRIMITIVE_POINTS); for(int i = start; i < n; i++) { unsigned int index = rankedCorners[i]; controlPoints.addVertex(mesh.getVertex(index)); } }
void ofApp::drawNormals(const ofMesh& mesh){ for(int i = 0; i < mesh.getVertices().size(); i++){ ofVec3f n = mesh.getNormal(i); ofVec3f v = mesh.getVertex(i); ofPushStyle(); ofSetColor(0, 255, 0); ofLine(v.x, v.y, v.z, v.x + (n.x*4), v.y + (n.y*4), v.z + (n.z*4) ); ofPopStyle(); } }
float getNearestVertex(const ofMesh& mesh, const ofVec2f& target, int& vertexIndex) { float bestDistance = 0; for(int i = 0; i < mesh.getNumVertices(); i++) { float distance = target.distance(mesh.getVertex(i)); if(distance < bestDistance || i == 0) { bestDistance = distance; vertexIndex = i; } } return bestDistance; }
oscThread::oscThread(ofVec2f origin, ofMesh mesh) { originP = mesh.getVertex(origin.x); destP = mesh.getVertex(origin.y); length = sqrt(pow(destP.x-originP.x,2)+pow(destP.y-originP.y,2)+pow(destP.z-originP.z,2)); tempO.set(-length/2,0); tempD.set(length/2,0); //Rethink these variables, and in what context do they REALLY have influence? color = ofRandom(255); //Real color of braid. Fixed res = 200; //Resolution of line speed = 5; //?? amp = 10; //?? f = 10; //?? numVerts = 0; tLength = 100; cSpeed = 40; }
// Returns true iff the mesh contains two index defined traingles that intersect. bool check_triangle_intersections(ofMesh &mesh) { int len = mesh.getNumIndices(); for(int i = 0; i < len; i += 3) { ofVec3f v1 = mesh.getVertex(mesh.getIndex(i)); ofVec3f v2 = mesh.getVertex(mesh.getIndex(i + 1)); ofVec3f v3 = mesh.getVertex(mesh.getIndex(i + 2)); for(int j = 0; j < len; j += 3) { ofVec3f p1 = mesh.getVertex(mesh.getIndex(j)); ofVec3f p2 = mesh.getVertex(mesh.getIndex(j + 1)); ofVec3f p3 = mesh.getVertex(mesh.getIndex(j + 2)); int b = Intersecting(p1, p2, v1, v2, v3); int b2 = Intersecting(p2, p3, v1, v2, v3); int b3 = Intersecting(p3, p1, v1, v2, v3); if(b == 1 || b2 == 1 || b3 == 1) { return true; } if(point_triangle_intersection(v1, v2, v3, p1)|| point_triangle_intersection(v1, v2, v3, p2)|| point_triangle_intersection(v1, v2, v3, p3)) { return true; } } } return false; }
void draw() { ofBackground(0); glPointSize(2); ofSetColor(32); historyMesh.draw(); ofSetColor(255); dataMesh.draw(); ofSetColor(255, 0, 0); neighborsMesh.draw(); for(int i = 0; i < neighborsMesh.getNumVertices(); i++) { ofLine(neighborsMesh.getVertex(i), ofVec2f(mouseX, mouseY)); } ofDrawBitmapStringHighlight(ofToString(neighborsMesh.getNumVertices()), mouseX, mouseY); drawFramerate(); }
void testApp::addMessage(string address, ofMesh data) { ofxOscMessage msg; msg.setAddress(address); int numOfVertices = data.getNumVertices(); for (int i = 0; i < numOfVertices; i++) { ofVec3f vertex = data.getVertex(i); msg.addFloatArg(vertex.x); msg.addFloatArg(vertex.y); msg.addFloatArg(vertex.z); } bundle.addMessage(msg); }
void getBoundingBox(const ofMesh& mesh, ofVec3f& min, ofVec3f& max) { int n = mesh.getNumVertices(); if(n > 0) { min = mesh.getVertex(0); max = mesh.getVertex(0); for(int i = 1; i < n; i++) { const ofVec3f& cur = mesh.getVertices()[i]; min.x = MIN(min.x, cur.x); min.y = MIN(min.y, cur.y); min.z = MIN(min.z, cur.z); max.x = MAX(max.x, cur.x); max.y = MAX(max.y, cur.y); max.z = MAX(max.z, cur.z); } } }
void MeshHelper::calculateAABoundingBox( const ofMesh& mesh, ofVec3f& topLeftBack, ofVec3f& bottomRightFront ) { ofVec3f& tlb = topLeftBack; ofVec3f& brf = bottomRightFront; for ( int i=0; i<mesh.getNumVertices(); i++ ) { ofVec3f vertex = mesh.getVertex(i); if ( i == 0 ){ tlb = brf = vertex; continue; } tlb.x = min(tlb.x,vertex.x); tlb.y = min(tlb.y,vertex.y); tlb.z = min(tlb.z,vertex.z); brf.x = max(brf.x,vertex.x); brf.y = max(brf.y,vertex.y); brf.z = max(brf.z,vertex.z); } }
vector<pair<btVector3, btConvexHullShape*> > ofxBulletConvexDecomposer::decompose(const ofMesh &meshToDecompose, btVector3 scale ) { assert( meshToDecompose.getMode() == OF_TRIANGLES_MODE ); vector<pair<btVector3, btConvexHullShape*> > convexShapes; int tcount = meshToDecompose.getNumIndices()/3; if ( tcount == 0 ) // nothing to do return convexShapes; // adapted from bullet-2.81-rev2613/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp /* unsigned int depth = 5; float cpercent = 5; float ppercent = 15; unsigned int maxv = 16; float skinWidth = 0.0; // ConvexDecomposition::WavefrontObj wo; ConvexDecomposition::DecompDesc desc; desc.mVcount = meshToDecompose.getNumVertices(); desc.mVertices = (float*)(meshToDecompose.getVerticesPointer()); desc.mTcount = meshToDecompose.getNumIndices()/3; desc.mIndices = meshToDecompose.getIndexPointer(); desc.mDepth = depth; desc.mCpercent = cpercent; desc.mPpercent = ppercent; desc.mMaxVertices = maxv; desc.mSkinWidth = skinWidth; desc.mCallback = this; */ //----------------------------------------------- // HACD //----------------------------------------------- std::vector< HACD::Vec3<HACD::Real> > points; std::vector< HACD::Vec3<long> > triangles; for(int i=0; i<meshToDecompose.getNumVertices(); i++ ) { ofVec3f meshVert = meshToDecompose.getVertex(i); HACD::Vec3<HACD::Real> vertex( meshVert.x, meshVert.y, meshVert.z ); points.push_back(vertex); } for(int i=0;i<meshToDecompose.getNumIndices(); i+=3 ) { HACD::Vec3<long> triangle(meshToDecompose.getIndex(i), meshToDecompose.getIndex(i+1), meshToDecompose.getIndex(i+2) ); triangles.push_back(triangle); } assert(triangles.size()==tcount); HACD::HACD myHACD; myHACD.SetPoints(&points[0]); myHACD.SetNPoints(points.size()); myHACD.SetTriangles(&triangles[0]); myHACD.SetNTriangles(triangles.size()); myHACD.SetCompacityWeight(0.1); myHACD.SetVolumeWeight(0.0); // HACD parameters // Recommended parameters: 2 100 0 0 0 0 size_t nClusters = 2; double concavity = 100; bool invert = false; bool addExtraDistPoints = false; bool addNeighboursDistPoints = false; bool addFacesPoints = false; myHACD.SetNClusters(nClusters); // minimum number of clusters myHACD.SetNVerticesPerCH(100); // max of 100 vertices per convex-hull myHACD.SetConcavity(concavity); // maximum concavity myHACD.SetAddExtraDistPoints(addExtraDistPoints); myHACD.SetAddNeighboursDistPoints(addNeighboursDistPoints); myHACD.SetAddFacesPoints(addFacesPoints); myHACD.SetCallBack( hacdCallback ); myHACD.Compute(); nClusters = myHACD.GetNClusters(); int totalTriangles = 0; int totalPoints = 0; for (int c=0;c<nClusters;c++) { //generate convex result size_t nPoints = myHACD.GetNPointsCH(c); size_t nTriangles = myHACD.GetNTrianglesCH(c); ofLogVerbose("ofxBulletConvexDecomposer") << "cluster " << c <<"/" << nClusters << " points " << nPoints << " triangles " << nTriangles; float* vertices = new float[nPoints*3]; unsigned int* triangles = new unsigned int[nTriangles*3]; HACD::Vec3<HACD::Real> * pointsCH = new HACD::Vec3<HACD::Real>[nPoints]; HACD::Vec3<long> * trianglesCH = new HACD::Vec3<long>[nTriangles]; myHACD.GetCH(c, pointsCH, trianglesCH); // points for(size_t v = 0; v < nPoints; v++) { vertices[3*v] = pointsCH[v].X(); vertices[3*v+1] = pointsCH[v].Y(); vertices[3*v+2] = pointsCH[v].Z(); } // triangles for(size_t f = 0; f < nTriangles; f++) { triangles[3*f] = trianglesCH[f].X(); triangles[3*f+1] = trianglesCH[f].Y(); triangles[3*f+2] = trianglesCH[f].Z(); } ConvexResult r(nPoints, vertices, nTriangles, triangles); convexShapes.push_back( createConvexHullShapeFromConvexResult(r, scale) ); delete [] pointsCH; delete [] trianglesCH; delete [] vertices; delete [] triangles; totalTriangles += nTriangles; } return convexShapes; }
ofMesh SurfaceCoons::surfaceTesselation5(const ofMesh &mesh){ // pour chaque poly, ajouter sommet central ofMesh meshret; meshret.setMode(OF_PRIMITIVE_LINES); vector<ofVec3f> vectorPts; vector<ofVec3f> vectorNormalPts; vector<ofVec3f> vectorSommetsArrets; vector<ofVec3f> vectorNormalSommetsArrets; int N = mesh.getVertices().size()/8; for(int i = 0; i < N; i++){ vectorPts.push_back(mesh.getVertex(8*i)); vectorNormalPts.push_back(mesh.getNormal(8*i)); vectorPts.push_back(mesh.getVertex(8*i+2)); vectorNormalPts.push_back(mesh.getNormal(8*i+2)); vectorPts.push_back(mesh.getVertex(8*i+4)); vectorNormalPts.push_back(mesh.getNormal(8*i+4)); vectorPts.push_back(mesh.getVertex(8*i+6)); vectorNormalPts.push_back(mesh.getNormal(8*i+6)); ofVec3f sommetCentral = vectorPts[0]/4 + vectorPts[1]/4 + vectorPts[2]/4 + vectorPts[3]/4; ofVec3f normalCentral = vectorNormalPts[0]/4 + vectorNormalPts[1]/4 + vectorNormalPts[2]/4 + vectorNormalPts[3]/4; // pour chaque arret, ajouter sommet // trouver triangle adjacent (fct) vectorSommetsArrets.push_back(vectorPts[0]/2 + vectorPts[1]/2); vectorNormalSommetsArrets.push_back(vectorNormalPts[0]/2 + vectorNormalPts[1]/2); vectorSommetsArrets.push_back(vectorPts[1]/2 + vectorPts[2]/2); vectorNormalSommetsArrets.push_back(vectorNormalPts[1]/2 + vectorNormalPts[2]/2); vectorSommetsArrets.push_back(vectorPts[2]/2 + vectorPts[3]/2); vectorNormalSommetsArrets.push_back(vectorNormalPts[2]/2 + vectorNormalPts[3]/2); vectorSommetsArrets.push_back(vectorPts[3]/2 + vectorPts[0]/2); vectorNormalSommetsArrets.push_back(vectorNormalPts[3]/2 + vectorNormalPts[0]/2); // pour chaque arret, ajouter arret // central-arret for(int j = 0; j < 4; j++){ meshret.addVertex(sommetCentral); meshret.addColor(ofFloatColor(1, 1, 0)); meshret.addNormal(normalCentral); meshret.addVertex(vectorSommetsArrets[j]); meshret.addColor(ofFloatColor(1, 1, 0)); meshret.addNormal(vectorNormalSommetsArrets[j]); meshret.addVertex(vectorSommetsArrets[j]); meshret.addColor(ofFloatColor(1, 1, 0)); meshret.addNormal(vectorNormalSommetsArrets[j]); int l = j + 1; if(j == 3){ l = 0; } meshret.addVertex(vectorPts[l]); meshret.addColor(ofFloatColor(1, 1, 0)); meshret.addNormal(vectorNormalPts[l]); meshret.addVertex(vectorPts[l]); meshret.addColor(ofFloatColor(1, 1, 0)); meshret.addNormal(vectorNormalPts[l]); int k = j + 1; if(j == 3){ k = 0; } meshret.addVertex(vectorSommetsArrets[k]); meshret.addColor(ofFloatColor(1, 1, 0)); meshret.addNormal(vectorNormalSommetsArrets[k]); meshret.addVertex(vectorSommetsArrets[k]); meshret.addColor(ofFloatColor(1, 1, 0)); meshret.addNormal(vectorNormalSommetsArrets[k]); meshret.addVertex(sommetCentral); meshret.addColor(ofFloatColor(1, 1, 0)); meshret.addNormal(normalCentral); } vectorPts.clear(); vectorSommetsArrets.clear(); vectorNormalPts.clear(); vectorNormalSommetsArrets.clear(); } return meshret; }
ofMesh SurfaceCoons::surfaceTesselation4(const ofMesh &mesh){ // pour chaque poly, ajouter sommet central vector<ofVec3f> tempVector; ofMesh meshret; meshret.setMode(OF_PRIMITIVE_LINES); vector<ofVec3f> vectorPts; vector<ofVec3f> vectorNormalPts; vector<ofVec3f> vectorSommetsArrets; vector<ofVec3f> vectorNormalSommetsArrets; int N = mesh.getVertices().size()/3; for(int i = 0; i < N; i++){ vectorPts.push_back(mesh.getVertex(3*i)); vectorNormalPts.push_back(mesh.getNormal(3*i)); vectorPts.push_back(mesh.getVertex(3*i+1)); vectorNormalPts.push_back(mesh.getNormal(3*i+1)); vectorPts.push_back(mesh.getVertex(3*i+2)); vectorNormalPts.push_back(mesh.getNormal(3*i+2)); ofVec3f sommetCentral = vectorPts[0]/3 + vectorPts[1]/3 + vectorPts[2]/3; ofVec3f normalCentral = vectorNormalPts[0]/3 + vectorNormalPts[1]/3 + vectorNormalPts[2]/3; // pour chaque arret, ajouter sommet // trouver triangle adjacent (fct) tempVector.clear(); tempVector = ArretTriangle::get2Triangles(m_at, vectorPts[0], vectorPts[1]); if(tempVector.size() == 6){ vectorSommetsArrets.push_back(vectorPts[0]/4 + vectorPts[1]/4 + (tempVector[0]/3 + tempVector[1]/3 + tempVector[2]/3)/4 + (tempVector[3]/3 + tempVector[4]/3 + tempVector[5]/3)/4); } else{ vectorSommetsArrets.push_back(vectorPts[0]/2 + vectorPts[1]/2); } vectorNormalSommetsArrets.push_back(vectorNormalPts[0]/2 + vectorNormalPts[1]/2); tempVector.clear(); tempVector = app::ArretTriangle::get2Triangles(m_at, vectorPts[1], vectorPts[2]); if(tempVector.size() == 6){ vectorSommetsArrets.push_back(vectorPts[1]/4 + vectorPts[2]/4 + (tempVector[0]/3 + tempVector[1]/3 + tempVector[2]/3)/4 + (tempVector[3]/3 + tempVector[4]/3 + tempVector[5]/3)/4); } else{ vectorSommetsArrets.push_back(vectorPts[1]/2 + vectorPts[2]/2); } vectorNormalSommetsArrets.push_back(vectorNormalPts[1]/2 + vectorNormalPts[2]/2); tempVector.clear(); tempVector = app::ArretTriangle::get2Triangles(m_at, vectorPts[2], vectorPts[0]); if(tempVector.size() == 6){ vectorSommetsArrets.push_back(vectorPts[2]/4 + vectorPts[0]/4+ (tempVector[0]/3 + tempVector[1]/3 + tempVector[2]/3)/4 + (tempVector[3]/3 + tempVector[4]/3 + tempVector[5]/3)/4); } else{ vectorSommetsArrets.push_back(vectorPts[2]/2 + vectorPts[0]/2); } vectorNormalSommetsArrets.push_back(vectorNormalPts[2]/2 + vectorNormalPts[0]/2); // pour chaque arret, ajouter arret // central-arret for(int j = 0; j < 3; j++){ meshret.addVertex(sommetCentral); meshret.addColor(ofFloatColor(1, 0, 1)); meshret.addNormal(normalCentral); meshret.addVertex(vectorSommetsArrets[j]); meshret.addColor(ofFloatColor(1, 0, 1)); meshret.addNormal(vectorNormalSommetsArrets[j]); meshret.addVertex(vectorSommetsArrets[j]); meshret.addColor(ofFloatColor(1, 0, 1)); meshret.addNormal(vectorNormalSommetsArrets[j]); int l = j + 1; if(j == 2){ l = 0; } meshret.addVertex(vectorPts[l]); meshret.addColor(ofFloatColor(1, 0, 1)); meshret.addNormal(vectorNormalPts[l]); meshret.addVertex(vectorPts[l]); meshret.addColor(ofFloatColor(1, 0, 1)); meshret.addNormal(vectorNormalPts[l]); int k = j + 1; if(j == 2){ k = 0; } meshret.addVertex(vectorSommetsArrets[k]); meshret.addColor(ofFloatColor(1, 0, 1)); meshret.addNormal(vectorNormalSommetsArrets[k]); meshret.addVertex(vectorSommetsArrets[k]); meshret.addColor(ofFloatColor(1, 0, 1)); meshret.addNormal(vectorNormalSommetsArrets[k]); meshret.addVertex(sommetCentral); meshret.addColor(ofFloatColor(1, 0, 1)); meshret.addNormal(normalCentral); } vectorPts.clear(); vectorSommetsArrets.clear(); vectorNormalPts.clear(); vectorNormalSommetsArrets.clear(); } return meshret; }
void ofCairoRenderer::draw(ofMesh & primitive, bool useColors, bool useTextures, bool useNormals){ if(primitive.getNumVertices() == 0){ return; } if(primitive.getNumIndices() == 0){ ofMesh indexedMesh = primitive; indexedMesh.setupIndicesAuto(); draw(indexedMesh, useColors, useTextures, useNormals); return; } pushMatrix(); cairo_matrix_init_identity(getCairoMatrix()); cairo_new_path(cr); int i = 1; ofVec3f v = transform(primitive.getVertex(primitive.getIndex(0))); ofVec3f v2; cairo_move_to(cr,v.x,v.y); if(primitive.getMode()==OF_PRIMITIVE_TRIANGLE_STRIP){ v = transform(primitive.getVertex(primitive.getIndex(1))); cairo_line_to(cr,v.x,v.y); v = transform(primitive.getVertex(primitive.getIndex(2))); cairo_line_to(cr,v.x,v.y); i=2; } for(; i<primitive.getNumIndices(); i++){ v = transform(primitive.getVertex(primitive.getIndex(i))); switch(primitive.getMode()){ case(OF_PRIMITIVE_TRIANGLES): if((i+1)%3==0){ cairo_line_to(cr,v.x,v.y); v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); }else if((i+3)%3==0){ cairo_move_to(cr,v.x,v.y); }else{ cairo_line_to(cr,v.x,v.y); } break; case(OF_PRIMITIVE_TRIANGLE_STRIP): v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v.x,v.y); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); break; case(OF_PRIMITIVE_TRIANGLE_FAN): /*triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)1); triangles.addIndex((GLuint)2); for(int i = 2; i < primitive.getNumVertices()-1;i++){ triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)i); triangles.addIndex((GLuint)i+1); }*/ break; default:break; } } cairo_move_to(cr,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).x,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).y); if(ofGetStyle().lineWidth>0){ cairo_stroke( cr ); } popMatrix(); }
void ofCairoRenderer::draw(const ofMesh & primitive, ofPolyRenderMode mode, bool useColors, bool useTextures, bool useNormals) const{ if(useColors || useTextures || useNormals){ ofLogWarning("ofCairoRenderer") << "draw(): cairo mesh rendering doesn't support colors, textures, or normals. drawing wireframe ..."; } if(primitive.getNumVertices() == 0){ return; } if(primitive.getNumIndices() == 0){ ofMesh indexedMesh = primitive; indexedMesh.setupIndicesAuto(); draw(indexedMesh, mode, useColors, useTextures, useNormals); return; } cairo_new_path(cr); cairo_matrix_t matrix; cairo_matrix_init_identity(&matrix); cairo_new_path(cr); std::size_t i = 1; ofVec3f v = transform(primitive.getVertex(primitive.getIndex(0))); ofVec3f v2; cairo_move_to(cr,v.x,v.y); if(primitive.getMode()==OF_PRIMITIVE_TRIANGLE_STRIP){ v = transform(primitive.getVertex(primitive.getIndex(1))); cairo_line_to(cr,v.x,v.y); v = transform(primitive.getVertex(primitive.getIndex(2))); cairo_line_to(cr,v.x,v.y); i=2; } for(; i<primitive.getNumIndices(); i++){ v = transform(primitive.getVertex(primitive.getIndex(i))); switch(primitive.getMode()){ case(OF_PRIMITIVE_TRIANGLES): if((i+1)%3==0){ cairo_line_to(cr,v.x,v.y); v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); }else if((i+3)%3==0){ cairo_move_to(cr,v.x,v.y); }else{ cairo_line_to(cr,v.x,v.y); } break; case(OF_PRIMITIVE_TRIANGLE_STRIP): v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v.x,v.y); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); break; case(OF_PRIMITIVE_TRIANGLE_FAN): /*triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)1); triangles.addIndex((GLuint)2); for(int i = 2; i < primitive.getNumVertices()-1;i++){ triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)i); triangles.addIndex((GLuint)i+1); }*/ break; default:break; } } cairo_move_to(cr,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).x,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).y); if(currentStyle.lineWidth>0){ cairo_stroke( cr ); } }
void ofxAutoColorMesh(ofMesh &mesh) { for (int i=0; i<mesh.getNumVertices(); i++) { ofVec3f v = mesh.getVertex(i).normalized(); mesh.addColor(ofFloatColor(v.x,v.y,v.z)); } }
// Return position pos in local grid index space for polygon n and vertex v void getIndexSpacePoint(size_t n, size_t v, openvdb::Vec3d& pos) const { ofVec3f pt = mesh->getVertex(mesh->getIndex(n * 3 + v)); pos[0] = pt.x; pos[1] = pt.y; pos[2] = pt.z; }
void ofCairoRenderer::draw(ofMesh & primitive){ if(primitive.getNumVertices()==0) return; pushMatrix(); cairo_matrix_init_identity(getCairoMatrix()); cairo_new_path(cr); //if(indices.getNumIndices()){ int i = 1; ofVec3f v = transform(primitive.getVertex(primitive.getIndex(0))); ofVec3f v2; cairo_move_to(cr,v.x,v.y); if(primitive.getMode()==OF_TRIANGLE_STRIP_MODE){ v = transform(primitive.getVertex(primitive.getIndex(1))); cairo_line_to(cr,v.x,v.y); v = transform(primitive.getVertex(primitive.getIndex(2))); cairo_line_to(cr,v.x,v.y); i=2; } for(; i<primitive.getNumIndices(); i++){ v = transform(primitive.getVertex(primitive.getIndex(i))); switch(primitive.getMode()){ case(OF_TRIANGLES_MODE): if((i+1)%3==0){ cairo_line_to(cr,v.x,v.y); v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); }else if((i+3)%3==0){ cairo_move_to(cr,v.x,v.y); }else{ cairo_line_to(cr,v.x,v.y); } break; case(OF_TRIANGLE_STRIP_MODE): v2 = transform(primitive.getVertex(primitive.getIndex(i-2))); cairo_line_to(cr,v.x,v.y); cairo_line_to(cr,v2.x,v2.y); cairo_move_to(cr,v.x,v.y); break; case(OF_TRIANGLE_FAN_MODE): /*triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)1); triangles.addIndex((GLuint)2); for(int i = 2; i < primitive.getNumVertices()-1;i++){ triangles.addIndex((GLuint)0); triangles.addIndex((GLuint)i); triangles.addIndex((GLuint)i+1); }*/ break; default:break; } } cairo_move_to(cr,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).x,primitive.getVertex(primitive.getIndex(primitive.getNumIndices()-1)).y); if(ofGetStyle().lineWidth>0){ cairo_stroke( cr ); } popMatrix(); }