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;
Torus<MyMesh>(m, 3.0f, 1.0f);
//! [Adding an attribute]
//! [Adding a few attributes]
// add a per-vertex attribute with type float named "GaussianCurvature"
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"
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]
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){
hf[&f]=vcg::DoubleArea(f)*0.5f;
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));
hff[&f]=vcg::DoubleArea(f)*0.5f;
for(int i=0;i<3;++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;
pi.AddPerVertexFloatAttribute("GaussianCurvature","quality");
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,28 +66,56 @@ class PlyInfo
public:
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";
if(propName.empty()) propName=attrName;
VertDescriptorVec.push_back(PropDescriptor());
VertAttrNameVec.push_back(attrName);
VertDescriptorVec.back().elemname=vertStr;
VertDescriptorVec.back().propname=propName.c_str();
VertDescriptorVec.back().stotype1 = vcg::ply::T_FLOAT;
VertDescriptorVec.back().memtype1 = vcg::ply::T_FLOAT;
static const char *elemStr[2]={"vertex","face"};
static std::vector<PropDescriptor> *elemDescVec[2]={&(this->VertDescriptorVec), &(this->FaceDescriptorVec)};
static std::vector<std::string > *elemNameVec[2]={&(this->VertAttrNameVec), &(this->FaceAttrNameVec)};
if(propName==0) propName=attrName;
elemDescVec[elemType]->push_back(PropDescriptor());
elemNameVec[elemType]->push_back(attrName);
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.empty()) propName=attrName;
FaceDescriptorVec.push_back(PropDescriptor());
FaceAttrNameVec.push_back(attrName);
FaceDescriptorVec.back().elemname=faceStr;
FaceDescriptorVec.back().propname=propName.c_str();
FaceDescriptorVec.back().stotype1 = vcg::ply::T_FLOAT;
FaceDescriptorVec.back().memtype1 = vcg::ply::T_FLOAT;
if(propName==0) propName=attrName;
const char *attrxyz[3] = {
strdup((std::string(attrName)+std::string("_x")).c_str()),
strdup((std::string(attrName)+std::string("_y")).c_str()),
strdup((std::string(attrName)+std::string("_z")).c_str()),
};
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()
{