Beispiel #1
0
//http://www.packtpub.com/sites/default/files/9781849518048_Chapter_07.pdf
//knotExample
void ofApp::addCircle( ofVec3f nextPoint, ofMesh &mesh ){
    float time = ofGetElapsedTimef();    //Time
    //Parameters – twisting and rotating angles and color

    ofFloatColor color( ofNoise( time * 0.05 ),
                       ofNoise( time * 0.1 ),
                       ofNoise( time * 0.15 ));
    color.setSaturation( 1.0 );  //Make the color maximally
    
    //Add vertices
    for (int i=0; i<circleN; i++) {
        float angle = float(i) / circleN * TWO_PI+(PI*0.25);
        float x = Rad * cos( angle );
        float y = Rad * sin( angle );
        ofPoint p =    nextPoint+ofVec3f(x ,y , 0);
        mesh.addVertex( p );
        mesh.addColor( color );
    }
    //Add the triangles
    int base = mesh.getNumVertices() - 2 * circleN;
    if ( base >= 0 ) {  //Check if it is not the first step
        //and we really need to add the triangles
        for (int i=0; i<circleN; i++) {
            int a = base + i;
            int b = base + (i + 1) % circleN;
            int c = circleN  + a;
            int d = circleN  + b;
            mesh.addTriangle(a,b,d);
            mesh.addTriangle(a, d, c);
        }
        //Update the normals
        setNormals( mesh );
    }
}
Beispiel #2
0
void BGGraphics::pushCirclePart(ofMesh& mesh, ofVec2f position, float nodeRadius, float minAngle, float deltaAngle) {

    mesh.setMode(OF_PRIMITIVE_TRIANGLES);

    pushVertex(mesh, position.x, position.y, 1, 0, 0, 1, 0, 0);

    float innerRadius = nodeRadius - NETWORK_OFFSET;

    float internalOffsetY = .5;// innerRadius / nodeRadius;

    int samples = (int)(15 * deltaAngle / M_PI);
    samples = max(1, samples);

    for(int i=0; i<samples; ++i) {
        float angle = minAngle + deltaAngle * i / (float)(samples - 1);
        ofVec2f to(cosf(angle), sinf(angle));

        ofVec2f p1 = position + to * innerRadius;
        ofVec2f p2 = position + to * nodeRadius;

        //pushVertex(ofMesh & mesh, float x, float y, float z, float nx, float ny, float nz, float offsetX, float offsetY) 
        pushVertex(mesh, p1.x, p1.y, 1, 0, 0, 1, 0, internalOffsetY);
        pushVertex(mesh, p2.x, p2.y, 0, to.x, to.y, 0, 0, 1);

        if(i > 0) {
            int offset = 1 + 2 * i;
            mesh.addTriangle(0, offset - 2, offset);
            mesh.addTriangle(offset - 2, offset - 1, offset);
            mesh.addTriangle(offset - 1, offset, offset + 1);
        }
    }
}
Beispiel #3
0
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";
}
Beispiel #4
0
void BGGraphics::pushDoubleConnectedNode(ofMesh& mesh, ofVec2f position, ofVec2f startEdgePoint, ofVec2f endEdgePoint) {

    int samples = 10;
    for(int i=0; i<samples; ++i) {

        float t = i / (float)(samples - 1);

        float localDepth = -.5 + t;

        ofVec2f pt, normal;
        sampleSpline(startEdgePoint, position, endEdgePoint, t, pt, normal);

        pushVertex(mesh, pt.x + NETWORK_OFFSET * normal.x, pt.y + NETWORK_OFFSET * normal.y, 0, normal.x, normal.y, 0, localDepth, 1);
        pushVertex(mesh, pt.x, pt.y, 1, 0, 0, 1, localDepth, 0);
        pushVertex(mesh, pt.x - NETWORK_OFFSET * normal.x, pt.y - NETWORK_OFFSET * normal.y, 0, -normal.x, -normal.y, 0, localDepth, 1);

        if(i > 0) {
            int offset = 3 * i;
            for(int j=0; j<2; ++j) {
                mesh.addTriangle(offset + j, offset - 3 + j, offset - 2 + j);
                mesh.addTriangle(offset + j, offset + 1 + j, offset - 2 + j);
            }
        }
    }
}
void getCellMesh(voro::voronoicell &_c, ofPoint _pos, ofMesh& mesh ){
    if( _c.p ) {
        
        ofPoint centroid = getCellCentroid(_c,_pos);
        
        int i,j,k,l,m,n;
        
        //  Vertex
        //
        double *ptsp=_c.pts;
        vector<ofPoint> vertices;
        vector<ofPoint> normals;
        for(i = 0; i < _c.p; i++, ptsp+=3){
            ofPoint newPoint;
            newPoint.x = _pos.x + ptsp[0]*0.5;
            newPoint.y = _pos.y + ptsp[1]*0.5;
            newPoint.z = _pos.z + ptsp[2]*0.5;
            vertices.push_back(newPoint);
            
            ofPoint newNormal;
            newNormal = _pos - newPoint;//centroid ;
            newNormal = newNormal.normalize();
            normals.push_back(newNormal);
        }
        
//        ofMesh mesh;
        mesh.setMode(OF_PRIMITIVE_TRIANGLES );
        mesh.addVertices(vertices);
        mesh.addNormals(normals);
        
        //  Index
        //
        for(i = 1; i < _c.p; i++){
            for(j = 0; j < _c.nu[i]; j++) {
                
                k = _c.ed[i][j];
                
                if( k >= 0 ) {
                    _c.ed[i][j]=-1-k;
                    l = _c.cycle_up( _c.ed[i][ _c.nu[i]+j], k);
                    m = _c.ed[k][l];
                    _c.ed[k][l]=-1-m;
                    
                    while(m!=i) {
                        n = _c.cycle_up( _c.ed[k][ _c.nu[k]+l],m);
                        mesh.addTriangle(i, k, m);
                        
                        k=m;
                        l=n;
                        m=_c.ed[k][l];
                        _c.ed[k][l]=-1-m;
                    }
                }
            }
        }
        
//        return mesh;
    }
    
//    return ofMesh();
};
Beispiel #6
0
void BGGraphics::pushSingleConnectedNode(ofMesh& mesh, ofVec2f position, float nodeRadius, ofVec2f edgePoint, bool isRoot) {

    float innerRadius = nodeRadius - NETWORK_OFFSET;

    ofVec2f to = edgePoint - position;
    float toDist = to.length();
    to /= toDist;
    ofVec2f perp = ofVec2f(-to.y, to.x);

    float depthFactor = isRoot ? .5 : -.5;

    float proj = sqrtf(.5 * innerRadius * innerRadius);

    if(toDist > innerRadius + NETWORK_OFFSET) {

        float offset = min(innerRadius + .5f * (toDist - innerRadius), 2 * proj);

        
        //perform spline traversal...
        ofVec2f controlPoint = position + offset * to;// .5 * (position + innerRadius * to) + .5 * edgePoint;
        float angle = acosf(innerRadius / offset);

        pushCirclePart(mesh, position, nodeRadius, atan2f(to.y, to.x) + angle, 2 * (M_PI - angle));
        int splineOffset = mesh.getVertices().size();

/*
        ofVec2f anchorLeft  = position + proj * to + proj * perp;
        ofVec2f anchorRight = position + proj * to - proj * perp;
        ofVec2f toA1 = (anchorLeft - position).normalize();
        ofVec2f toA2 = (anchorRight - position).normalize();
            */

        
        float toAng = atan2f(to.y, to.x);
        ofVec2f toA1(cosf(toAng + angle), sinf(toAng + angle));
        ofVec2f toA2(cosf(toAng - angle), sinf(toAng - angle));

        float facU = innerRadius * cosf(angle);
        float facV = innerRadius * sinf(angle);

        float anchorProj = sqrtf(.5 * innerRadius * innerRadius);
        ofVec2f anchorLeft  = position + innerRadius * toA1;
        ofVec2f anchorRight = position + innerRadius * toA2;
        

        float innerRadiusFactor = .5;// innerRadius / nodeRadius;

        //add first point:
        pushVertex(mesh, anchorLeft.x + NETWORK_OFFSET * toA1.x, anchorLeft.y + NETWORK_OFFSET * toA1.y, 0, toA1.x, toA1.y, 0, 0, 1);
        pushVertex(mesh, anchorLeft.x, anchorLeft.y, 1, 0, 0, 1, 0, innerRadiusFactor);
        pushVertex(mesh, position.x, position.y, 1, 0, 0, 1, 0, 0);
        pushVertex(mesh, anchorRight.x, anchorRight.y, 1, 0, 0, 1, 0, innerRadiusFactor);
        pushVertex(mesh, anchorRight.x + NETWORK_OFFSET * toA2.x, anchorRight.y + NETWORK_OFFSET * toA2.y, 0, toA2.x, toA2.y, 0, 0, 1);

        int samples = 8;
        for(int i=1; i<samples; ++i) {

            float t = i / (float)(samples - 1);

            float localDepth = depthFactor * t;

            ofVec2f pt, normal;
            sampleSpline(anchorLeft, controlPoint, edgePoint, t, pt, normal);
            normal = -normal;
/*
            //project point on skeleton:
            //float projDistance = dot(pt - position, to);
            float innerSampleOffset = dot(pt - position, to);//(pt - centerSample).length();
            ofVec2f centerSample = position + innerSampleOffset * to;



            float centerSampleDepth = depth + depthFactor * (innerSampleOffset / toDist);
            centerSampleDepth = (centerSampleDepth + localDepth) * .5;
            */
            ofVec2f centerSample;
            getIntersection(position, to, pt, normal, centerSample);
            

            //float innerSampleOffset = (pt - centerSample).length();
            float innerSampleOffsetFactor = (1 - t) * .5;// innerSampleOffset / (innerSampleOffset + NETWORK_OFFSET);

            ofVec2f otherPt = position + reflect(pt - position, to);
            ofVec2f otherNormal = reflect(normal, to);

            pushVertex(mesh, pt.x + NETWORK_OFFSET * normal.x, pt.y + NETWORK_OFFSET * normal.y, 0, normal.x, normal.y, 0, localDepth, 1);
            pushVertex(mesh, pt.x, pt.y, 1, 0, 0, 1, localDepth, innerSampleOffsetFactor);
            pushVertex(mesh, centerSample.x, centerSample.y, 1, 0, 0, 1, localDepth, 0);
            pushVertex(mesh, otherPt.x, otherPt.y, 1, 0, 0, 1, localDepth, innerSampleOffsetFactor);
            pushVertex(mesh, otherPt.x + NETWORK_OFFSET * otherNormal.x, otherPt.y + NETWORK_OFFSET * otherNormal.y, 0, otherNormal.x, otherNormal.y, 0, localDepth, 1);

            if(i > 0) {
                int offset = splineOffset + 5 * i;

                for(int j=0; j<4; ++j) {
                     mesh.addTriangle(offset + j, offset - 5 + j, offset - 4 + j);
                     mesh.addTriangle(offset + j, offset + 1 + j, offset - 4 + j);
                }
            }
        }
    }
    else
        pushSeparateNode(mesh, position, nodeRadius);
}
Beispiel #7
0
void BGGraphics::pushTripleConnectedNode(ofMesh& mesh, ofVec2f position, ofVec2f startEdgePoint, ofVec2f endEdgePoint1, ofVec2f endEdgePoint2) {
 
    ofVec2f orderedPts[3] = {
        startEdgePoint,
        endEdgePoint1,
        endEdgePoint2
    };

    /*
    ofMesh centerTriangleMesh;
    centerTriangleMesh.setMode(OF_PRIMITIVE_TRIANGLE_FAN);
    ofVec2f centerTriangleTexPt = calculateInternalTexOffset(0.5, true, true, -1);
    pushVertex(centerTriangleMesh, position.x, position.y, 1, 0, 0, 1, centerTriangleTexPt.x, centerTriangleTexPt.y);
    */

    ofVec2f sumCenterPosition(0,0);

    int centerIndices[9];

    int halfSamples = 8;
    for(int idx=0; idx<3; ++idx) {

        int prevIdx = idx == 0 ? 2 : (idx - 1);
        int nextIdx = (idx + 1) % 3;

        //ofVec2f focus1 = focusPts[idx];
        //ofVec2f focus2 = focusPts[prevIdx];

        for(int i=0; i<halfSamples; ++i) {

            float t = .5 * i / (float)(halfSamples - 1);

            ofVec2f pt1, normal1, pt2, normal2;
            sampleSpline(orderedPts[idx], position, orderedPts[nextIdx], t, pt1, normal1);
            sampleSpline(orderedPts[idx], position, orderedPts[prevIdx], t, pt2, normal2);
            normal2 = -normal2;

            ofVec2f center = (pt1 + pt2) / 2.0;

            /*
            float offAngle1 = focusAngles[idx] + t * deltaAngle;
            ofVec2f offVector1 = ofVec2f(cosf(offAngle1), sinf(offAngle1));
            float offAngle2 = focusAngles[prevIdx] + (1. - t) * deltaAngle;
            ofVec2f offVector2 = ofVec2f(cosf(offAngle2), sinf(offAngle2));
            */

            //ofVec2f BGGraphics::calculateInternalTexOffset(float t, bool isSourceSpline, int offsetIndex)

            bool isSourceSegment = idx == 0;
            bool isSourceSpline1 = true, isSourceSpline2 = true;
            float t1 = t, t2 = t;

            if(idx == 1) {
                isSourceSpline1 = false;
                t2 = 1. - t;
            }
            else if(idx == 2) {
                //mirrored version of idx == 1
                isSourceSpline2 = false;
                t1 = 1. - t;
            }


            ofVec2f centerTexPt = calculateInternalTexOffset(t1, isSourceSpline1, isSourceSegment, 0);
            ofVec2f innerTexPt1 = calculateInternalTexOffset(t1, isSourceSpline1, isSourceSegment, 1);
            ofVec2f outerTexPt1 = calculateInternalTexOffset(t1, isSourceSpline1, isSourceSegment, 2);
            ofVec2f innerTexPt2 = calculateInternalTexOffset(t2, isSourceSpline2, isSourceSegment, 1);
            ofVec2f outerTexPt2 = calculateInternalTexOffset(t2, isSourceSpline2, isSourceSegment, 2);

            //TODO: remove!!
            //centerTexPt = (innerTexPt1 + innerTexPt2) / 2.0;

            //innerTexPt2 = ofVec2f(-10000,-10000);
            //outerTexPt2 = innerTexPt2;

            /*
            ofVec2f innerTexPt1 = focus1 + baseSize * offVector1;
            ofVec2f outerTexPt1 = focus1 + .5 * baseSize * offVector1;
            ofVec2f innerTexPt2 = focus2 + baseSize * offVector2;
            ofVec2f outerTexPt2 = focus2 + .5 * baseSize * offVector2;
            ofVec2f centerTexPt = (innerTexPt1 + innerTexPt2) / 2.0;
            */

            pushVertex(mesh, pt1.x + NETWORK_OFFSET * normal1.x, pt1.y + NETWORK_OFFSET * normal1.y, 0, normal1.x, normal1.y, 0, outerTexPt1.x, outerTexPt1.y);
            pushVertex(mesh, pt1.x, pt1.y, 1, 0, 0, 1, innerTexPt1.x, innerTexPt1.y);
            pushVertex(mesh, center.x, center.y, 1, 0, 0, 1, centerTexPt.x, centerTexPt.y);
            pushVertex(mesh, pt2.x, pt2.y, 1, 0, 0, 1, innerTexPt2.x, innerTexPt2.y);
            pushVertex(mesh, pt2.x + NETWORK_OFFSET * normal2.x, pt2.y + NETWORK_OFFSET * normal2.y, 0, normal2.x, normal2.y, 0, outerTexPt2.x, outerTexPt2.y);

            if(i > 0) {
                int offset = (5 * idx * halfSamples) + 5 * i;
                for(int j=0; j<4; ++j) {
                    mesh.addTriangle(offset + j, offset - 5 + j, offset - 4 + j);
                    mesh.addTriangle(offset + j, offset + 1 + j, offset - 4 + j);
                }

                if(i == halfSamples - 1) {
                    sumCenterPosition += pt1;
                    for(int j=0; j<3; ++j) {
                        centerIndices[3 * idx + j] = offset + 1 + j;
                    }
                }
            }
        }
    }

    //add center point:
    ofVec2f avgCenter = sumCenterPosition / 3.0;
    ofVec2f centerTriangleTexPt = calculateInternalTexOffset(0.5, true, true, -1);
    pushVertex(mesh, avgCenter.x, avgCenter.y, 1, 0, 0, 1, centerTriangleTexPt.x, centerTriangleTexPt.y);

    //stitch to bounds:
    int centerOffset = mesh.getVertices().size() - 1;
    for(int i=0; i<9; ++i)
         mesh.addTriangle(centerOffset, centerIndices[i], centerIndices[(i + 1) % 9]);


    //centerTriangleMesh.setVertex(0, ofVec3f(avgCenter.x, avgCenter.y, 1));

    /*
    ofVec2f avgCenter = sumCenterPosition / 3.0;
    centerTriangleMesh.setVertex(0, ofVec3f(avgCenter.x, avgCenter.y, 1));

    //stitch up center triangle fan:
    centerTriangleMesh.addVertex(centerTriangleMesh.getVertex(1));
    centerTriangleMesh.addTexCoord(centerTriangleMesh.getTexCoord(1));
    centerTriangleMesh.addNormal(centerTriangleMesh.getNormal(1));
    centerTriangleMesh.addColor(centerTriangleMesh.getColor(1));

    drawMesh(centerTriangleMesh, depth);
    */
}