Added saving of per vertex point3 attribute.

warning: it leaks memory...
This commit is contained in:
Paolo Cignoni 2018-02-16 07:29:42 +01:00
parent 8d00be785e
commit bf7cf6d5a0
2 changed files with 65 additions and 29 deletions

View File

@ -46,25 +46,33 @@ int main()
{ {
MyMesh m; MyMesh m;
Torus<MyMesh>(m, 3.0f, 1.0f); Torus<MyMesh>(m, 3.0f, 1.0f);
//! [Adding an attribute] //! [Adding a few attributes]
// add a per-vertex attribute with type float named "GaussianCurvature" // add a per-vertex attribute with type float named "GaussianCurvature"
MyMesh::PerVertexAttributeHandle<float> MyMesh::PerVertexAttributeHandle<float>
hv = vcg::tri::Allocator<MyMesh>:: GetPerVertexAttribute<float> (m,std::string("GaussianCurvature")); hvf = vcg::tri::Allocator<MyMesh>:: GetPerVertexAttribute<float> (m,std::string("GaussianCurvature"));
MyMesh::PerVertexAttributeHandle<vcg::Point3f>
hv3f = vcg::tri::Allocator<MyMesh>:: GetPerVertexAttribute<vcg::Point3f> (m,std::string("InvertedNormal"));
// add a per-face attribute with type float named "FaceArea" // add a per-face attribute with type float named "FaceArea"
MyMesh::PerFaceAttributeHandle<float> MyMesh::PerFaceAttributeHandle<float>
hf = vcg::tri::Allocator<MyMesh>:: GetPerFaceAttribute<float> (m,std::string("FaceArea")); hff = vcg::tri::Allocator<MyMesh>:: GetPerFaceAttribute<float> (m,std::string("FaceArea"));
//! [filling the attribute] //! [filling the attribute]
vcg::tri::Allocator<MyMesh>::ClearPerVertexAttribute<float>(m,hv, float(M_PI*2)); vcg::tri::Allocator<MyMesh>::ClearPerVertexAttribute<float>(m,hvf, float(M_PI*2));
vcg::tri::Allocator<MyMesh>::ClearPerVertexAttribute<vcg::Point3f>(m,hv3f, vcg::Point3f(0,0,0));
ForEachFace(m, [&](MyFace &f){ ForEachFace(m, [&](MyFace &f){
hf[&f]=vcg::DoubleArea(f)*0.5f; hff[&f]=vcg::DoubleArea(f)*0.5f;
for(int i=0;i<3;++i) for(int i=0;i<3;++i){
hv[f.V(i)] -= vcg::Angle(f.P1(i)-f.P0(i),f.P2(i)-f.P0(i)); hvf[f.V(i)] -= vcg::Angle(f.P1(i)-f.P0(i),f.P2(i)-f.P0(i));
hv3f[f.V(i)] -= vcg::NormalizedTriangleNormal(f);
}
}); });
//! [Saving two attributes in ply, one of the two disguised as quality] //! [Saving 3 attributes in ply, one of the 3 disguised as quality]
vcg::tri::io::PlyInfo pi; vcg::tri::io::PlyInfo pi;
pi.AddPerVertexFloatAttribute("GaussianCurvature","quality"); pi.AddPerVertexFloatAttribute("GaussianCurvature","quality");
pi.AddPerFaceFloatAttribute("FaceArea"); pi.AddPerFaceFloatAttribute("FaceArea");
vcg::tri::io::ExporterPLY<MyMesh>::Save(m,"MeshWithCurvature.ply",true,pi); pi.AddPerVertexPoint3fAttribute(m,"InvertedNormal");
vcg::tri::io::ExporterPLY<MyMesh>::Save(m,"MeshWithCurvature.ply",false,pi);
} }

View File

@ -66,29 +66,57 @@ class PlyInfo
public: public:
typedef ::vcg::ply::PropDescriptor PropDescriptor ; typedef ::vcg::ply::PropDescriptor PropDescriptor ;
void AddPerVertexFloatAttribute(const std::string &attrName, std::string propName="") void AddPerElemFloatAttribute(int elemType, const char *attrName, const char * propName=0)
{ {
static const char *vertStr="vertex"; static const char *elemStr[2]={"vertex","face"};
if(propName.empty()) propName=attrName; static std::vector<PropDescriptor> *elemDescVec[2]={&(this->VertDescriptorVec), &(this->FaceDescriptorVec)};
VertDescriptorVec.push_back(PropDescriptor()); static std::vector<std::string > *elemNameVec[2]={&(this->VertAttrNameVec), &(this->FaceAttrNameVec)};
VertAttrNameVec.push_back(attrName);
VertDescriptorVec.back().elemname=vertStr; if(propName==0) propName=attrName;
VertDescriptorVec.back().propname=propName.c_str(); elemDescVec[elemType]->push_back(PropDescriptor());
VertDescriptorVec.back().stotype1 = vcg::ply::T_FLOAT; elemNameVec[elemType]->push_back(attrName);
VertDescriptorVec.back().memtype1 = vcg::ply::T_FLOAT; elemDescVec[elemType]->back().elemname=elemStr[elemType];
elemDescVec[elemType]->back().propname=propName;
elemDescVec[elemType]->back().stotype1 = vcg::ply::T_FLOAT;
elemDescVec[elemType]->back().memtype1 = vcg::ply::T_FLOAT;
} }
void AddPerFaceFloatAttribute(const std::string &attrName, std::string propName="")
void AddPerVertexFloatAttribute(const char *attrName, const char *propName=0) {
AddPerElemFloatAttribute(0,attrName,propName);
}
void AddPerFaceFloatAttribute(const char *attrName, const char *propName=0) {
AddPerElemFloatAttribute(1,attrName,propName);
}
/* Note that saving a per vertex point3 attribute is a mess.
* Actually require to allocate 3 float attribute and save them. And they are never deallocated... */
template<class MeshType>
void AddPerVertexPoint3fAttribute(MeshType &m, const char *attrName, const char *propName="")
{ {
static const char *faceStr="face"; if(propName==0) propName=attrName;
if(propName.empty()) propName=attrName;
FaceDescriptorVec.push_back(PropDescriptor()); const char *attrxyz[3] = {
FaceAttrNameVec.push_back(attrName); strdup((std::string(attrName)+std::string("_x")).c_str()),
FaceDescriptorVec.back().elemname=faceStr; strdup((std::string(attrName)+std::string("_y")).c_str()),
FaceDescriptorVec.back().propname=propName.c_str(); strdup((std::string(attrName)+std::string("_z")).c_str()),
FaceDescriptorVec.back().stotype1 = vcg::ply::T_FLOAT; };
FaceDescriptorVec.back().memtype1 = vcg::ply::T_FLOAT; typename MeshType::template PerVertexAttributeHandle <vcg::Point3f>
ht = vcg::tri::Allocator<MeshType>:: template GetPerVertexAttribute <vcg::Point3f> (m,attrName);
typename MeshType::template PerVertexAttributeHandle <float> htt[3];
for(int i=0;i<3;++i)
{
htt[i] = vcg::tri::Allocator<MeshType>:: template GetPerVertexAttribute<float> (m,std::string(attrxyz[i]));
ForEachVertex (m, [&](typename MeshType::VertexType &v) {
htt[i][v] = ht[v][i];
});
AddPerVertexFloatAttribute(attrxyz[i]);
}
} }
PlyInfo() PlyInfo()
{ {
status=0; status=0;