Skip to content

Instantly share code, notes, and snippets.

@haldean
Created March 8, 2012 05:35

Revisions

  1. haldean created this gist Mar 8, 2012.
    103 changes: 103 additions & 0 deletions gistfile1.m
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,103 @@
    - (Mesh)generateMesh {
    int numRings = [spine count];

    /* Triangles in the cylinder */
    int triCount = 2 * (numRings - 1) * SEGMENTS_IN_CIRCLE;
    /* Triangles in flat end cap (m - 2 triangles required for an m-gon) */
    triCount += 2 * SEGMENTS_IN_CIRCLE - 4;

    Mesh* result = (Mesh*) malloc(sizeof(Mesh));
    /* 3 verteces for each triangle */
    result->size = triCount * 3;
    /* 6 floats for each triangle (3 for position, 3 for normal) */
    result->data = (GLfloat*) malloc(result->size * 6);

    int dataidx = 0;

    Vec3 **points = (Vec3**) malloc(numRings * sizeof(Vec3*));
    Vec3 **normals = (Vec3**) malloc(numRings * sizeof(Vec3*));
    for (int i = 0; i < numRings; i++) {
    points[i] = (Vec3*) malloc((SEGMENTS_IN_CIRCLE) * sizeof(Vec3));
    normals[i] = (Vec3*) malloc((SEGMENTS_IN_CIRCLE) * sizeof(Vec3));
    }

    for (int i = 0; i < numRings; i++) {
    CGPoint cgSpinePoint = [[spine objectAtIndex:i] CGPointValue];
    Vec2 derivative2d = [self derivativeAtSpineIndex:i];
    Vec3 spinePoint(cgSpinePoint.x, cgSpinePoint.y, 0),
    derivative(derivative2d.x(), derivative2d.y(), 0),
    radius(-derivative2d.y(), derivative2d.x(), 0);

    radius *= [[radii objectAtIndex:i] doubleValue];
    for (int j = 0; j < SEGMENTS_IN_CIRCLE; j++) {
    Vec3 surfacePoint;
    if (j == 0) surfacePoint = radius;
    else {
    float theta = (float) j * 2 * M_PI / (float) SEGMENTS_IN_CIRCLE;
    AngleAxis<float> rot(theta, derivative);
    surfacePoint = rot * radius;
    }
    points[i][j] = surfacePoint + spinePoint;
    normals[i][j] = surfacePoint;
    normals[i][j].normalize();
    }
    }

    /* Generate tube */
    for (int i = 0; i < numRings - 1; i++) {
    Vec3 *ring1 = points[i];
    Vec3 *norms1 = normals[i];
    Vec3 *ring2 = points[i+1];
    Vec3 *norms2 = normals[i+1];

    for (int j = 0; j < SEGMENTS_IN_CIRCLE; j++) {
    VecX v1(6), v2(6), v3(6), v4(6);

    v1.segment(0, 3) = ring1[j]; v1.segment(3, 3) = norms1[j];
    v2.segment(0, 3) = ring2[j]; v2.segment(3, 3) = norms2[j];

    int adjacent = j == 0 ? SEGMENTS_IN_CIRCLE - 1 : j - 1;
    v3.segment(0, 3) = ring1[adjacent]; v3.segment(3, 3) = norms1[adjacent];
    v4.segment(0, 3) = ring2[adjacent]; v4.segment(3, 3) = norms2[adjacent];

    /* triangle 123 */
    for (int k = 0; k < 6; k++, dataidx++) result->data[dataidx] = v1[k];
    for (int k = 0; k < 6; k++, dataidx++) result->data[dataidx] = v2[k];
    for (int k = 0; k < 6; k++, dataidx++) result->data[dataidx] = v3[k];

    /* triangle 234 */
    for (int k = 0; k < 6; k++, dataidx++) result->data[dataidx] = v2[k];
    for (int k = 0; k < 6; k++, dataidx++) result->data[dataidx] = v3[k];
    for (int k = 0; k < 6; k++, dataidx++) result->data[dataidx] = v4[k];
    }
    }

    /* Flat end caps. This for loop is a bit hacky -- k will be either 0 or
    * numRings - 1, and therefore will act on the first and last ring. */
    for (int k = 0; k < numRings; k += numRings - 1) {
    Vec3 *ring = points[k], *norm = normals[k];
    for (int t = 1; t < SEGMENTS_IN_CIRCLE - 1; t++) {
    for (int i = 0; i < 3; i++, dataidx++) result->data[dataidx] = ring[0][i];
    for (int i = 0; i < 3; i++, dataidx++) result->data[dataidx] = norm[0][i];
    for (int i = 0; i < 3; i++, dataidx++) result->data[dataidx] = ring[t][i];
    for (int i = 0; i < 3; i++, dataidx++) result->data[dataidx] = norm[t][i];
    for (int i = 0; i < 3; i++, dataidx++) result->data[dataidx] = ring[t+1][i];
    for (int i = 0; i < 3; i++, dataidx++) result->data[dataidx] = norm[t+1][i];
    }
    }

    for (int i = 0; i < numRings; i++) {
    free(points[i]); free(normals[i]);
    }
    free(points); free(normals);

    NSLog(@"Points:"); // This is the line that BAD_ACCESS's.
    for (int i = 0; i < 4; i++) {
    NSLog(@"v %f %f %f, n %f %f %f",
    result->data[i*6+0], result->data[i*6+1], result->data[i*6+2],
    result->data[i*6+3], result->data[i*6+4], result->data[i*6+5]);
    }
    NSLog(@"...");

    return *result;
    }