Skip to content

Instantly share code, notes, and snippets.

@haldean
Created March 8, 2012 05:35
Show Gist options
  • Save haldean/1998932 to your computer and use it in GitHub Desktop.
Save haldean/1998932 to your computer and use it in GitHub Desktop.
Mesh generation with memory error
- (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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment