Example #1
0
void Geometry::ShowInformation() const
{
    Debug::Log(QString("Information of the mesh %1:").arg(mName));
    Debug::Log(QString("   Number of faces: %1").arg(GetNumFaces()));
    Debug::Log(QString("   Number of vertices: %1").arg(GetNumVertices()));
    Debug::Log(QString("   Diameter: %1").arg(mBoundingSphere->GetRadius()*2));
}
Example #2
0
HRESULT Mesh::CreateTopologyFromMesh() {
	HRESULT hr;
	mVertices = new Vertex[GetNumVertices()];
	mFaces = new DWORD[3*GetNumFaces()];
	mVertexFaceAdjazency = new std::vector<DWORD>[GetNumVertices()];

	FULL_VERTEX *pVertices = NULL;
  hr = mMesh->LockVertexBuffer(0, (void**)&pVertices);
  PD(hr, L"lock vertex buffer");
  if(FAILED(hr)) return hr;

  for ( DWORD i = 0; i < mMesh->GetNumVertices(); ++i ) {
    Vertex vertex;
    vertex.pos.x = pVertices[i].position.x;
    vertex.pos.y = pVertices[i].position.y;
    vertex.pos.z = pVertices[i].position.z;
    vertex.normal.x = pVertices[i].normal.x;
    vertex.normal.y = pVertices[i].normal.y;
    vertex.normal.z = pVertices[i].normal.z;
    mVertices[i] = vertex;
  }

  hr = mMesh->UnlockVertexBuffer();
  PD(hr, L"unlock vertex buffer");
  if(FAILED(hr)) return hr;

	DWORD* pIndexBuffer = NULL;
	hr = mMesh->LockIndexBuffer( 0, ( void** )&pIndexBuffer );
	PD(hr, L"lock index buffer");
	if(FAILED(hr)) return hr;

	for( DWORD j = 0; j < GetNumFaces(); j++ )
	{		
		mFaces[j*3+0] = pIndexBuffer[j*3+0];
		mFaces[j*3+1] = pIndexBuffer[j*3+1];
		mFaces[j*3+2] = pIndexBuffer[j*3+2];

		mVertexFaceAdjazency[pIndexBuffer[j*3+0]].push_back(j);
		mVertexFaceAdjazency[pIndexBuffer[j*3+1]].push_back(j);
		mVertexFaceAdjazency[pIndexBuffer[j*3+2]].push_back(j);
	}

	hr = mMesh->UnlockIndexBuffer();
	PD(hr, L"unlock index buffer");
	if(FAILED(hr)) return hr;
}
Example #3
0
void SkpModel::print_all_counts(){
	
	std::cout << "Definitions: " << GetNumDefinitions() << "\n";
	std::cout << "Instances: "   << GetNumInstances()   << "\n";
	std::cout << "Groups: "      << GetNumGroups()      << "\n";
	std::cout << "Faces: "       << GetNumFaces()       << "\n";
	std::cout << "Images: "      << GetNumImages()      << "\n";
	std::cout << "Edges: "       << GetNumEdges()       << "\n";
	std::cout << "Guides: "      << GetNumGuides()      << "\n";
	std::cout << "Curves: "      << GetNumCurves()      << "\n";

}
Example #4
0
void Geometry::ComputeAreasOfPolygons()
{
    mAreasOfPolygons.fill( 0.0f, GetNumFaces() );

    if( mTopology == Triangles )
    {
        for( int i = 0; i < mIndexData.size(); i+=3 )
        {
            mAreasOfPolygons[ i / 3 ] = 0.5f * glm::length( glm::cross( GetVertexByIndexPosition( i + 1 ) - GetVertexByIndexPosition( i ), GetVertexByIndexPosition( i + 2 ) - GetVertexByIndexPosition( i ) ) );
        }
    }
}
    void RenderWindowControl::updateInfo()
    {
        auto model = HonViewerApp::GetViewerApp()->GetModelViewer();
        if (!model)
            return;

        int numVerts = model->GetNumVertices();
        int numFaces = model->GetNumFaces();
        int numSubMods = model->GetNumSubModels();
        int numBones = model->GetNumBones();

        DiString info;
        info.Format("%d\n%d\n%d\n%d", numVerts, numFaces, numSubMods, numBones);
        mInfo->setCaption(info.c_str());
    }
Example #6
0
ParametricSurface::ParametricSurface(int dSampleU, int dSampleV) : iVertexVBO(0), iUvVBO(0), iNormalVBO(0), pVertex(0),
																	pUV(0),pNormal(0), pIndex(0), fMinU(0), fMaxU(0), fMinV(0), 
																	fMaxV(0), nSampleU(dSampleU), nSampleV(dSampleV)
{
	pIndex = new unsigned short[GetNumFaces()*3];

	// Generate three vertex buffer objects.
	glGenBuffers(1, &iVertexVBO);
	glGenBuffers(1, &iUvVBO);
	glGenBuffers(1, &iNormalVBO);

	for (int i=0; i<nSampleU-1; i++)
	{
		for (int j=0; j<nSampleV-1; j++)
		{
			pIndex[ (j*(nSampleU-1)+i)*6 + 0 ] = (unsigned short) (j * nSampleU + i);
			pIndex[ (j*(nSampleU-1)+i)*6 + 1 ] = (unsigned short) (j * nSampleU + (i+1));
			pIndex[ (j*(nSampleU-1)+i)*6 + 2 ] = (unsigned short) ((j+1) * nSampleU + (i+1));
			pIndex[ (j*(nSampleU-1)+i)*6 + 3 ] = (unsigned short) (j * nSampleU + i);
			pIndex[ (j*(nSampleU-1)+i)*6 + 4 ] = (unsigned short) ((j+1) * nSampleU + (i+1));
			pIndex[ (j*(nSampleU-1)+i)*6 + 5 ] = (unsigned short) ((j+1) * nSampleU + i);
		}
	}
}
Example #7
0
// Draw shape using OpenGL.
void STShape::Draw()
{
    glBegin(GL_TRIANGLES);

    size_t numFaces = GetNumFaces();
    for (size_t ii = 0; ii < numFaces; ++ii) {
        const Face& face = GetFace(ii);

        for (size_t jj = 0; jj < 3; ++jj) {
            Index index = face.GetIndex(jj);

            const Vertex& vertex = mVertices[index];
            glTexCoord2f(vertex.texCoord.x,
                         vertex.texCoord.y);
            glNormal3f(vertex.normal.x,
                       vertex.normal.y,
                       vertex.normal.z);
            glVertex3f(vertex.position.x,
                       vertex.position.y,
                       vertex.position.z);
        }
    }
    glEnd();
}
/*! Subdivides the mesh one step, depending on subdividability
*/
void AdaptiveLoopSubdivisionMesh::Subdivide()
{
  // Create new mesh and copy all the attributes
  HalfEdgeMesh subDivMesh;
  subDivMesh.SetTransform(GetTransform());
  subDivMesh.SetName(GetName());
  subDivMesh.SetColorMap(GetColorMap());
  subDivMesh.SetWireframe(GetWireframe());
  subDivMesh.SetShowNormals(GetShowNormals());
  subDivMesh.SetOpacity(GetOpacity());
  if (IsHovering()) subDivMesh.Hover();
  if (IsSelected()) subDivMesh.Select();
  subDivMesh.mMinCMap = mMinCMap;
  subDivMesh.mMaxCMap = mMaxCMap;
  subDivMesh.mAutoMinMax = mAutoMinMax;


  // loop over each face and create new ones
  for(unsigned int i=0; i<GetNumFaces(); i++){

    // find neighbor faces
    unsigned int f1, f2, f3;
    EdgeIterator eit = GetEdgeIterator( f(i).edge );
    f1 = eit.Pair().GetEdgeFaceIndex(); eit.Pair();
    f2 = eit.Next().Pair().GetEdgeFaceIndex(); eit.Pair();
    f3 = eit.Next().Pair().GetEdgeFaceIndex();

    unsigned int numNotSubdividable = !Subdividable(f1) + !Subdividable(f2) + !Subdividable(f3);

    // Do not subdivide if "self" is not subdividable
    if(!Subdividable(i)){
      numNotSubdividable = 3;
    }

    std::vector< std::vector <Vector3<float> > > faces;
    switch(numNotSubdividable){
    case 0:
      // normal subdivision (from LoopSubdivisionMesh)
      faces = LoopSubdivisionMesh::Subdivide(i);
      break;
    case 1:
      // special case 1
      faces = Subdivide1(i);
      break;
    case 2:
      // special case 2
      faces = Subdivide2(i);
      break;
    case 3:
      // trivial case, no subdivision, same as if subdividable(fi) == false
      faces = Subdivide3(i);
      break;
    }

    // add the faces (if any) to subDivMesh
    for(unsigned int j=0; j<faces.size(); j++){
      subDivMesh.AddFace(faces.at(j));
    }
  }

  // Assign the new mesh
  *this = AdaptiveLoopSubdivisionMesh(subDivMesh, ++mNumSubDivs);
  Update();
}
Example #9
0
void HalfEdgeMesh::Render()
{
  glEnable(GL_LIGHTING);
  glMatrixMode(GL_MODELVIEW);

  // Apply transform
  glPushMatrix(); // Push modelview matrix onto stack

  // Convert transform-matrix to format matching GL matrix format
  // Load transform into modelview matrix
  glMultMatrixf(  mTransform.ToGLMatrix().GetArrayPtr() );

  if (mWireframe)
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

  // Draw geometry
  glBegin(GL_TRIANGLES);
  const int numTriangles = GetNumFaces();
  for (int i = 0; i < numTriangles; i++){

    Face & face = f(i);

    HalfEdge* edge = &e(face.edge);

    Vertex & v1 = v(edge->vert);
    edge = &e(edge->next);

    Vertex & v2 = v(edge->vert);
    edge = &e(edge->next);

    Vertex & v3 = v(edge->vert);

    if (mVisualizationMode == CurvatureVertex) {
      glColor3fv(v1.color.GetArrayPtr());
      glNormal3fv(v1.normal.GetArrayPtr());
      glVertex3fv(v1.pos.GetArrayPtr());

      glColor3fv(v2.color.GetArrayPtr());
      glNormal3fv(v2.normal.GetArrayPtr());
      glVertex3fv(v2.pos.GetArrayPtr());

      glColor3fv(v3.color.GetArrayPtr());
      glNormal3fv(v3.normal.GetArrayPtr());
      glVertex3fv(v3.pos.GetArrayPtr());
    }
    else {
      glColor3fv(face.color.GetArrayPtr());
      glNormal3fv(face.normal.GetArrayPtr());

      glVertex3fv(v1.pos.GetArrayPtr());
      glVertex3fv(v2.pos.GetArrayPtr());
      glVertex3fv(v3.pos.GetArrayPtr());
    }

  }
  glEnd();

  // Mesh normals by courtesy of Richard Khoury
  if (mShowNormals)
  {
    glDisable(GL_LIGHTING);
    glBegin(GL_LINES);
    const int numTriangles = GetNumFaces();
    for (int i = 0; i < numTriangles; i++){

      Face & face = f(i);

      HalfEdge* edge = &e(face.edge);

      Vertex & v1 = v(edge->vert);
      edge = &e(edge->next);

      Vertex & v2 = v(edge->vert);
      edge = &e(edge->next);

      Vertex & v3 = v(edge->vert);

      Vector3<float> faceStart = (v1.pos + v2.pos + v3.pos) / 3.0f;
      Vector3<float> faceEnd = faceStart + face.normal*0.1;

      glColor3f(1,0,0); // Red for face normal
      glVertex3fv(faceStart.GetArrayPtr());
      glVertex3fv(faceEnd.GetArrayPtr());

      glColor3f(0,1,0); // Vertex normals in Green
      glVertex3fv(v1.pos.GetArrayPtr());
      glVertex3fv((v1.pos + v1.normal*0.1).GetArrayPtr());
      glVertex3fv(v2.pos.GetArrayPtr());
      glVertex3fv((v2.pos + v2.normal*0.1).GetArrayPtr());
      glVertex3fv(v3.pos.GetArrayPtr());
      glVertex3fv((v3.pos + v3.normal*0.1).GetArrayPtr());
    }
    glEnd();
    glEnable(GL_LIGHTING);

  }


  if (mWireframe)
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

  // Restore modelview matrix
  glPopMatrix();

  GLObject::Render();

}
Example #10
0
void HalfEdgeMesh::Update() {
  // Calculate and store all differentials and area

  // First update all face normals and triangle areas
  for(unsigned int i = 0; i < GetNumFaces(); i++){
    f(i).normal = FaceNormal(i);
  }
  // Then update all vertex normals and curvature
  for(unsigned int i = 0; i < GetNumVerts(); i++){
    // Vertex normals are just weighted averages
    mVerts.at(i).normal = VertexNormal(i);
  }

  // Then update vertex curvature
  for(unsigned int i = 0; i < GetNumVerts(); i++){
    mVerts.at(i).curvature = VertexCurvature(i);
    //    std::cerr <<   mVerts.at(i).curvature << "\n";
  }

  // Finally update face curvature
  for(unsigned int i = 0; i < GetNumFaces(); i++){
    f(i).curvature = FaceCurvature(i);
  }

  std::cerr << "Area: " << Area() << ".\n";
  std::cerr << "Volume: " << Volume() << ".\n";

  // Update vertex and face colors
  if (mVisualizationMode == CurvatureVertex) {
    std::vector<Vertex>::iterator iter = mVerts.begin();
    std::vector<Vertex>::iterator iend = mVerts.end();
    float minCurvature = (std::numeric_limits<float>::max)();
    float maxCurvature = -(std::numeric_limits<float>::max)();
    while (iter != iend) {
      if (minCurvature > (*iter).curvature)  minCurvature = (*iter).curvature;
      if (maxCurvature < (*iter).curvature)  maxCurvature = (*iter).curvature;
      iter++;
    }
    std::cerr << "Mapping color based on vertex curvature with range [" << minCurvature << "," << maxCurvature << "]" << std::endl;
    iter = mVerts.begin();
    while (iter != iend) {
      (*iter).color = mColorMap->Map((*iter).curvature, minCurvature, maxCurvature);
      iter++;
    }
  }
  else if (mVisualizationMode == CurvatureFace) {
    std::vector<Face>::iterator iter = mFaces.begin();
    std::vector<Face>::iterator iend = mFaces.end();
    float minCurvature = (std::numeric_limits<float>::max)();
    float maxCurvature = -(std::numeric_limits<float>::max)();
    while (iter != iend) {
      if (minCurvature > (*iter).curvature)  minCurvature = (*iter).curvature;
      if (maxCurvature < (*iter).curvature)  maxCurvature = (*iter).curvature;
      iter++;
    }
    std::cerr << "Mapping color based on face curvature with range [" << minCurvature << "," << maxCurvature << "]" << std::endl;
    iter = mFaces.begin();
    while (iter != iend) {
      (*iter).color = mColorMap->Map((*iter).curvature, minCurvature, maxCurvature);
      iter++;
    }
  }

}
Example #11
0
/*! Proceeds to check if the mesh is valid. All indices are inspected and
 * checked to see that they are initialized. The method checks: mEdges, mFaces and mVerts.
 * Also checks to see if all verts have a neighborhood using the findNeighbourFaces method.
 */
void HalfEdgeMesh::Validate()
{
  std::vector<HalfEdge>::iterator iterEdge = mEdges.begin();
  std::vector<HalfEdge>::iterator iterEdgeEnd = mEdges.end();
  while (iterEdge != iterEdgeEnd) {
    if ((*iterEdge).face == UNINITIALIZED ||
        (*iterEdge).next == UNINITIALIZED ||
        (*iterEdge).pair == UNINITIALIZED ||
        (*iterEdge).prev == UNINITIALIZED ||
        (*iterEdge).vert == UNINITIALIZED)
        std::cerr << "HalfEdge " << iterEdge - mEdges.begin() << " not properly initialized" << std::endl;

    iterEdge++;
  }
  std::cerr << "Done with edge check (checked " << GetNumEdges() << " edges)" << std::endl;

  std::vector<Face>::iterator iterTri = mFaces.begin();
  std::vector<Face>::iterator iterTriEnd = mFaces.end();
  while (iterTri != iterTriEnd) {
    if ((*iterTri).edge == UNINITIALIZED)
        std::cerr << "Tri " << iterTri - mFaces.begin() << " not properly initialized" << std::endl;

    iterTri++;
  }
  std::cerr << "Done with face check (checked " << GetNumFaces() << " faces)" << std::endl;

  std::vector<Vertex>::iterator iterVertex = mVerts.begin();
  std::vector<Vertex>::iterator iterVertexEnd = mVerts.end();
  while (iterVertex != iterVertexEnd) {
    if ((*iterVertex).edge == UNINITIALIZED)
        std::cerr << "Vertex " << iterVertex - mVerts.begin() << " not properly initialized" << std::endl;

    iterVertex++;
  }
  std::cerr << "Done with vertex check (checked " << GetNumVerts() << " vertices)" << std::endl;

  std::cerr << "Looping through triangle neighborhood of each vertex... ";
  iterVertex = mVerts.begin();
  iterVertexEnd = mVerts.end();
  int emptyCount = 0;
  std::vector<unsigned int> problemVerts;
  while (iterVertex != iterVertexEnd) {
    std::vector<unsigned int> foundFaces = FindNeighborFaces(iterVertex - mVerts.begin());
    std::vector<unsigned int> foundVerts = FindNeighborVertices(iterVertex - mVerts.begin());
    if (foundFaces.empty() || foundVerts.empty())
      emptyCount++;
    std::set<unsigned int> uniqueFaces(foundFaces.begin(), foundFaces.end());
    std::set<unsigned int> uniqueVerts(foundVerts.begin(), foundVerts.end());
        if ( foundFaces.size() != uniqueFaces.size() ||
         foundVerts.size() != uniqueVerts.size() )
      problemVerts.push_back(iterVertex - mVerts.begin());
    iterVertex++;
  }
  std::cerr << std::endl << "Done: " << emptyCount << " isolated vertices found" << std::endl;
  if(problemVerts.size()){
    std::cerr << std::endl << "Found " << problemVerts.size() << " duplicate faces in vertices: ";
    std::copy(problemVerts.begin(), problemVerts.end(), std::ostream_iterator<unsigned int>(std::cerr, ", "));
    std::cerr << "\n";
  }
  std::cerr << std::endl << "The mesh has genus " << Genus() << ", and consists of " << Shells() << " shells.\n";
}
Example #12
0
void DoPhysicsAlignObject (tObject * objP)
{
	vmsVector desired_upvec;
	fixang delta_ang, roll_ang;
	//vmsVector forvec = {0, 0, f1_0};
	vmsMatrix temp_matrix;
	fix d, largest_d=-f1_0;
	int i, best_side;

        best_side=0;
	// bank player according to tSegment orientation

	//find tSide of tSegment that player is most alligned with

	for (i=0;i<6;i++) {
		#ifdef COMPACT_SEGS
			vmsVector _tv1;
			GetSideNormal (gameData.segs.segments + objP->nSegment, i, 0, &_tv1);
			d = VmVecDot (&_tv1, &objP->orient.uVec);
		#else					
			d = VmVecDot (gameData.segs.segments [objP->nSegment].sides [i].normals, &objP->orient.uVec);
		#endif

		if (d > largest_d) {largest_d = d; best_side=i;}
	}

	if (floorLevelling) {

		// old way: used floor's normal as upvec
		#ifdef COMPACT_SEGS
			GetSideNormal (gameData.segs.segments + objP->nSegment, 3, 0, &desired_upvec);			
		#else
			desired_upvec = gameData.segs.segments [objP->nSegment].sides [3].normals [0];
		#endif

	}
	else  // new player leveling code: use normal of tSide closest to our up vec
		if (GetNumFaces (&gameData.segs.segments [objP->nSegment].sides [best_side])==2) {
			#ifdef COMPACT_SEGS
				vmsVector normals [2];
				GetSideNormals (&gameData.segs.segments [objP->nSegment], best_side, &normals [0], &normals [1]);			

				desired_upvec.x = (normals [0].x + normals [1].x) / 2;
				desired_upvec.y = (normals [0].y + normals [1].y) / 2;
				desired_upvec.z = (normals [0].z + normals [1].z) / 2;

				VmVecNormalize (&desired_upvec);
			#else
				tSide *s = &gameData.segs.segments [objP->nSegment].sides [best_side];
				desired_upvec.x = (s->normals [0].x + s->normals [1].x) / 2;
				desired_upvec.y = (s->normals [0].y + s->normals [1].y) / 2;
				desired_upvec.z = (s->normals [0].z + s->normals [1].z) / 2;
		
				VmVecNormalize (&desired_upvec);
			#endif
		}
		else
			#ifdef COMPACT_SEGS
				GetSideNormal (&gameData.segs.segments [objP->nSegment], best_side, 0, &desired_upvec);			
			#else
				desired_upvec = gameData.segs.segments [objP->nSegment].sides [best_side].normals [0];
			#endif

	if (labs (VmVecDot (&desired_upvec, &objP->orient.fVec)) < f1_0/2) {
		fixang save_delta_ang;
		vmsAngVec tangles;
		
		VmVector2Matrix (&temp_matrix, &objP->orient.fVec, &desired_upvec, NULL);

		save_delta_ang = delta_ang = VmVecDeltaAng (&objP->orient.uVec, &temp_matrix.uVec, &objP->orient.fVec);

		delta_ang += objP->mType.physInfo.turnRoll;

		if (abs (delta_ang) > DAMP_ANG) {
			vmsMatrix rotmat, new_pm;

			roll_ang = FixMul (gameData.time.xFrame, ROLL_RATE);

			if (abs (delta_ang) < roll_ang) roll_ang = delta_ang;
			else if (delta_ang<0) roll_ang = -roll_ang;

			tangles.p = tangles.h = 0;  tangles.b = roll_ang;
			VmAngles2Matrix (&rotmat, &tangles);

			VmMatMul (&new_pm, &objP->orient, &rotmat);
			objP->orient = new_pm;
		}
		else floorLevelling=0;
	}

}
Example #13
0
// Compute or re-compute the per-vertex normals for this shape
// using the normals of adjoining faces.
void STShape::GenerateNormals()
{
    //
    // We compute the normals for hte mesh as the area-weighted average of
    // the normals of incident faces. This is a simple technique to implement,
    // but other techniques are possible.
    //

    //
    // Initialize all the normals to zero.
    //
    size_t numVertices = GetNumVertices();
    for (size_t ii = 0; ii < numVertices; ++ii) {
        mVertices[ii].normal = STVector3::Zero;
    }

    //
    // Loop over faces, adding the normal of each face
    // to the vertices that use it.
    //
    size_t numFaces = GetNumFaces();
    for (size_t ii = 0; ii < numFaces; ++ii) {
        const Face& face = mFaces[ii];

        Vertex& v0 = mVertices[face.GetIndex(0)];
        Vertex& v1 = mVertices[face.GetIndex(1)];
        Vertex& v2 = mVertices[face.GetIndex(2)];

        //
        // We compute a cross-product of two triangle edges.
        // This direction of this vector will be the normal
        // direction, while the magnitude will be twice
        // the triangle area. We can thus use this directly
        // as a weighted normal.
        //
        STVector3 edge1 = v1.position - v0.position;
        STVector3 edge2 = v2.position - v0.position;
        STVector3 weightedNormal = STVector3::Cross(edge1, edge2);

        //
        // We now add the face normal to the normal stored
        // in each of the vertices using the face.
        //
        v0.normal += weightedNormal;
        v1.normal += weightedNormal;
        v2.normal += weightedNormal;
    }

    //
    // Each vertex now has an area-weighted normal. We need to
    // normalize them to turn them into correct unit-lenght
    // normal vectors for rendering.
    //
    for (size_t ii = 0; ii < numVertices; ++ii) {
        //
        // Check that the weighted normal is non-zero so that
        // we don't divide by zero when normalizing.
        //
        Vertex& vertex = mVertices[ii];
        if (vertex.normal.LengthSq() > 0.0f) {
            vertex.normal.Normalize();
        }
    }
}