Exemple #1
0
//--
//
// ComputeFaceNormals
//
//--
// Compute unit normal of every faces
void Mesh::ComputeFaceNormals()
{
	// Resize face normal array
	face_normals.resize( FaceNumber() );

	// For every face
	for( int i=0; i<FaceNumber(); i++ )
	{
		// Compute unit face normal
		FaceNormal(i) = ComputeFaceNormal(i);
	}
}
Exemple #2
0
CTriangle::CTriangle	(CPoint3D pos, CColor col, CPoint3D pptVertices[3]) : CShape (pos, col)
{
	m_pptVertices[0] = pptVertices[0];
	m_pptVertices[1] = pptVertices[1];
	m_pptVertices[2] = pptVertices[2];

	m_eNormalMode = FACE_NORMAL;
	
	// VVIMP - do not forget this step!
	ComputeFaceNormal();
	
	m_pShader = 0;
}
Exemple #3
0
void CTriangle::Init (CPoint3D pos, CColor col, CPoint3D pptVertices[3])
{
    objColor = col;
    m_ptPosition = pos;
    
	m_pptVertices[0] = pptVertices[0];
	m_pptVertices[1] = pptVertices[1];
	m_pptVertices[2] = pptVertices[2];
   
	m_eNormalMode = FACE_NORMAL;
	
	// VVIMP - do not forget this step!
	ComputeFaceNormal();
    
	m_pShader = 0;
}
Exemple #4
0
GLuint HalfEdgeModel::CreateTriangleDisplayList( unsigned int flags )
{
	bool normals =    (flags & WITH_NORMALS) > 0;
	bool facetNorms = (flags & WITH_FACET_NORMALS) > 0;
	bool failure = false;
	float facetNorm[3];
	Solid *sobj = (Solid *)solid;
	GLuint list = glGenLists( 1 );
	glNewList( list, GL_COMPILE );

	glBegin( GL_TRIANGLES );
	Face *currFace = sobj->sfaces;
	for ( ; currFace; ) 
	{
		Loop *loop   = currFace->floop;
		if (!loop) { failure=true; break; }
		HalfEdge *he1 = loop->ledges;
		if (!he1) { failure=true; break; }
		HalfEdge *he2 = he1->next;
		if (!he2) { failure=true; break; }
		HalfEdge *he3 = he2->next;
		if (!he3) { failure=true; break; }
		if (facetNorms)
		{
			ComputeFaceNormal( facetNorm, (void *)(loop->lface) );	
			glNormal3fv( facetNorm );
		}
		if (normals) glNormal3dv( he1->hvert->ncoord );
		glVertex3dv( he1->hvert->vcoord );
		if (normals) glNormal3dv( he2->hvert->ncoord );
		glVertex3dv( he2->hvert->vcoord );
		if (normals) glNormal3dv( he3->hvert->ncoord );
		glVertex3dv( he3->hvert->vcoord );
		currFace = currFace->next;
		if (!currFace || currFace == sobj->sfaces) break;
	}
	glEnd();
	glEndList();

	if (failure)
	{
		glDeleteLists( list, 1 );
		return 0;
	}

	return (triList = list);
}
Exemple #5
0
GLuint HalfEdgeModel::CreateTriangleAdjacencyDisplayList( unsigned int flags )
{
	bool normals =    (flags & WITH_NORMALS) > 0;
	bool facetNorms = (flags & WITH_FACET_NORMALS) > 0;
	bool failure = false;
	float centralFacetNorm[3], extFacetNorm[3];
	Solid *sobj = (Solid *)solid;
	GLuint list = glGenLists( 1 );
	glNewList( list, GL_COMPILE );

	glBegin( GL_TRIANGLES_ADJACENCY_EXT );
	Face *currFace = sobj->sfaces;
	for ( ; currFace; ) 
	{
		Loop *loop   = currFace->floop;
		if (!loop) { failure=true; break; }
		HalfEdge *he1 = loop->ledges;
		if (!he1) { failure=true; break; }
		HalfEdge *he2 = he1->next;
		if (!he2) { failure=true; break; }
		HalfEdge *he3 = he2->next;
		if (!he3) { failure=true; break; }
		/* vertex 1 */
		if (facetNorms)
		{
			ComputeFaceNormal( centralFacetNorm, (void *)(loop->lface) );	
			glNormal3fv( centralFacetNorm );
		}
		if (normals) glNormal3dv( he1->hvert->ncoord );
		glVertex3dv( he1->hvert->vcoord );

		/* vertex 2 */
		HalfEdge *ext = (he1->hedge->he1 == he1) ? he1->hedge->he2 : he1->hedge->he1;
		if (ext)
		{
			ext = ext->prev;
			if (facetNorms)
			{
				ComputeFaceNormal( extFacetNorm, (void *)(ext->hloop->lface) );	
				glNormal3fv( extFacetNorm );
			}
			if (normals) glNormal3dv( ext->hvert->ncoord );
			glVertex3dv( ext->hvert->vcoord );
		}
		else
		{ 
			if (normals || facetNorms) glNormal3d( 0, 0, 0 ); 
			glVertex3d( 0, 0, 0 ); 
		}

		/* vertex 3 */
		if (facetNorms) glNormal3fv( centralFacetNorm );
		if (normals) glNormal3dv( he2->hvert->ncoord );
		glVertex3dv( he2->hvert->vcoord );

		/* vertex 4 */
		ext = (he3->hedge->he1 == he3) ? he3->hedge->he2 : he3->hedge->he1;
		if (ext)
		{
			ext = ext->prev;
			if (facetNorms)
			{
				ComputeFaceNormal( extFacetNorm, (void *)(ext->hloop->lface) );	
				glNormal3fv( extFacetNorm );
			}
			if (normals) glNormal3dv( ext->hvert->ncoord );
			glVertex3dv( ext->hvert->vcoord );
		}
		else
		{ 
			if (normals || facetNorms) glNormal3d( 0, 0, 0 ); 
			glVertex3d( 0, 0, 0 ); 
		}

		/* vertex 5 */
		if (facetNorms) glNormal3fv( centralFacetNorm );
		if (normals) glNormal3dv( he3->hvert->ncoord );
		glVertex3dv( he3->hvert->vcoord );

		/* vertex 6 */
		ext = (he2->hedge->he1 == he2) ? he2->hedge->he2 : he2->hedge->he1;
		if (ext)
		{
			ext = ext->prev;
			if (facetNorms)
			{
				ComputeFaceNormal( extFacetNorm, (void *)(ext->hloop->lface) );	
				glNormal3fv( extFacetNorm );
			}
			if (normals) glNormal3dv( ext->hvert->ncoord );
			glVertex3dv( ext->hvert->vcoord );
		}
		else
		{ 
			if (normals || facetNorms) glNormal3d( 0, 0, 0 ); 
			glVertex3d( 0, 0, 0 ); 
		}

		currFace = currFace->next;
		if (!currFace || currFace == sobj->sfaces) break;
	}
	glEnd();

	glEndList();

	if (failure)
	{
		glDeleteLists( list, 1 );
		return 0;
	}

	return (adjList = list);
}
Exemple #6
0
GLuint HalfEdgeModel::CreateEdgeDisplayList( unsigned int flags )
{
	bool normals =    (flags & WITH_NORMALS) > 0;
	bool facetNorms = (flags & WITH_ADJACENT_FACE_NORMS) > 0;
	bool failure = false;
	float fnorm1[3], fnorm2[3];
	Solid *sobj = (Solid *)solid;
	GLuint list = glGenLists( 1 );
	glNewList( list, GL_COMPILE );


	glBegin( GL_LINES );
	Edge *currEdge = sobj->sedges;
	for ( ; currEdge; ) 
	{
		
		if( !currEdge->he1 && !currEdge->he2)
		{
			currEdge = currEdge->next;
			if (!currEdge || currEdge == sobj->sedges) break;
			continue;
		}
		
		if (facetNorms) 
		{
			if(!currEdge->he1)
			{ fnorm1[0] = 0; fnorm1[1] = 0; fnorm1[2] = 0;}
			else
				ComputeFaceNormal( fnorm1, (void *)(currEdge->he1->hloop->lface) );
			if(!currEdge->he2)
			{ fnorm2[0] = 0; fnorm2[1] = 0; fnorm2[2] = 0; }
			else
				ComputeFaceNormal( fnorm2, (void *)(currEdge->he2->hloop->lface) );
			glMultiTexCoord3fv( GL_TEXTURE6, fnorm1 );
			glMultiTexCoord3fv( GL_TEXTURE7, fnorm2 );
		}
		if(!currEdge->he1 || !currEdge->he2)
		{
			HalfEdge *he = currEdge->he1 ? currEdge->he1 : currEdge->he2;
			//only one halfedge was valid.
			if (normals) 
				glNormal3dv( he->hvert->ncoord );
			glVertex3dv( he->hvert->vcoord );
			// the other halfedge is next in the loop
			he = he->next;
			if(!he) 
			{
				printf("Error: Corrupted half-edge loop!\n");
				failure=true;
				break;
			}
			else
			{
				if(normals) glNormal3dv(he->hvert->ncoord);
				glVertex3dv(he->hvert->vcoord);
			}
		}
		else
		{
			if (normals) glNormal3dv( currEdge->he1->hvert->ncoord );
			glVertex3dv( currEdge->he1->hvert->vcoord );
			if (normals) glNormal3dv( currEdge->he2->hvert->ncoord );
			glVertex3dv( currEdge->he2->hvert->vcoord );
		}
		
		currEdge = currEdge->next;
		if (!currEdge || currEdge == sobj->sedges) break;
	}
	glEnd();
	glEndList();

	if (failure)
	{
		glDeleteLists( list, 1 );
		return 0;
	}

	return (edgeList = list);
}
Exemple #7
0
GLuint HalfEdgeModel::CreateEdgeVBO( unsigned int flags )
{
	bool normals =    (flags & WITH_NORMALS) > 0;
	bool facetNorms = (flags & WITH_ADJACENT_FACE_NORMS) > 0;
	bool failure = false;
	float fnorm1[3], fnorm2[3];
	int edgeCount=0;
	Solid *sobj = (Solid *)solid;
	int numComponents = 1 + (normals?1:0) + (facetNorms?2:0);

	// Do this in two passes.  The first checks for validity and counts the number
	//    of edges.  Here's pass 1.
	for ( Edge *currEdge = sobj->sedges; currEdge; ) 
	{
		if( !currEdge->he1 && !currEdge->he2)
		{
			currEdge = currEdge->next;
			if (!currEdge || currEdge == sobj->sedges) break;
			continue;
		}
		if(!currEdge->he1 || !currEdge->he2)
		{
			HalfEdge *he = currEdge->he1 ? currEdge->he1 : currEdge->he2;
			if(!he->next) { failure=true; break; }
		}
		edgeCount++;
		currEdge = currEdge->next;
		if (!currEdge || currEdge == sobj->sedges) break;
	}
	if (failure)
	{
		printf("Unable to create edge VBO.  Corrupted half-edge loop!\n");
		return 0;
	}

	// Allocate enough memory for all the edges
	unsigned int dataSize = edgeCount*6*sizeof(float)*numComponents;
	float *floatData = (float *)malloc( dataSize );
	int currentEdge = 0;
	if (!floatData)
	{
		printf("Unable to allocate temporary memory for edge VBO!\n");
		return 0;
	}

	// Copy data into allocated memory
	for (Edge *currEdge = sobj->sedges; currEdge; ) 
	{
		int vertOff0 = 6*numComponents*currentEdge;
		int vertOff1 = vertOff0+3*numComponents;
		int normOff0 = vertOff0+3;
		int normOff1 = normOff0+3*numComponents;
		int fnormOff0_1 = vertOff0+3+(normals?3:0);
		int fnormOff1_1 = fnormOff0_1+3*numComponents;
		int fnormOff0_2 = fnormOff0_1+3;
		int fnormOff1_2 = fnormOff1_1+3;

		if( !currEdge->he1 && !currEdge->he2)
		{
			currEdge = currEdge->next;
			if (!currEdge || currEdge == sobj->sedges) break;
			continue;
		}
		
		if (facetNorms) 
		{
			if(!currEdge->he1)
				{ fnorm1[0] = 0; fnorm1[1] = 0; fnorm1[2] = 0;}
			else
				ComputeFaceNormal( fnorm1, (void *)(currEdge->he1->hloop->lface) );
			if(!currEdge->he2)
				{ fnorm2[0] = 0; fnorm2[1] = 0; fnorm2[2] = 0; }
			else
				ComputeFaceNormal( fnorm2, (void *)(currEdge->he2->hloop->lface) );
			floatData[fnormOff0_1+0] = fnorm1[0]; floatData[fnormOff0_1+1] = fnorm1[1]; floatData[fnormOff0_1+2] = fnorm1[2]; 
			floatData[fnormOff1_1+0] = fnorm1[0]; floatData[fnormOff1_1+1] = fnorm1[1]; floatData[fnormOff1_1+2] = fnorm1[2]; 
			floatData[fnormOff0_2+0] = fnorm2[0]; floatData[fnormOff0_2+1] = fnorm2[1]; floatData[fnormOff0_2+2] = fnorm2[2]; 
			floatData[fnormOff1_2+0] = fnorm2[0]; floatData[fnormOff1_2+1] = fnorm2[1]; floatData[fnormOff1_2+2] = fnorm2[2];
		}
		if(!currEdge->he1 || !currEdge->he2)
		{
			HalfEdge *he = currEdge->he1 ? currEdge->he1 : currEdge->he2;
			//only one halfedge was valid.
			if (normals) 
				{ floatData[normOff0+0] = he->hvert->ncoord[0]; floatData[normOff0+1] = he->hvert->ncoord[1]; floatData[normOff0+2] = he->hvert->ncoord[2]; }
			floatData[vertOff0+0] = he->hvert->vcoord[0]; floatData[vertOff0+1] = he->hvert->vcoord[1]; floatData[vertOff0+2] = he->hvert->vcoord[2]; 

			// the other halfedge is next in the loop
			he = he->next;
			if (normals) 
				{ floatData[normOff1+0] = he->hvert->ncoord[0]; floatData[normOff1+1] = he->hvert->ncoord[1]; floatData[normOff1+2] = he->hvert->ncoord[2]; }
			floatData[vertOff1+0] = he->hvert->vcoord[0]; floatData[vertOff1+1] = he->hvert->vcoord[1]; floatData[vertOff1+2] = he->hvert->vcoord[2]; 
		}
		else
		{
			HalfEdge *he = currEdge->he1;
			if (normals) 
				{ floatData[normOff0+0] = he->hvert->ncoord[0]; floatData[normOff0+1] = he->hvert->ncoord[1]; floatData[normOff0+2] = he->hvert->ncoord[2]; }
			floatData[vertOff0+0] = he->hvert->vcoord[0]; floatData[vertOff0+1] = he->hvert->vcoord[1]; floatData[vertOff0+2] = he->hvert->vcoord[2]; 

			he = currEdge->he2;
			if (normals) 
				{ floatData[normOff1+0] = he->hvert->ncoord[0]; floatData[normOff1+1] = he->hvert->ncoord[1]; floatData[normOff1+2] = he->hvert->ncoord[2]; }
			floatData[vertOff1+0] = he->hvert->vcoord[0]; floatData[vertOff1+1] = he->hvert->vcoord[1]; floatData[vertOff1+2] = he->hvert->vcoord[2]; 
		}
		
		currentEdge++;
		currEdge = currEdge->next;
		if (!currEdge || currEdge == sobj->sedges) break;
	}

	vboEdgeCount = currentEdge;
	vboEdgeComponents = numComponents;

	if (edgeVBO > 0) glDeleteBuffers( 1, &edgeVBO );
	glGenBuffers( 1, &edgeVBO );
	glBindBuffer( GL_ARRAY_BUFFER, edgeVBO );
	glBufferData( GL_ARRAY_BUFFER, dataSize, floatData, GL_STATIC_DRAW );
	glBindBuffer( GL_ARRAY_BUFFER, 0 );

	free( floatData );

	return edgeVBO;
}
//--
//
// PredictVertex
//
//--
bool MultiresolutionMesh::PredictVertex(int v, VertexType vt)
{
	double coef;
	double weight(0);
	ConstNeighborIterator itv1, itv2;

	// Initialise detail validity
	levels[current_level_number].vertex_types[v] = UNDEFINED_VERTEX;

	//-- Test --
//	tmp_mem = 0;
	//--
	
	// Check border vertex
	if( IsBorderVertex(v) ) return false;

	// For every neighbor vertices
	itv1 = NeighborVertices(v).begin();
	while( itv1 != NeighborVertices(v).end() ) {
		// Check for topological noise
	//	if( NeighborVertexNumber(*itv1) < 4 ) return false;

	
		coef = 0;
		itv2 = NeighborVertices(*itv1).begin();
		while( itv2 != NeighborVertices(*itv1).end() ) {
			if( FindNeighborVertex(v, *itv2) ) {
				if( IsColinear( Vertex(*itv2), Vertex(v), Vertex(*itv1) ) ) return false;
				coef += Cotan( Vertex(*itv2), Vertex(v), Vertex(*itv1) );
			}
			++itv2;
		}
	
		// Laplacian relaxation
	//	coef = 1.0 / (double)NeighborVertexNumber(v);
	
		// Save the current coeff
		levels[current_level_number].subdivision_weights[v].push_back( SubdivisionWeight(*itv1,coef) );

		//-- Test --
		//tmp_mem++;
		//

		// Add current coef to normalization coef
		weight += coef;
		++itv1;
	}
	
	// Sanity check
	if( weight == 0 ) {
		return false;
	}

	// Normalize weights
	weight = 1.0 / weight;
	SubdivisionWeightList::iterator itw = levels[current_level_number].subdivision_weights[v].begin();
	while( itw != levels[current_level_number].subdivision_weights[v].end() ) {
		itw->weight *= weight;
		++itw;
	}

	// Compute predicted vertex position
	Vector3d relax(0,0,0);
	itw = levels[current_level_number].subdivision_weights[v].begin();
	while( itw != levels[current_level_number].subdivision_weights[v].end() ) {
		relax += itw->weight * Vertex(itw->vertex);
		++itw;
	}

	// Compute detail (vertex - subdivided_vertex)
	levels[current_level_number].geometric_details[v] = Vertex(v) - relax;

	//-- Test --
	//tmp_mem++;
	//

	// Sanety check (degenerated detail)
//	if( levels[current_level_number].geometric_details[v].Length() > detail_length_tolerance ) return false;

	// Validate detail
	levels[current_level_number].vertex_types[v] = vt;

	// Create predicted mesh fo geometrical attribute details
	std::swap( Vertex(v), relax );

	// Normal vector detail
	Vector3d relax_normal(0,0,0);
	itv1 = NeighborFaces(v).begin();
	while( itv1 != NeighborFaces(v).end() )
	{
		relax_normal += ComputeFaceNormal( *itv1 );
		++itv1;
	}
	relax_normal.Normalize();
//	levels[current_level_number].normal_details[v] = VertexNormal(v) - relax_normal;
	levels[current_level_number].normal_details[v] = Vector3d(acos(VertexNormal(v) | relax_normal), 0, 0);

	// Gaussian curvature
//	relax_curvature = GaussianCurvature(this, v);
//	levels[current_level_number].gaussian_curvature_details[v] = gaussian_curvature[v] - relax_curvature;

	// Go back to the initial mesh
	std::swap( Vertex(v), relax );

	// Color detail
	if( use_color )
	{
		relax = 0.0;
		itw = levels[current_level_number].subdivision_weights[v].begin();
		while( itw != levels[current_level_number].subdivision_weights[v].end() ) {
			relax += itw->weight * Color(itw->vertex);
			++itw;
		}
		relax.Clamp(0,1);
		#ifdef _HSI_COLOR_
			levels[current_level_number].color_details[v][0] = HsiDifference(Rgb2Hsi(Color(v)), Rgb2Hsi(relax));
			levels[current_level_number].color_details[v][1] = 0;
			levels[current_level_number].color_details[v][2] = 0;
		#else
			levels[current_level_number].color_details[v] = Color(v) - relax;
		#endif
	}

	// Texture detail
	if( use_texture )
	{
	//	Vector2d relax_texture_coord(0,0);
		relax = 0.0;
		itw = levels[current_level_number].subdivision_weights[v].begin();
		while( itw != levels[current_level_number].subdivision_weights[v].end() )
		{
		//	relax_texture_coord += itw->weight * Texture(itw->vertex);
			relax += itw->weight * Pixel(itw->vertex);
			++itw;
		}
		levels[current_level_number].texture_details[v] = Pixel(v) - relax;
	//	levels[current_level_number].texture_details[v] = Pixel(v) - Pixel(relax_texture_coord);
	//	levels[current_level_number].texture_details[v][0] = Texture(v)[0] - relax_texture_coord[0];
	//	levels[current_level_number].texture_details[v][1] = Texture(v)[1] - relax_texture_coord[1];
	//	levels[current_level_number].texture_details[v][2] = 0;
	}

	return true;
}