昨天一直在尝试使用assimp导入obj模型,再把数据导入到cgal的Polyhedron_3中。结果发现,所有的模型都是平滑着色的。好奇怪的现象。。。我尝试了很多次修改着色模式,一点反应都没有。我去掉assimp显示就是对的。后面,怀疑到我在cgal中计算顶点法线的过程。果然是这里出问题了。计算顶点法线的过程中基本上只使用了一个邻接面。也就是cgal里面已经没有原有obj模型的拓扑性质了。所以,顶点法线基本上等于面法线了,效果就成了flat着色了。
这有什么办法了。难道在assimp中计算法线。即使这样,我能够得到正确的顶点法线,但是cgal里面已经没有原有模型的拓扑性质了。我的数据结构还是加载失败的。所以,我不能使用assimp。而且,assimp还不能导入.m模型。虽然,它能导入格式麻烦的obj模型已经很不错了。
下面是我用assimp加载模型,并且导入到cgal中的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <CGAL/Polyhedron_incremental_builder_3.h> #include "Enriched_polyhedron.h" #include <vector> #include <assimp/Importer.hpp> #include <assimp/scene.h> #include <assimp/postprocess.h>
template <class HDS> class Builder_obj : public CGAL::Modifier_base<HDS> { private: typedef typename HDS::Vertex::Point Point; typedef typename CGAL::Polyhedron_incremental_builder_3<HDS> Builder; const char* pcszfileName; const aiScene* scene;
public: Builder_obj(const char* pFilename) { pcszfileName = pFilename; }
~Builder_obj() {}
void operator()(HDS hds) { Builder builder(hds,true); builder.begin_surface(3,1,6);
Assimp::Importer importer; scene = importer.ReadFile(pcszfileName, aiProcessPreset_TargetRealtime_Quality); if (!scene) { fprintf (stderr, "ERROR: reading mesh %s\n", pcszfileName); return; }
for (unsigned int m_i = 0; m_i < scene->mNumMeshes; m_i++) { const aiMesh* mesh = scene->mMeshes[m_i];
for (unsigned int v_i = 0; v_i < mesh->mNumVertices; v_i++) { if (mesh->HasPositions()) { const aiVector3D* vp = (mesh->mVertices[v_i]); printf (" vp %i (%f,%f,%f)\n", v_i, vp->x, vp->y, vp->z); builder.add_vertex(Point(vp->x, vp->y, vp->z)); } }
for (unsigned int j = 0; j < mesh->mNumFaces; ++j) { const aiFace face = mesh->mFaces[j]; assert(face.mNumIndices == 3);
builder.begin_facet(); builder.add_vertex_to_facet(face.mIndices[0]); builder.add_vertex_to_facet(face.mIndices[1]); builder.add_vertex_to_facet(face.mIndices[2]); builder.end_facet(); }
}
builder.end_surface(); } };
template <class kernel, class items> class Parser_obj { public: typedef typename Enriched_Model::HalfedgeDS HalfedgeDS; Parser_obj() {} ~Parser_obj() {}
public: bool read(const char*pFilename, Enriched_Model *pMesh) { CGAL_assertion(pMesh != NULL); Builder_obj<HalfedgeDS> builder(pFilename); pMesh->delegate(builder); return true; } };
|
代码确实非常简洁,但是不能到达要求,又有什么办法了。如果谁有什么解决办法的,欢迎回复啊。。。所以,我打算自己实现一个适用于cgal的导入obj模型(我只导入顶点),.m模型,.off模型等的类吧,以方便以后扩充和重复使用吧。