⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mesh.cpp

📁 此代码主要用于汽车车身的优化
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	{
		int k = vitr->m_adjEdgePosSet.size();
		ASSERT( k < 50 );//断言函数,返回一个布尔值
	
			Vector3d newV(vitr->m_v * ( 1. - aerfa[k]));
			for( int i = 0; i < k; i ++ )
			{
				int vi = getEdge(vitr->m_adjEdgePosSet[i]).getCounterVertex(vitr->m_index);
				newV += (getVertex(vi).m_v * aerfa[k])/k;
			}
			vitr->m_newVertexPointIdx = addSubdivVertex(newV);
	
	
	}


}
Mesh* Mesh::calcsqrt3SubdivMesh(bool divBeforesqrt3)
{
	if(divBeforesqrt3)
	{
		FOR_EACH_FACE(fitr)
		{
			Mesh *p, *q;
			if(fitr->m_vertexIdxSet.size() > 3)
			{
				p = splitTriangleMesh();
//				p->dump();
				q = p->calcsqrt3SubdivMeshSep();
				p->reset();
				delete p;		// delete temp triangle-mesh删除临时的三角面片
				return q;
			}
		}
	}
	// fall through if no face to div:
	return calcsqrt3SubdivMeshSep();
}	
	
Mesh* Mesh::calcsqrt3SubdivMeshSep()// loop细分开始
{
	preparesqrt3SubdivMesh();
	bool blFound;
	Mesh *pSubMesh = new Mesh();
	// link(copy) vertexes data
	pSubMesh->m_pVertexes = this->m_pSubdivVertexes;

//	FOR_EACH_FACE(fitr)		// Faces may changes when looping
	int fnum = m_faces.size();
	for( int i = 0; i < fnum; i ++ )
	{
		vector<int> firstFaceVertex;//分裂三角形
		//vector<int> cornerFaceVertex;//

		int k = m_faces[i].m_vertexIdxSet.size();
		for( int j = 0; j < k; j ++)
		{
	      // 连接新面点和新顶点
			firstFaceVertex.push_back(m_faces[i].m_newFacePointIdx );
			firstFaceVertex.push_back(getVertex(m_faces[i].m_vertexIdxSet[j]).m_newVertexPointIdx );
			//firstFaceVertex.push_back(m_faces[i].m_newFacePointIdx );
			firstFaceVertex.push_back(getVertex(m_faces[i].m_vertexIdxSet[(j+1)%k]).m_newVertexPointIdx );
			
			pSubMesh->addFace(firstFaceVertex);
			firstFaceVertex.clear();
		}
		
	}
	
	this->m_pSubdivVertexes = NULL;
	pSubMesh->printMeshInfo();
	return pSubMesh;
}







inline void Mesh::GLSetVertex( Vector3d &v )
{
	glVertex3f(v.x, v.y, v.z);		//glVertex3d
}

inline void Mesh::GLSetNormal( Vector3d &v )
{
	glNormal3f(v.x, v.y, v.z);		//glVertex3d
}

void Mesh::render(int rtype)
{
	if( rtype == Mesh::RenderVertex ) //顶点显示
	{
		glPointSize(4);
		glColor3f(1, 1 ,100);
		glBegin(GL_POINTS);
		FOR_EACH_VERTEX(itr)
		{
			GLSetVertex(itr->m_v);
		}
		glEnd();
	}
	else if (rtype == Mesh::RenderEdge )//边显示
	{
		glColor3f(100, 0 ,0);
		glBegin(GL_LINES);
		FOR_EACH_EDGE(itr)
		{
			GLSetVertex((*m_pVertexes)[itr->m_bgVertexIdx].m_v);
			GLSetVertex((*m_pVertexes)[itr->m_edVertexIdx].m_v);
		}
		glEnd();
	}
	else if (rtype == Mesh::RenderFace )//面显示
	{
		glColor3f(1, 1 ,0);
		FOR_EACH_FACE(itr)
		{
			glBegin(GL_POLYGON);
			int vnum = itr->m_vertexIdxSet.size();
			for( int i = 0; i < vnum; i ++ )
			{
				GLSetNormal(itr->m_normal);
				GLSetVertex(getVertex(itr->m_vertexIdxSet[i]).m_v);
			}
			glEnd();
		}
	}
}

void Mesh::dump() const
{
	FOR_EACH_CONST_VERTEX(vitr)
	{
		vitr->dump();
	}
	FOR_EACH_CONST_EDGE(eitr)
	{
		eitr->dump();
	}
	FOR_EACH_CONST_FACE(fitr)
	{
		fitr->dump();
	}
}

void Mesh::printMeshInfo()
{
	cout << "Mesh Vertexes Number:" << m_pVertexes->size() << endl;//输出顶点的个数
	cout << "Mesh Edges Number:" << m_edges.size() << endl;//输出边的个数
	cout << "Mesh Faces Number:" << m_faces.size() << endl;//输出面的个数

}



void Mesh::saveObjFile(CString objFile)//保存obj文件
{
	CString strLine, strtemp;
	CStdioFile fmesh;
	if( !fmesh.Open( objFile, CFile::modeWrite | CFile::modeCreate | CFile::typeText ) ) 
	{
		AfxMessageBox("Error Open File");
	}
        /*strLine1.Format("%f",m_pVertexes->size());
		fmesh.WriteString(strLine1);
		fmesh.WriteString("\r\n");*/
	FOR_EACH_VERTEX(vitr)
	{
//		vitr->dump();
		strLine.Format("v %f %f %f", vitr->m_v.x, vitr->m_v.y, vitr->m_v.z );
		fmesh.WriteString(strLine);
		fmesh.WriteString("\r\n");
	}
		fmesh.WriteString("g    \n");
	FOR_EACH_FACE(fitr)
	{
		strLine = "f ";
		for( int i = 0; i < fitr->m_vertexIdxSet.size(); i ++ )//面的顶点个数
		{
			strtemp.Format("%d ", fitr->m_vertexIdxSet[i]+1);	
			// add 1 for index base 1使面的索引基数为1
			strLine += strtemp;
			
		}
		fmesh.WriteString(strLine);//写字符串文件
		fmesh.WriteString("\r\n");
		//cout<<m_vertexIdxSet.size()<<endl;
	}
	fmesh.Close();
}

// call this to each vertex before generating a new vertex-face when doing doo-sabin subdiv
// as for each vertexes this function is called and called only once, 
// it should take the same time as pre-sorting in for subdiv-calculation...

// sort the face index of vertex vi clockwisely! 
//   Needs only one known adj-face.(by taking care of this, optimism is possible!)
void Mesh::sortVertexAdjFace(int vi)
{
	// should check before call this function
	if((*m_pVertexes)[vi].m_adjFaceIdxSet.size() <= 0)
		return;
//	ASSERT((*m_pVertexes)[vi].m_adjFaceIdxSet.size() > 0);

//	(*m_pVertexes)[vi].dump(); // dump before sort

	vector<int> sortedAdjFaceIdxSet;
	int ofi = (*m_pVertexes)[vi].m_adjFaceIdxSet[0];
	int fi = (*m_pVertexes)[vi].m_adjFaceIdxSet[0];

	do
	{
		sortedAdjFaceIdxSet.push_back(fi);	// clockwise!
		// find the vertex_vi's idx in face's m_vertexIdxSet, then the edge  
		// start from vertex_vi is  m_faces[first].m_faceIdxSet[idx]
		bool blFound = false;
		for( int j = 0; j < m_faces[fi].m_vertexIdxSet.size(); j ++ )
			if (m_faces[fi].m_vertexIdxSet[j] == vi)
			{
				blFound = true;
				break;
			}
		ASSERT(blFound);
/*
		cout << "Vertex " << vi + 1 << " 's out edge in face " << fi + 1 << " is :" << endl;
		cout << "       ";
		m_faces[fi].m_edgePosSet[j]->dump();
		cout << "       ";
		m_faces[fi].dump();
*/
		m_faces[fi].dump();
		fi = getAdjFace( fi,  *(m_faces[fi].m_edgePosSet[j]) );
	} 
	while( ofi != fi && fi != -1);

	(*m_pVertexes)[vi].m_adjFaceIdxSet = sortedAdjFaceIdxSet;

//	(*m_pVertexes)[vi].dump();	// dump after sort

}

typedef struct{
    int a,b,c;
}polygon_type;


bool Mesh::loadObjFile(CString fname)//加载obj文件
{
	// check file validity
	if( fname.Find(".obj") == -1 )
		return false;

	CString strLine;
	CStdioFile fmesh;
	char type[4];

	if( !fmesh.Open( fname, CFile::modeRead | CFile::typeText ) ) 
	{
		AfxMessageBox("Error Open File");
	}
	
	int i1, i2, i3;
	float f1, f2, f3;
	int vcount = 0;
	while( fmesh.ReadString(strLine) )
	{
		//int nnn;
		//nnn=strLine.GetLength();
		strLine.TrimRight();//删除右边部分
		//nnn=strLine.GetLength();
		if(strLine.GetLength() < 2)
			continue;
		sscanf(strLine, "%3s", type);
		if(type[1] != 0 || !(type[0] == 'f' || type[0] == 'v'))	
			// type[0] == 0: sscanf stop when meeting any ' ' and patch '\0' to type
			continue;
		else if(type[0] == 'v')
		{
			vcount ++;
			sscanf(strLine.Mid(2), "%f %f %f", &f1, &f2, &f3);
			this->addVertex(f1, f2, f3);
			cout << "vertex: " << f1 << " " << f2 << " " << f3 << endl;
		}
		else if(type[0] == 'f')
		{
			vector<int> vectVertex;
			int i1, i = 2, j;
			cout << "face: ";
				while( i < strLine.GetLength() )
		{
				j = strLine.Find(' ',i);
				if( j == -1)	j = strLine.GetLength();
				sscanf(strLine.Mid(i,j-i), "%d", &i1);
				cout <<i1<<" "  ; //i1
				vectVertex.push_back(i1 - 1);		
				// vector index base 0 while obj index base 1
				i = j + 1;
			}
			cout << endl;
			this->addFace(vectVertex);
			
		}
	}
	
	fmesh.Close();
	printMeshInfo();
	return true;
}



bool Mesh::load3dsFile(CString p_filename)
{
	int i; //Index variable
	
	FILE *l_file; //File pointer
	
	unsigned short l_chunk_id; //Chunk identifier
	unsigned int l_chunk_lenght; //Chunk lenght
 	vector<int> fvs;

	unsigned char l_char; //Char variable
	unsigned short l_qty; //Number of elements in each chunk

	unsigned short l_face_flags; //Flag that stores some face information

	if ((l_file=fopen (p_filename, "rb"))== NULL) return false; //Open the file

	while (ftell (l_file) < filelength (fileno (l_file))) //Loop to scan the whole file 
	{
		//getche(); //Insert this command for debug (to wait for keypress for each chuck reading)

		fread (&l_chunk_id, 2, 1, l_file); //Read the chunk header
		printf("ChunkID: %x\n",l_chunk_id); 
		fread (&l_chunk_lenght, 4, 1, l_file); //Read the lenght of the chunk
		printf("ChunkLenght: %x\n",l_chunk_lenght);

		switch (l_chunk_id)
        {
			//----------------- MAIN3DS -----------------
			// Description: Main chunk, contains all the other chunks
			// Chunk ID: 4d4d 
			// Chunk Lenght: 0 + sub chunks
			//-------------------------------------------
			case 0x4d4d: 
			break;    

			//----------------- EDIT3DS -----------------
			// Description: 3D Editor chunk, objects layout info 
			// Chunk ID: 3d3d (hex)
			// Chunk Lenght: 0 + sub chunks
			//-------------------------------------------
			case 0x3d3d:
			break;
			
			//--------------- EDIT_OBJECT ---------------
			// Description: Object block, info for each object
			// Chunk ID: 4000 (hex)
			// Chunk Lenght: len(object name) + sub chunks
			//-------------------------------------------
			case 0x4000: 
				i=0;
				do
				{
					fread (&l_char, 1, 1, l_file);
                    //p_object->name[i]=l_char;
					i++;
                }while(l_char != '\0' && i<20);
			break;

			//--------------- OBJ_TRIMESH ---------------
			// Description: Triangular mesh, contains chunks for 3d mesh info
			// Chunk ID: 4100 (hex)
			// Chunk Lenght: 0 + sub chunks
			//-------------------------------------------
			case 0x4100:
			break;
			
			//--------------- TRI_VERTEXL ---------------
			// Description: Vertices list
			// Chunk ID: 4110 (hex)
			// Chunk Lenght: 1 x unsigned short (number of vertices) 
			//             + 3 x float (vertex coordinates) x (number of vertices)
			//             + sub chunks
			//-------------------------------------------
			case 0x4110: 
				float vx, vy, vz;

				fread (&l_qty, sizeof (unsigned short), 1, l_file);
                printf("Number of vertices: %d\n",l_qty);
                for (i=0; i<l_qty; i++)
                {
					fread (&vx, sizeof(float), 1, l_file);
                    fread (&vy, sizeof(float), 1, l_file);
					fread (&vz, sizeof(float), 1, l_file);
					this->addVertex(vx, vy, vz);
					//cout << "vertex" << i << " :" << vx << " " << vy << " " << vz << endl;
				}
				break;

			//--------------- TRI_FACEL1 ----------------
			// Description: Polygons (faces) list
			// Chunk ID: 4120 (hex)
			// Chunk Lenght: 1 x unsigned short (number of polygons) 
			//             + 3 x unsigned short (polygon points) x (number of polygons)
			//             + sub chunks
			//-------------------------------------------
			case 0x4120:
				fread (&l_qty, sizeof (unsigned short), 1, l_file);
                printf("Number of polygons: %d\n",l_qty); 
               for (i=0; i<l_qty; i++)
                {
					unsigned short i1, i2, i3;
					fread (&i1, sizeof (unsigned short), 1, l_file);		// !!!! unsigned short !!! NOT int!!
					fvs.push_back(i1);
					fread (&i2, sizeof (unsigned short), 1, l_file);		// !!!! unsigned short !!! NOT int!!
					fvs.push_back(i2);
					fread (&i3, sizeof (unsigned short), 1, l_file);		// !!!! unsigned short !!! NOT int!!
					fvs.push_back(i3);
					this->addFace(fvs);
					//cout << "face " << i << " :" << i1 << " " << i2 << " " << i3 << endl;
					fread (&l_face_flags, sizeof (unsigned short), 1, l_file);
					fvs.clear();
//					printf("Face flags: %x\n",l_face_flags);
				}
                break;

			//------------- TRI_MAPPINGCOORS ------------
			// Description: Vertices list
			// Chunk ID: 4140 (hex)
			// Chunk Lenght: 1 x unsigned short (number of mapping points) 
			//             + 2 x float (mapping coordinates) x (number of mapping points)
			//             + sub chunks
			//-------------------------------------------
			case 0x4140:
				 fseek(l_file, l_chunk_lenght-6, SEEK_CUR);
/*				fread (&l_qty, sizeof (unsigned short), 1, l_file);
				for (i=0; i<l_qty; i++)
				{	// Mapping list u, v
					float u,v;
					fread (&u, sizeof (float), 1, l_file);
                    fread (&v, sizeof (float), 1, l_file);
				}*/
               break;

			//----------- Skip unknow chunks ------------
			//We need to skip all the chunks that currently we don't use
			//We use the chunk lenght information to set the file pointer
			//to the same level next chunk
			//-------------------------------------------
			default:
				 fseek(l_file, l_chunk_lenght-6, SEEK_CUR);
        } 
	}
	fclose (l_file); // Closes the file stream
	return (true); // Returns ok

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -