Exemple #1
0
static void
display(void)
{
#ifdef _WIN32
  LARGE_INTEGER t1, t2, freq;
  QueryPerformanceCounter(&t1);
#else
  struct timespec t1, t2;
  clock_gettime(CLOCK_MONOTONIC, &t1);
#endif
  glClear(GL_COLOR_BUFFER_BIT);
  if (draw_normal) {
    triangle_normal();
  } else {
    triangle_normal();
  }
  glFinish();
#ifdef _WIN32
  QueryPerformanceCounter(&t2);
  QueryPerformanceFrequency(&freq);
  printf("one frame: %lf.\n",
         (double)(t2.QuadPart - t1.QuadPart) / freq.QuadPart);
#else
  clock_gettime(CLOCK_MONOTONIC, &t2);
  printf("one frame: %lf.\n", ((double)(t2.tv_sec - t1.tv_sec) +
                               ((double)(t2.tv_nsec - t1.tv_nsec) / 1e9)));
#endif
  checkError("display");
}
void shape_smooth_frames(Shape* shape) {
    if(is<TriangleMesh>(shape)) {
        auto mesh = cast<TriangleMesh>(shape);
        mesh->norm.resize(mesh->pos.size(),zero3f);
        for(auto f : mesh->triangle) for(auto vid : f) mesh->norm[vid] += triangle_normal(mesh->pos[f.x],mesh->pos[f.y],mesh->pos[f.z]);
        for(auto &n : mesh->norm) n = normalize(n);
    }
    else if(is<Mesh>(shape)) {
        auto mesh = cast<Mesh>(shape);
        mesh->norm.resize(mesh->pos.size(),zero3f);
        for(auto f : mesh->triangle) for(auto vid : f) mesh->norm[vid] += triangle_normal(mesh->pos[f.x],mesh->pos[f.y],mesh->pos[f.z]);
        for(auto f : mesh->quad) for(auto vid : f) mesh->norm[vid] += quad_normal(mesh->pos[f.x],mesh->pos[f.y],mesh->pos[f.z],mesh->pos[f.w]);
        for(auto &n : mesh->norm) n = normalize(n);
    }
}
Exemple #3
0
void MxPropSlim::discontinuity_constraint(MxVertexID i, MxVertexID j, MxFaceID f)
{
	Vec3 org(m->vertex(i)), dest(m->vertex(j));
	Vec3 e = dest - org;

	Vec3 v1(m->vertex(m->face(f)(0)));
	Vec3 v2(m->vertex(m->face(f)(1)));
	Vec3 v3(m->vertex(m->face(f)(2)));
	Vec3 n = triangle_normal(v1,v2,v3);

	Vec3 n2 = e ^ n;
	unitize(n2);

	MxQuadric3 Q3(n2, -(n2*org));
	Q3 *= boundary_weight;

	if( weighting_policy == MX_WEIGHT_AREA ||
		weighting_policy == MX_WEIGHT_AREA_AVG )
	{
		Q3.set_area(norm2(e));
		Q3 *= Q3.area();
	}

	MxQuadric Q(Q3, dim());

	quadric(i) += Q;
	quadric(j) += Q;
}
Exemple #4
0
void prepare_gravity(Real_t nv[], Real_t rij[], Real_t cm[], int numfaces, std::vector<unsigned int>& fi, std::vector<float>& ev)
{
	for(int i = 0; i < numfaces; i++)
	{
		double a[3], b[3], c[3], d[3], nu[3];

		int ain = fi[i*3+0];
		int bin = fi[i*3+1];
		int cin = fi[i*3+2];
		
		a[0] = ev[ain*3+0];
		a[1] = ev[ain*3+1];
		a[2] = ev[ain*3+2];
		
		b[0] = ev[bin*3+0];
		b[1] = ev[bin*3+1];
		b[2] = ev[bin*3+2];
		
		c[0] = ev[cin*3+0];
		c[1] = ev[cin*3+1];
		c[2] = ev[cin*3+2];
		
		d[0] = (a[0]+b[0]+c[0])/3.0;
		d[1] = (a[1]+b[1]+c[1])/3.0;
		d[2] = (a[2]+b[2]+c[2])/3.0;
		
		// face center
		cm[i*3+0] = d[0];
		cm[i*3+1] = d[1];
		cm[i*3+2] = d[2];
		
		triangle_normal(a, b, c, nu);
		
		nv[i*3+0] = nu[0];
		nv[i*3+1] = nu[1];
		nv[i*3+2] = nu[2];

		rij[(i*4+0)*3+0] = a[0];
		rij[(i*4+0)*3+1] = a[1];
		rij[(i*4+0)*3+2] = a[2];

		rij[(i*4+1)*3+0] = b[0];
		rij[(i*4+1)*3+1] = b[1];
		rij[(i*4+1)*3+2] = b[2];

		rij[(i*4+2)*3+0] = c[0];
		rij[(i*4+2)*3+1] = c[1];
		rij[(i*4+2)*3+2] = c[2];

		rij[(i*4+3)*3+0] = a[0];
		rij[(i*4+3)*3+1] = a[1];
		rij[(i*4+3)*3+2] = a[2];
	}
}
frame3f trianglemesh_frame(TriangleMesh* mesh, int elementid, const vec2f& uv) {
    auto f = mesh->triangle[elementid];
    frame3f ff;
    ff.x = normalize(mesh->pos[f.y]-mesh->pos[f.x]);
    ff.y = normalize(mesh->pos[f.z]-mesh->pos[f.x]);
    if(not mesh->norm.empty()) ff.z = normalize(interpolate_baricentric_triangle(mesh->norm, f, uv));
    else ff.z = triangle_normal(mesh->pos[f.x], mesh->pos[f.y], mesh->pos[f.z]);
    ff.o = interpolate_baricentric_triangle(mesh->pos, f, uv);
    ff = orthonormalize(ff);
    return ff;
}
frame3f mesh_frame(Mesh* mesh, int elementid, const vec2f& uv) {
    auto f = mesh_triangle_face(mesh,elementid);
    frame3f ff;
    ff.x = normalize(mesh->pos[f.y]-mesh->pos[f.x]);
    ff.y = normalize(mesh->pos[f.z]-mesh->pos[f.x]);
    if(not mesh->norm.empty()) ff.z = normalize(interpolate_baricentric_triangle(mesh->norm,f,uv));
    else if(elementid < mesh->triangle.size()) ff.z = triangle_normal(mesh->pos[f.x], mesh->pos[f.y], mesh->pos[f.z]);
    else { auto f = mesh->quad[(elementid-mesh->triangle.size())/2]; ff.z = quad_normal(mesh->pos[f.x], mesh->pos[f.y], mesh->pos[f.z], mesh->pos[f.w]); }
    ff.o = interpolate_baricentric_triangle(mesh->pos,f,uv);
    ff = orthonormalize(ff);
    return ff;
}
void glutils_draw_triangle_lines(const vec3f& v0, const vec3f& v1, const vec3f& v2) {
    glsCheckError();
    glBegin(GL_LINE_LOOP);
    glsNormal(triangle_normal(v0, v1, v2));
    glsTexCoord(zero2f);
    glsVertex(v0);
    glsTexCoord(x2f);
    glsVertex(v1);
    glsTexCoord(y2f);
    glsVertex(v2);
    glEnd();
    glsCheckError();
}
Exemple #8
0
int tri_tet_disjoint(ptriangle tri, ptetra tet) {
  arr3 normals[4];
  /*
   * First check facet normals for separating axes.
   * This covers face-face and face-edge.
   */
  triangle_normal(tri,normals[0]);
  if (tri_tet_separation_axis(tri,tet,normals[0]) == DISJOINT)
    return DISJOINT;

  tetra_normals(tet, normals); 
  if (tri_tet_separation_axes(tri,tet,normals, 4) == DISJOINT)
    return DISJOINT;

  /*
   * Check all cross produts of edges between triangle and tetrahedron as separating axis.
   * This covers edge-edge.
   * 
   * The six edges of a tet are given by edges.
   * Indication how edge 'x' is made up.. for example edge[0] = vertex[1] - vertex[0]
   */
  int edges[6][2] = {{1,0},{2,0},{2,1}, //Base triangle (first three)
    {3,0},{3,1},{3,2}}; //Edges from base to apex
  //Test all the edges
  arr3 edge_a, edge_b;

  for (int i = 0; i < 3; i++) {
    subArr3(tri->vertices[edges[i][0]], tri->vertices[edges[i][1]], edge_a);
    for (int j = 0; j < 6; j++)
    {
      subArr3(tet->vertices[edges[j][0]], tet->vertices[edges[j][1]], edge_b);
      //Check crossproduct of edge_a and edge_b as seperating axis
      arr3 perp_axis;
      crossArr3(edge_a,edge_b, perp_axis);
      if (zeroArr3(perp_axis)) { 
        /*
         * Edges are parallel thus lie in some plane.
         * Calculate another vector in this plane and try the cross product
         * between those vectors as separating axis
         */
        subArr3(tri->vertices[edges[i][0]], tet->vertices[edges[j][0]], edge_b);
        crossArr3(edge_a,edge_b, perp_axis);
        if (zeroArr3(perp_axis)) //Still zero, all points lie on the same line, not a separation axis, IS TRUE?
          continue;
      }     
      if (tri_tet_separation_axis(tri,tet, perp_axis) == DISJOINT)
        return DISJOINT;
    }
  }
  return INTERSECT; //No separation axis found, thus we are not disjoint
}
Exemple #9
0
int triangle_plane( Vec4 *out, const Vec3 *v1, const Vec3 *v2, const Vec3 *v3 )
{
    Vec3 n;
	
	if( !triangle_normal( &n, v1, v2, v3 ) )
		return 0;

	out->elt[0] = n.elt[0];
	out->elt[1] = n.elt[1];
	out->elt[2] = n.elt[2];
	out->elt[3] = -( mxv_dot(n.elt, v1->elt, 3) );
	return 1;

} /* end function triangle_plane */
Exemple #10
0
int in_triangle(Point point, Triangle tri)
{
	/* This implementation is based on "Graphics Gems" p390 */
	int i1, i2;
	Normal norm;
	float u0, v0, u1, v1, u2, v2;
	float alpha, beta;
	int inter = 0;

	triangle_normal(tri, &norm);
	if(fabs(norm[0]) >= fabs(norm[1]) && fabs(norm[0]) >= fabs(norm[2])) {
		i1 = 1; i2 = 2;
	}else if(fabs(norm[1]) >= fabs(norm[0]) && fabs(norm[1]) >= fabs(norm[2])) {
		i1 = 0; i2 = 2;
	}else {
		i1 = 0; i2 = 1;
	}
	u0 = point[i1] - tri.vert[0][i1];
	v0 = point[i2] - tri.vert[0][i2];
	u1 = tri.vert[1][i1] - tri.vert[0][i1];
	v1 = tri.vert[1][i2] - tri.vert[0][i2];
	u2 = tri.vert[2][i1] - tri.vert[0][i1];
	v2 = tri.vert[2][i2] - tri.vert[0][i2];

    if(u1 == 0) {
        beta = u0/u2;
        if((beta >= 0.) && (beta <= 1.)) {
            alpha = (v0 - beta*v2)/v1;
            inter = ((alpha >= 0.) && ((alpha+beta) <= 1.))? 1:0;
        }
    } else {
        beta = (v0*u1 - u0*v1)/(v2*u1 - u2*v1);
        if ((beta >= 0.)&&(beta <= 1.)) {
            alpha = (u0 - beta*u2)/u1;
            inter = ((alpha >= 0) && ((alpha+beta) <= 1.))? 1:0;
        }
    }

	return inter;
}
Exemple #11
0
static void
triangle(void)
{
  GLint tmpFramebuffer;
  GLint tmpRenderbuffer;
  GLint viewport[4];
  GLenum err;

  checkError("triangle enter");
  glGetIntegerv(GL_VIEWPORT, viewport);
  glGenFramebuffers(1, (GLuint*)&tmpFramebuffer);
  glGenRenderbuffers(1, (GLuint*)&tmpRenderbuffer);
  glBindFramebuffer(GL_FRAMEBUFFER, tmpFramebuffer);
  glBindRenderbuffer(GL_RENDERBUFFER, tmpRenderbuffer);
  glRenderbufferStorageMultisample(GL_RENDERBUFFER, 16, GL_RGBA, viewport[2],
                                   viewport[3]);
  err = glGetError();
  if (err != GL_NO_ERROR) {
    fprintf(stderr, "error occurs: %X.\n", err);
    exit(1);
  }
  glBindRenderbuffer(GL_RENDERBUFFER, 0);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                            GL_RENDERBUFFER, tmpRenderbuffer);
  if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
    fprintf(stderr, "fbo is not completed.\n");
    exit(1);
  }
  triangle_normal();
  glBindFramebuffer(GL_FRAMEBUFFER, 0);
  // blit here
  glBindFramebuffer(GL_READ_FRAMEBUFFER, tmpFramebuffer);
  glBlitFramebuffer(0, 0, viewport[2], viewport[3], 0, 0, viewport[2],
                    viewport[3], GL_COLOR_BUFFER_BIT, GL_LINEAR);
  glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
  glDeleteFramebuffers(1, (GLuint*)&tmpFramebuffer);
  glDeleteRenderbuffers(1, (GLuint*)&tmpRenderbuffer);
  checkError("triangle");
}
Exemple #12
0
static void append_triangles(struct groupdata *groupdata, buffer *buffer)
{
    triangle *triangles = buffer_data(buffer);
    size_t trianglecount = buffer_count(buffer, sizeof(struct triangle));

    for (size_t i = 0; i < trianglecount; ++i)
    {
        vec3 normal;

        triangle_normal(&normal, &triangles[i]);
        vec3_normalize(&normal, &normal);

        vertex vertices[3] =
        {
            {normal, triangles[i].a},
            {normal, triangles[i].b},
            {normal, triangles[i].c}
        };

        append_buffer(groupdata->vertices, vertices, sizeof(vertices));
    }
}
Exemple #13
0
float intersect_triangle(iRay ray, Triangle tri, Point point)
{
	Normal norm;			/* triangle normal */
	float t, fz, fm;
	int i;
	triangle_normal(tri, &norm);
	fz = 0; fm = 0;
	for (i = 0; i < 3; i++) {
		fz += norm[i] * (tri.vert[0][i]-ray.orig[i]);
		fm += norm[i] * ray.dir[i];
	}
	if(fm == 0.0) return -1;
	t = fz / fm;
	/* don't consider negative parameter any more */
	if(t < 0.0) return t;
	for(i = 0; i < 3; i++) point[i] = ray.orig[i] + ray.dir[i] * t;
#ifdef _DEBUG
	printf("intersection point: (%f, %f, %f)\n", 
			point[0], point[1], point[2]);
#endif
	if(in_triangle(point, tri)) return t;
	return -1;
}
Exemple #14
0
bool EdgeCollapser::collapse_edge_introduces_normal_inversion( size_t source_vertex,
        size_t destination_vertex,
        size_t edge_index,
        const Vec3d& vertex_new_position )
{

    // Get the set of triangles which are going to be deleted
    std::vector< size_t >& triangles_incident_to_edge = m_surf.m_mesh.m_edge_to_triangle_map[edge_index];

    // Get the set of triangles which move because of this motion
    std::vector<size_t> moving_triangles;
    for ( size_t i = 0; i < m_surf.m_mesh.m_vertex_to_triangle_map[source_vertex].size(); ++i )
    {
        moving_triangles.push_back( m_surf.m_mesh.m_vertex_to_triangle_map[source_vertex][i] );
    }
    for ( size_t i = 0; i < m_surf.m_mesh.m_vertex_to_triangle_map[destination_vertex].size(); ++i )
    {
        moving_triangles.push_back( m_surf.m_mesh.m_vertex_to_triangle_map[destination_vertex][i] );
    }

    //
    // check for normal inversion
    //

    for ( size_t i = 0; i < moving_triangles.size(); ++i )
    {

        // Disregard triangles which will end up being deleted - those triangles incident to the collapsing edge.
        bool triangle_will_be_deleted = false;
        for ( size_t j = 0; j < triangles_incident_to_edge.size(); ++j )
        {
            if ( moving_triangles[i] == triangles_incident_to_edge[j] )
            {
                triangle_will_be_deleted = true;
                break;
            }
        }

        if ( triangle_will_be_deleted ) {
            continue;
        }

        const Vec3st& current_triangle = m_surf.m_mesh.get_triangle( moving_triangles[i] );
        Vec3d old_normal = m_surf.get_triangle_normal( current_triangle );

        Vec3d new_normal;

        double new_area;
        if ( current_triangle[0] == source_vertex || current_triangle[0] == destination_vertex )
        {
            new_normal = triangle_normal( vertex_new_position, m_surf.get_position(current_triangle[1]), m_surf.get_position(current_triangle[2]) );
            new_area = triangle_area( vertex_new_position, m_surf.get_position(current_triangle[1]), m_surf.get_position(current_triangle[2]) );
        }
        else if ( current_triangle[1] == source_vertex || current_triangle[1] == destination_vertex )
        {
            new_normal = triangle_normal( m_surf.get_position(current_triangle[0]), vertex_new_position, m_surf.get_position(current_triangle[2]) );
            new_area = triangle_area( m_surf.get_position(current_triangle[0]), vertex_new_position, m_surf.get_position(current_triangle[2]) );
        }
        else
        {
            assert( current_triangle[2] == source_vertex || current_triangle[2] == destination_vertex );
            new_normal = triangle_normal( m_surf.get_position(current_triangle[0]), m_surf.get_position(current_triangle[1]), vertex_new_position );
            new_area = triangle_area( m_surf.get_position(current_triangle[0]), m_surf.get_position(current_triangle[1]), vertex_new_position );
        }

        if ( dot( new_normal, old_normal ) < 1e-5 )
        {
            if ( m_surf.m_verbose ) {
                std::cout << "collapse edge introduces normal inversion" << std::endl;
            }

            g_stats.add_to_int( "EdgeCollapser:collapse_normal_inversion", 1 );

            return true;
        }

        if ( new_area < m_surf.m_min_triangle_area )
        {
            if ( m_surf.m_verbose ) {
                std::cout << "collapse edge introduces tiny triangle area" << std::endl;
            }

            g_stats.add_to_int( "EdgeCollapser:collapse_degenerate_triangle", 1 );

            return true;
        }

    }

    return false;

}
Exemple #15
0
/* create a smoothed version of the given Object
   by computing average normal vectors for the vertexes 
*/
static ObjectSmooth *create_ObjectSmooth( Object *obj )
{
  int t, v, i;
  Vector *t_normal = 
      (Vector *) malloc( obj->num_triangle*sizeof(Vector) );
  ObjectSmooth *ret = 
      (ObjectSmooth *) malloc( sizeof( ObjectSmooth ) );
  
  /* fill in vertexes and triangles */
  ret->num_vertex = obj->num_vertex;
  ret->num_triangle = obj->num_triangle;
  ret->vertex = 
      (Vector *) malloc( obj->num_vertex * sizeof( Vector ) );
  ret->normal = 
      (Vector *) malloc( obj->num_vertex * sizeof( Vector ) );
  ret->triangle = 
      (Triangle *) malloc( obj->num_triangle * sizeof( Triangle ) );
  
  for (v=0; v<obj->num_vertex; ++v) {
    ret->vertex[v] = obj->vertex[v];
  }
  
  for (t=0; t<obj->num_triangle; ++t) {
    ret->triangle[t] = obj->triangle[t];
  }
  
  /* create normals (triangles) */
  for (t=0; t<ret->num_triangle; ++t) {
    triangle_normal( &ret->vertex[ret->triangle[t].i[0]],
                     &ret->vertex[ret->triangle[t].i[1]],
                     &ret->vertex[ret->triangle[t].i[2]],
                     &t_normal[t] );
  }
  
  /* create normals (vertex) by averaging triangle 
     normals at vertex
  */
  for (v=0; v<ret->num_vertex; ++v) {
    vector_clear( &ret->normal[v] );
    for (t=0; t<ret->num_triangle; ++t) {
      for (i=0; i<3; ++i) {
        if (ret->triangle[t].i[i] == v) {
          vector_add( &ret->normal[v], &t_normal[t] );
        }
      }
    }
    /* as we have only a half sphere we force the
       normals at the bortder to be perpendicular to z.
       the simple algorithm above makes an error here.
    */
    if (fabs(ret->vertex[v].z) < 0.0001) {
      ret->normal[v].z = 0.0;
    }  
    
    vector_normalize( &ret->normal[v] );
  }
  
  free( t_normal );
  
  return ret;
}