Merge branch 'devel' of https://github.com/cnr-isti-vclab/vcglib into devel
This commit is contained in:
commit
142ec158f6
|
|
@ -522,6 +522,47 @@ void Cone( MeshType& in,
|
|||
}
|
||||
}
|
||||
|
||||
template <class MeshType>
|
||||
void OrientedCone(MeshType & m,
|
||||
const typename MeshType::CoordType origin,
|
||||
const typename MeshType::CoordType end,
|
||||
const typename MeshType::ScalarType r1,
|
||||
const typename MeshType::ScalarType r2,
|
||||
const int SubDiv = 36 )
|
||||
{
|
||||
typedef typename MeshType::ScalarType ScalarType;
|
||||
typedef typename MeshType::CoordType CoordType;
|
||||
typedef Matrix44<typename MeshType::ScalarType> Matrix44x;
|
||||
Cone(m,r1,r2,Distance(origin,end),SubDiv);
|
||||
|
||||
// tri::UpdatePosition<MeshType>::Translate(m,CoordType(0,1,0));
|
||||
// tri::UpdatePosition<MeshType>::Scale(m,CoordType(1,0.5f,1));
|
||||
// tri::UpdatePosition<MeshType>::Scale(m,CoordType(xScale,1.0f,yScale));
|
||||
|
||||
// float height = Distance(origin,end);
|
||||
// tri::UpdatePosition<MeshType>::Scale(m,CoordType(radius,height,radius));
|
||||
CoordType norm = end-origin;
|
||||
ScalarType angleRad = Angle(CoordType(0,1,0),norm);
|
||||
const ScalarType Delta= 0.000000001;
|
||||
Matrix44x rotM;
|
||||
if (fabs(angleRad)<Delta)
|
||||
rotM.SetIdentity();
|
||||
else
|
||||
if (fabs(angleRad-M_PI)<Delta)
|
||||
{
|
||||
CoordType axis = CoordType(0,0,1)^norm;
|
||||
rotM.SetRotateRad(angleRad,axis);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoordType axis = CoordType(0,1,0)^norm;
|
||||
rotM.SetRotateRad(angleRad,axis);
|
||||
}
|
||||
tri::UpdatePosition<MeshType>::Matrix(m,rotM);
|
||||
tri::UpdatePosition<MeshType>::Translate(m,origin);
|
||||
|
||||
}
|
||||
|
||||
|
||||
template <class MeshType >
|
||||
void Box(MeshType &in, const typename MeshType::BoxType & bb )
|
||||
|
|
@ -1000,9 +1041,21 @@ void OrientedEllipticPrism(MeshType & m, const typename MeshType::CoordType orig
|
|||
tri::UpdatePosition<MeshType>::Scale(m,CoordType(radius,height,radius));
|
||||
CoordType norm = end-origin;
|
||||
ScalarType angleRad = Angle(CoordType(0,1,0),norm);
|
||||
CoordType axis = CoordType(0,1,0)^norm;
|
||||
const ScalarType Delta= 0.000000001;
|
||||
Matrix44x rotM;
|
||||
rotM.SetRotateRad(angleRad,axis);
|
||||
if (fabs(angleRad)<Delta)
|
||||
rotM.SetIdentity();
|
||||
else
|
||||
if (fabs(angleRad-M_PI)<Delta)
|
||||
{
|
||||
CoordType axis = CoordType(0,0,1)^norm;
|
||||
rotM.SetRotateRad(angleRad,axis);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoordType axis = CoordType(0,1,0)^norm;
|
||||
rotM.SetRotateRad(angleRad,axis);
|
||||
}
|
||||
tri::UpdatePosition<MeshType>::Matrix(m,rotM);
|
||||
tri::UpdatePosition<MeshType>::Translate(m,origin);
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,13 @@ public:
|
|||
return vcg::tri::GetClosestFaceBase(base,uniformGrid,p, this->par.gridBailout, closestDist, closestP,closestN,ip);
|
||||
}
|
||||
|
||||
FaceType *GetClosestFaceIP(const CoordType &p, CoordType &ip, CoordType &in)
|
||||
{
|
||||
ScalarType closestDist;
|
||||
CoordType closestP;
|
||||
return vcg::tri::GetClosestFaceBase(base,uniformGrid,p, this->par.gridBailout, closestDist, closestP,in,ip);
|
||||
}
|
||||
|
||||
FaceType *GetClosestFacePoint(const CoordType &p, CoordType &closestP)
|
||||
{
|
||||
ScalarType closestDist;
|
||||
|
|
@ -193,8 +200,10 @@ public:
|
|||
{
|
||||
VertexPointer v0 = FindVertexSnap(f0,ip0);
|
||||
VertexPointer v1 = FindVertexSnap(f1,ip1);
|
||||
|
||||
if(v0==0 || v1==0) return false;
|
||||
if(v0==v1) return false;
|
||||
|
||||
FacePointer ff0,ff1;
|
||||
int e0,e1;
|
||||
bool ret=face::FindSharedFaces<FaceType>(v0,v1,ff0,ff1,e0,e1);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <vcg/complex/algorithms/update/topology.h>
|
||||
#include <vcg/simplex/face/pos.h>
|
||||
#include <vcg/complex/algorithms/clean.h>
|
||||
#include <vcg/complex/algorithms/polygonal_algorithms.h>
|
||||
|
||||
namespace vcg {
|
||||
namespace tri {
|
||||
|
|
@ -61,65 +62,8 @@ class DualMeshing
|
|||
vertSeq.push_back(indexV);
|
||||
}
|
||||
|
||||
if (startV.IsB())
|
||||
{
|
||||
vcg::face::Pos<FaceType> firstPos=posVec[0];
|
||||
firstPos.FlipE();
|
||||
assert(firstPos.IsBorder());
|
||||
|
||||
int indexVt0=vcg::tri::Index(primal,firstPos.V());
|
||||
int indexVt1=vcg::tri::Index(primal,firstPos.VFlip());
|
||||
std::pair<int,int> key(std::min(indexVt0,indexVt1),
|
||||
std::max(indexVt0,indexVt1));
|
||||
assert(EdgeMap.count(key)>0);
|
||||
int indexV0=EdgeMap[key];
|
||||
|
||||
vcg::face::Pos<FaceType> lastPos=posVec.back();
|
||||
assert(lastPos.IsBorder());
|
||||
|
||||
indexVt0=vcg::tri::Index(primal,lastPos.V());
|
||||
indexVt1=vcg::tri::Index(primal,lastPos.VFlip());
|
||||
key=std::pair<int,int> (std::min(indexVt0,indexVt1),
|
||||
std::max(indexVt0,indexVt1));
|
||||
assert(EdgeMap.count(key)>0);
|
||||
int indexV1=EdgeMap[key];
|
||||
|
||||
vertSeq.push_back(indexV1);
|
||||
vertSeq.push_back(indexV0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateBorderEdgeVert(PolyMeshType &primal,
|
||||
PolyMeshType &dual,
|
||||
std::map<std::pair<int,int>, int> &VertMap)
|
||||
{
|
||||
VertMap.clear();
|
||||
vcg::tri::UpdateFlags<PolyMeshType>::VertexClearB(primal);
|
||||
|
||||
for (size_t i=0;i<primal.face.size();i++)
|
||||
for (int j=0;j<primal.face[i].VN();j++)
|
||||
{
|
||||
int edge_size=primal.face[i].VN();
|
||||
FaceType *nextF=primal.face[i].cFFp(j);
|
||||
|
||||
if (nextF!=&primal.face[i])continue;
|
||||
|
||||
VertexType *v0=primal.face[i].V(j);
|
||||
VertexType *v1=primal.face[i].V((j+1)%edge_size);
|
||||
|
||||
v0->SetB();
|
||||
v1->SetB();
|
||||
|
||||
int V0Index=vcg::tri::Index(primal,v0);
|
||||
int V1Index=vcg::tri::Index(primal,v1);
|
||||
CoordType pos=(v0->P()+v1->P())/2;
|
||||
vcg::tri::Allocator<PolyMeshType>::AddVertex(dual,pos);
|
||||
std::pair<int,int> key(std::min(V0Index,V1Index),
|
||||
std::max(V0Index,V1Index));
|
||||
|
||||
VertMap[key]=dual.vert.size()-1;
|
||||
}
|
||||
}
|
||||
|
||||
static void CreateFaceVert(PolyMeshType &primal,
|
||||
PolyMeshType &dual,
|
||||
|
|
@ -137,7 +81,6 @@ class DualMeshing
|
|||
int num=0;
|
||||
if (snapBorder)//search for border edge
|
||||
{
|
||||
std::vector<CoordType> BorderPos;
|
||||
for (int j=0;j<primal.face[i].VN();j++)
|
||||
{
|
||||
if (!primal.face[i].V(j)->IsB())continue;
|
||||
|
|
@ -145,7 +88,7 @@ class DualMeshing
|
|||
num++;
|
||||
}
|
||||
if (num>0)
|
||||
pos/=num;
|
||||
pos/=num;
|
||||
}
|
||||
|
||||
if (num==0)
|
||||
|
|
@ -153,15 +96,22 @@ class DualMeshing
|
|||
for (int j=0;j<primal.face[i].VN();j++)
|
||||
{
|
||||
pos+=primal.face[i].V(j)->P();
|
||||
int indexV=vcg::tri::Index(primal,primal.face[i].V(j));
|
||||
if (VertFace[indexV]!=-1)continue;
|
||||
VertFace[indexV]=i;
|
||||
}
|
||||
pos/=(ScalarType)primal.face[i].VN();
|
||||
}
|
||||
vcg::tri::Allocator<PolyMeshType>::AddVertex(dual,pos);
|
||||
VertMap[i]=dual.vert.size()-1;
|
||||
dual.vert.back().Q()=i;
|
||||
}
|
||||
|
||||
//then initialize VF first face
|
||||
for (size_t i=0;i<primal.face.size();i++)
|
||||
for (int j=0;j<primal.face[i].VN();j++)
|
||||
{
|
||||
int indexV=vcg::tri::Index(primal,primal.face[i].V(j));
|
||||
if (VertFace[indexV]!=-1)continue;
|
||||
VertFace[indexV]=i;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -177,16 +127,18 @@ public:
|
|||
vcg::tri::RequireFFAdjacency(primal);
|
||||
|
||||
vcg::tri::UpdateTopology<PolyMeshType>::FaceFace(primal);
|
||||
vcg::tri::UpdateFlags<PolyMeshType>::VertexBorderFromFaceAdj(primal);
|
||||
|
||||
std::map<std::pair<int,int>, int> VertEdgeMap;
|
||||
CreateBorderEdgeVert(primal,dual,VertEdgeMap);
|
||||
|
||||
std::cout<<"Creating Dual Vertices"<<std::endl;
|
||||
std::vector<int> VertFaceMap,VertFace;
|
||||
CreateFaceVert(primal,dual,VertFaceMap,VertFace,snapBorder);
|
||||
|
||||
std::cout<<"Creating Dual Faces"<<std::endl;
|
||||
for (size_t i=0;i<primal.vert.size();i++)
|
||||
{
|
||||
if ((snapBorder)&&(primal.vert[i].IsB()))continue;
|
||||
if (primal.vert[i].IsB())continue;
|
||||
|
||||
FaceType *firstF=&primal.face[VertFace[i]];
|
||||
std::vector<int> VertSeq;
|
||||
|
|
@ -195,9 +147,11 @@ public:
|
|||
dual.face.back().Alloc(VertSeq.size());
|
||||
for (size_t j=0;j<VertSeq.size();j++)
|
||||
dual.face.back().V(j)=&dual.vert[VertSeq[j]];
|
||||
dual.face.back().Q()=i;
|
||||
}
|
||||
|
||||
vcg::tri::Clean<PolyMeshType>::RemoveUnreferencedVertex(dual);
|
||||
//finally remove valence 1 vertices on the border
|
||||
vcg::PolygonalAlgorithm<PolyMeshType>::RemoveValence2Vertices(dual);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -199,7 +199,7 @@ private:
|
|||
|
||||
//push the first one
|
||||
SubDEdges.push_back(Edge0);
|
||||
for (size_t i=1;i<Nsub;i++)
|
||||
for (int i=1;i<Nsub;i++)
|
||||
{
|
||||
//find angle interval
|
||||
ScalarType B=StepAngle*(ScalarType)i;
|
||||
|
|
@ -340,8 +340,8 @@ private:
|
|||
IndexF1=(interval+1) % OriginalFace.size();
|
||||
alpha=1;
|
||||
}
|
||||
assert((IndexF0>=0)&&(IndexF0<OriginalFace.size()));
|
||||
assert((IndexF1>=0)&&(IndexF1<OriginalFace.size()));
|
||||
assert((IndexF0>=0)&&(IndexF0<(int)OriginalFace.size()));
|
||||
assert((IndexF1>=0)&&(IndexF1<(int)OriginalFace.size()));
|
||||
|
||||
FaceType* F0=OriginalFace[IndexF0];
|
||||
FaceType* F1=OriginalFace[IndexF1];
|
||||
|
|
@ -394,7 +394,7 @@ private:
|
|||
const TriangleType &t0,
|
||||
const TriangleType &t1,
|
||||
CoordType &Interpolated,
|
||||
size_t &Face)
|
||||
int &Face)
|
||||
{
|
||||
//find smallest edge
|
||||
ScalarType smallestE=std::numeric_limits<ScalarType>::max();
|
||||
|
|
@ -511,7 +511,7 @@ private:
|
|||
directions.clear();
|
||||
faces.clear();
|
||||
|
||||
for (size_t i=0;i<SwapV.size();i++)
|
||||
for (int i=0;i<(int)SwapV.size();i++)
|
||||
{
|
||||
if (i==IndexDel)continue;
|
||||
directions.push_back(SwapV[i]);
|
||||
|
|
@ -619,7 +619,7 @@ public:
|
|||
|
||||
|
||||
CoordType InterpDir;
|
||||
size_t tri_Index=-1;
|
||||
int tri_Index=-1;
|
||||
if ((versef0D1 * versef1D1) < ScalarType(0))
|
||||
{
|
||||
InterpolateDir(Dir1F0,Dir1F1,Bary0,Bary1,t0,t1,InterpDir,tri_Index);
|
||||
|
|
@ -636,7 +636,7 @@ public:
|
|||
assert((tri_Index==0)||(tri_Index==1));
|
||||
int OrigFIndex=((i+tri_Index)%SubFaces.size())/numSub;
|
||||
assert(OrigFIndex>=0);
|
||||
assert(OrigFIndex<OriginalFaces.size());
|
||||
assert(OrigFIndex<(int)OriginalFaces.size());
|
||||
|
||||
FaceType* currF=OriginalFaces[OrigFIndex];
|
||||
//add the data
|
||||
|
|
@ -644,7 +644,7 @@ public:
|
|||
faces.push_back(currF);
|
||||
}
|
||||
if (expVal==-1)return directions.size();
|
||||
if (directions.size()<=expVal)return directions.size();
|
||||
if ((int)directions.size()<=expVal)return directions.size();
|
||||
|
||||
size_t sampledDir=directions.size();
|
||||
int to_erase=directions.size()-expVal;
|
||||
|
|
@ -700,7 +700,7 @@ public:
|
|||
CoordType dirS=CrossVector(f0,dir0);
|
||||
CoordType dirR=vcg::tri::CrossField<MeshType>::Rotate(f0,f1,dirS);
|
||||
///then get the closest upf to K*PI/2 rotations
|
||||
CoordType dir1=f1.cPD1();
|
||||
//CoordType dir1=f1.cPD1();
|
||||
//int ret=I_K_PI(dir1,dirR,f1.cN());
|
||||
CoordType dir[4];
|
||||
CrossVector(f1,dir);
|
||||
|
|
@ -936,8 +936,8 @@ public:
|
|||
const CoordType &t1=f.V(1)->PD1();
|
||||
const CoordType &t2=f.V(2)->PD1();
|
||||
const CoordType &N0=f.V(0)->N();
|
||||
const CoordType &N1=f.V(0)->N();
|
||||
const CoordType &N2=f.V(0)->N();
|
||||
const CoordType &N1=f.V(1)->N();
|
||||
const CoordType &N2=f.V(2)->N();
|
||||
const CoordType &NF=f.N();
|
||||
const CoordType bary=CoordType(0.33333,0.33333,0.33333);
|
||||
CoordType tF0,tF1;
|
||||
|
|
@ -948,7 +948,9 @@ public:
|
|||
SetCrossVector(f,tF0,tF1);
|
||||
|
||||
//then set the magnitudo
|
||||
ScalarType mag1,mag2;
|
||||
ScalarType mag1=0;
|
||||
ScalarType mag2=0;
|
||||
|
||||
for (int i=0;i<3;i++)
|
||||
{
|
||||
vcg::Matrix33<ScalarType> rotN=vcg::RotationMatrix(f.V(i)->N(),f.N());
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#include <vcg/complex/algorithms/closest.h>
|
||||
#include <vcg/complex/algorithms/point_sampling.h>
|
||||
|
||||
#include <wrap/io_trimesh/export_obj.h>
|
||||
|
||||
//define a temporary triangle mesh type
|
||||
class TempFace;
|
||||
class TempVertex;
|
||||
|
|
@ -169,8 +171,7 @@ private:
|
|||
|
||||
|
||||
static bool CollapseBorderSmallEdgesStep(PolyMeshType &poly_m,
|
||||
const ScalarType edge_limit,
|
||||
ScalarType angleDeg=100)
|
||||
const ScalarType edge_limit)
|
||||
{
|
||||
//update topology
|
||||
vcg::tri::UpdateTopology<PolyMeshType>::FaceFace(poly_m);
|
||||
|
|
@ -356,11 +357,19 @@ public:
|
|||
vcg::GetPolyTemplatePos(f,TemplatePos,true);
|
||||
|
||||
CoordType NormT=Normal(TemplatePos);
|
||||
|
||||
//get the normal of vertices
|
||||
CoordType AVN(0,0,0);
|
||||
//CoordType AVN(0,0,0);
|
||||
//CoordType AVN0(0,0,0);
|
||||
CoordType Origin(0,0,0);
|
||||
for (int j=0;j<f.VN();j++)
|
||||
AVN+=f.V(j)->N();
|
||||
// for (int j=0;j<f.VN();j++)
|
||||
// AVN0=AVN0+f.V(j)->N();
|
||||
|
||||
CoordType AVN=vcg::PolygonNormal(f);
|
||||
//AVN0.Normalize();
|
||||
// std::cout<<"AVN "<<AVN.X()<<","<<AVN.Y()<<","<<AVN.Z()<<std::endl;
|
||||
// std::cout<<"AVN0 "<<AVN0.X()<<","<<AVN0.Y()<<","<<AVN0.Z()<<std::endl;
|
||||
// std::cout<<"NormT "<<NormT.X()<<","<<NormT.Y()<<","<<NormT.Z()<<std::endl;
|
||||
|
||||
for (size_t j=0;j<TemplatePos.size();j++)
|
||||
Origin+=TemplatePos[j];
|
||||
|
|
@ -374,9 +383,9 @@ public:
|
|||
//apply transformation
|
||||
for (size_t j=0;j<TemplatePos.size();j++)
|
||||
{
|
||||
TemplatePos[j]-=Origin;
|
||||
TemplatePos[j]=TemplatePos[j]-Origin;
|
||||
TemplatePos[j]=Rot*TemplatePos[j];
|
||||
TemplatePos[j]+=Origin;
|
||||
TemplatePos[j]=TemplatePos[j]+Origin;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -402,12 +411,15 @@ public:
|
|||
|
||||
ScalarType AvgArea=MeshArea/(ScalarType)poly_m.face.size();
|
||||
|
||||
PolyMeshType TestM;
|
||||
|
||||
for (size_t s=0;s<(size_t)relax_step;s++)
|
||||
{
|
||||
//initialize the accumulation vector
|
||||
std::vector<CoordType> avgPos(poly_m.vert.size(),CoordType(0,0,0));
|
||||
std::vector<ScalarType> weightSum(poly_m.vert.size(),0);
|
||||
//then compute the templated positions
|
||||
|
||||
for (size_t i=0;i<poly_m.face.size();i++)
|
||||
{
|
||||
std::vector<typename PolygonType::CoordType> TemplatePos;
|
||||
|
|
@ -416,8 +428,7 @@ public:
|
|||
ScalarType val=vcg::PolyArea(poly_m.face[i]);
|
||||
if (val<(AvgArea*0.00001))
|
||||
val=(AvgArea*0.00001);
|
||||
ScalarType W=1.0/val;//poly_m.face[i].Q();
|
||||
//ScalarType W=1;
|
||||
ScalarType W=1.0/val;
|
||||
|
||||
for (size_t j=0;j<TemplatePos.size();j++)
|
||||
{
|
||||
|
|
@ -426,7 +437,9 @@ public:
|
|||
//sum up contributes
|
||||
avgPos[IndexV]+=Pos*W;
|
||||
weightSum[IndexV]+=W;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//get the laplacian contribute
|
||||
|
|
@ -440,7 +453,9 @@ public:
|
|||
// if (alpha>1)alpha=1;
|
||||
// if (isnan(alpha))alpha=1;
|
||||
CoordType newP=avgPos[i]/weightSum[i];
|
||||
//std::cout<<"W "<<weightSum[i]<<std::endl;
|
||||
newP=newP*(1-alpha)+AvVert[i]*alpha;
|
||||
//newP=AvVert[i];
|
||||
if ((fixB)&&(poly_m.vert[i].IsB()))continue;
|
||||
if ((FixS)&&(poly_m.vert[i].IsS()))continue;
|
||||
poly_m.vert[i].P()=poly_m.vert[i].P()*Damp+
|
||||
|
|
@ -900,49 +915,6 @@ public:
|
|||
return MeshArea;
|
||||
}
|
||||
|
||||
// static void InitQualityVertVoronoiArea(PolyMeshType &poly_m)
|
||||
// {
|
||||
// for (size_t i=0;i<poly_m.vert.size();i++)
|
||||
// poly_m.vert[i].Q()=0;
|
||||
|
||||
// //set the sum of angle for each face
|
||||
|
||||
// std::vector<ScalarType> SumAngle(poly_m.face.size(),0);
|
||||
// for (size_t i=0;i<poly_m.face.size();i++)
|
||||
// {
|
||||
// size_t sizeV=poly_m.face[i].VN()-1;
|
||||
// for (size_t j=0;j<sizeV;j++)
|
||||
// {
|
||||
// CoordType P0=poly_m.face[i].P((j+1)%sizeV);
|
||||
// CoordType P1=poly_m.face[i].P(j);
|
||||
// CoordType P2=poly_m.face[i].P1(j);
|
||||
// CoordType dir0=P0-P1;
|
||||
// CoordType dir1=P2-P1;
|
||||
// dir0.Normalize();
|
||||
// dir1.Normalize();
|
||||
// SumAngle[i]+=vcg::Angle(dir0,dir1);
|
||||
// }
|
||||
// }
|
||||
|
||||
// for (size_t i=0;i<poly_m.face.size();i++)
|
||||
// {
|
||||
// ScalarType AreaF=vcg::PolyArea(poly_m.face[i]);
|
||||
// size_t sizeV=poly_m.face[i].VN()-1;
|
||||
// for (size_t j=0;j<poly_m.face[i].VN();j++)
|
||||
// {
|
||||
// CoordType P0=poly_m.face[i].P((j+1)%sizeV);
|
||||
// CoordType P1=poly_m.face[i].P(j);
|
||||
// CoordType P2=poly_m.face[i].P1(j);
|
||||
// CoordType dir0=P0-P1;
|
||||
// CoordType dir1=P2-P1;
|
||||
// dir0.Normalize();
|
||||
// dir1.Normalize();
|
||||
// ScalarType CurrAngle=vcg::Angle(dir0,dir1);
|
||||
// poly_m.face[i].V(j)->Q()+=AreaF * CurrAngle/SumAngle[i];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
static void InitQualityVertVoronoiArea(PolyMeshType &poly_m)
|
||||
{
|
||||
for (size_t i=0;i<poly_m.vert.size();i++)
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ static void FaceFromVertex( MeshType &m)
|
|||
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
|
||||
{
|
||||
(*fi).Q() =0;
|
||||
for (size_t i=0;i<(*fi).VN();i++)
|
||||
for (int i=0;i<(*fi).VN();i++)
|
||||
(*fi).Q() += (*fi).V(i)->Q();
|
||||
(*fi).Q()/=(FaceQualityType)(*fi).VN();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1080,6 +1080,7 @@ public:
|
|||
h._sizeof = sizeof(ATTR_TYPE);
|
||||
h._padding = 0;
|
||||
h._handle = new SimpleTempData<VertContainer,ATTR_TYPE>(m.vert);
|
||||
h._type = typeid(ATTR_TYPE);
|
||||
m.attrn++;
|
||||
h.n_attr = m.attrn;
|
||||
std::pair < AttrIterator , bool> res = m.vert_attr.insert(h);
|
||||
|
|
@ -1221,6 +1222,7 @@ public:
|
|||
h._padding = 0;
|
||||
// h._typename = typeid(ATTR_TYPE).name();
|
||||
h._handle = new SimpleTempData<EdgeContainer,ATTR_TYPE>(m.edge);
|
||||
h._type = typeid(ATTR_TYPE);
|
||||
m.attrn++;
|
||||
h.n_attr = m.attrn;
|
||||
std::pair < AttrIterator , bool> res = m.edge_attr.insert(h);
|
||||
|
|
@ -1344,6 +1346,7 @@ public:
|
|||
h._sizeof = sizeof(ATTR_TYPE);
|
||||
h._padding = 0;
|
||||
h._handle = new SimpleTempData<FaceContainer,ATTR_TYPE>(m.face);
|
||||
h._type = typeid(ATTR_TYPE);
|
||||
m.attrn++;
|
||||
h.n_attr = m.attrn;
|
||||
std::pair < AttrIterator , bool> res = m.face_attr.insert(h);
|
||||
|
|
@ -1462,6 +1465,7 @@ public:
|
|||
h._sizeof = sizeof(ATTR_TYPE);
|
||||
h._padding = 0;
|
||||
h._handle = new Attribute<ATTR_TYPE>();
|
||||
h._type = typeid(ATTR_TYPE);
|
||||
m.attrn++;
|
||||
h.n_attr = m.attrn;
|
||||
std::pair < AttrIterator , bool> res = m.mesh_attr.insert(h);
|
||||
|
|
|
|||
|
|
@ -37,10 +37,12 @@ public:
|
|||
int _padding; // padding (used only with VMI loading)
|
||||
|
||||
int n_attr; // unique ID of the attribute
|
||||
|
||||
std::type_index _type;
|
||||
void Resize(size_t sz){((SimpleTempDataBase *)_handle)->Resize(sz);}
|
||||
void Reorder(std::vector<size_t> & newVertIndex){((SimpleTempDataBase *)_handle)->Reorder(newVertIndex);}
|
||||
bool operator<(const PointerToAttribute b) const { return(_name.empty()&&b._name.empty())?(_handle < b._handle):( _name < b._name);}
|
||||
|
||||
PointerToAttribute(): _type(typeid(void)) { };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <stdexcept>
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
#include <typeindex>
|
||||
#include <wrap/callback.h>
|
||||
#include <vcg/complex/exception.h>
|
||||
#include <vcg/container/simple_temporary_data.h>
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
typename VALUE_TYPE::ColorType wc[3];
|
||||
typename VALUE_TYPE::WedgeColorType wc[3];
|
||||
};
|
||||
|
||||
class WedgeNormalTypePack {
|
||||
|
|
@ -111,7 +111,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
typename VALUE_TYPE::NormalType wn[3];
|
||||
typename VALUE_TYPE::WedgeNormalType wn[3];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ public:
|
|||
T::Dealloc();
|
||||
}
|
||||
|
||||
static bool HasVertexRef() { return true; }
|
||||
static bool HasFVAdjacency() { return true; }
|
||||
static void Name(std::vector<std::string> & name){name.push_back(std::string("PFVAdj"));T::Name(name);}
|
||||
|
||||
|
|
|
|||
|
|
@ -323,6 +323,7 @@ void Add( const Point3<BoxScalarType> & p, const BoxScalarType radius )
|
|||
|
||||
template <class T> Box3<T> Point3<T>::GetBBox(Box3<T> &bb) const {
|
||||
bb.Set( *this );
|
||||
return bb;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -74,10 +74,11 @@ public:
|
|||
const ScalarType &size,
|
||||
const bool oneside,
|
||||
const bool onlyPD1,
|
||||
const ScalarType maxN)
|
||||
const ScalarType maxN,
|
||||
const ScalarType minN)
|
||||
{
|
||||
CoordType center=(f.cP(0)+f.cP(1)+f.cP(2))/3;
|
||||
CoordType normal=f.cN();
|
||||
//CoordType normal=f.cN();
|
||||
CoordType dir[4];
|
||||
vcg::tri::CrossField<MeshType>::CrossVector(f,dir);
|
||||
|
||||
|
|
@ -92,10 +93,10 @@ public:
|
|||
ScalarType IntervW=MaxW-MinW;
|
||||
if (Norm0>maxN)Norm0=maxN;
|
||||
if (Norm1>maxN)Norm1=maxN;
|
||||
vcg::Color4b Col0=vcg::Color4b::ColorRamp(0,maxN,Norm0);
|
||||
vcg::Color4b Col1=vcg::Color4b::ColorRamp(0,maxN,Norm1);
|
||||
ScalarType W0=(Norm0/maxN)*IntervW+MinW;
|
||||
ScalarType W1=(Norm1/maxN)*IntervW+MinW;
|
||||
vcg::Color4b Col0=vcg::Color4b::ColorRamp(minN,maxN,Norm0);
|
||||
vcg::Color4b Col1=vcg::Color4b::ColorRamp(minN,maxN,Norm1);
|
||||
ScalarType W0=(Norm0/(maxN-minN))*IntervW+MinW;
|
||||
ScalarType W1=(Norm1/(maxN-minN))*IntervW+MinW;
|
||||
GLDrawField(dir,center,size,W0,W1,Col0,Col1,oneside,onlyPD1);
|
||||
}
|
||||
}
|
||||
|
|
@ -132,7 +133,8 @@ public:
|
|||
bool onlyPD1,
|
||||
bool oneside,
|
||||
ScalarType GlobalScale=0.002,
|
||||
const ScalarType maxN=0)
|
||||
const ScalarType maxN=0,
|
||||
const ScalarType minN=0)
|
||||
{
|
||||
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
|
|
@ -144,7 +146,7 @@ public:
|
|||
for (unsigned int i=0;i<mesh.face.size();i++)
|
||||
{
|
||||
if (mesh.face[i].IsD())continue;
|
||||
GLDrawSingleFaceField(mesh.face[i],size,oneside,onlyPD1,maxN);
|
||||
GLDrawSingleFaceField(mesh.face[i],size,oneside,onlyPD1,maxN,minN);
|
||||
}
|
||||
glPopAttrib();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,6 +217,20 @@ namespace vcg
|
|||
return res;
|
||||
}
|
||||
|
||||
size_t serialize(std::string& str)
|
||||
{
|
||||
for (unsigned int ii = 0; ii < ATT_NAMES_DERIVED_CLASS::enumArity(); ++ii)
|
||||
str.append(((_atts[ii]) ? "1" : "0"));
|
||||
return ATT_NAMES_DERIVED_CLASS::enumArity();
|
||||
}
|
||||
|
||||
void deserialize(const std::string& str)
|
||||
{
|
||||
std::bitset<ATT_NAMES_DERIVED_CLASS::ATT_ARITY> bset(str);
|
||||
for (unsigned int ii = 0; ii < ATT_NAMES_DERIVED_CLASS::enumArity(); ++ii)
|
||||
_atts[ATT_NAMES_DERIVED_CLASS::enumArity() - ii - 1] = bset[ii];
|
||||
}
|
||||
|
||||
//template<typename MESHTYPE>
|
||||
//static void computeARequestedAttributesSetCompatibleWithMesh(const MESHTYPE& mesh,const PRIMITIVE_MODALITY_MASK,RenderingAtts<ATT_NAMES_DERIVED_CLASS>& rqatt)
|
||||
//{
|
||||
|
|
@ -330,6 +344,8 @@ namespace vcg
|
|||
class InternalRendAtts : public RenderingAtts<INT_ATT_NAMES>
|
||||
{
|
||||
public:
|
||||
typedef INT_ATT_NAMES AttName;
|
||||
|
||||
InternalRendAtts()
|
||||
:RenderingAtts<INT_ATT_NAMES>()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ namespace vcg
|
|||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void copyData(const RenderingModalityGLOptions& opts)
|
||||
{
|
||||
|
|
@ -156,6 +155,9 @@ namespace vcg
|
|||
class PerViewData : public GLMeshAttributesInfo
|
||||
{
|
||||
public:
|
||||
|
||||
typedef GL_OPTIONS_DERIVED_TYPE GLOptionsType;
|
||||
|
||||
PerViewData()
|
||||
:_pmmask(),_intatts(PR_ARITY),_glopts(NULL)
|
||||
{
|
||||
|
|
@ -260,6 +262,53 @@ namespace vcg
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void serialize(std::string& str)
|
||||
{
|
||||
str.append(_pmmask.to_string());
|
||||
for (typename PerRendModData::iterator it = _intatts.begin(); it != _intatts.end(); ++it)
|
||||
{
|
||||
std::string s;
|
||||
it->serialize(s);
|
||||
str.append(s);
|
||||
}
|
||||
std::string s;
|
||||
_glopts->serialize(s);
|
||||
str.append(s);
|
||||
}
|
||||
|
||||
bool deserialize(const std::string& str)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
std::string token[6];
|
||||
token[0] = str.substr(pos, _pmmask.size());
|
||||
if (token[0].length() < _pmmask.size())
|
||||
return false;
|
||||
int i = 1;
|
||||
pos = _pmmask.size();
|
||||
for (typename PerRendModData::iterator it = _intatts.begin(); it != _intatts.end(); ++it, i++)
|
||||
{
|
||||
token[i] = str.substr(pos, InternalRendAtts::AttName::enumArity());
|
||||
if (token[i].length() < InternalRendAtts::AttName::enumArity())
|
||||
return false;
|
||||
pos = pos + InternalRendAtts::AttName::enumArity();
|
||||
}
|
||||
if (_glopts != NULL)
|
||||
{
|
||||
int size = _glopts->serialize(std::string());
|
||||
token[i] = str.substr(pos, size);
|
||||
if (token[i].length() < size)
|
||||
return false;
|
||||
}
|
||||
_pmmask = PRIMITIVE_MODALITY_MASK(token[0]);
|
||||
i = 1;
|
||||
for (typename PerRendModData::iterator it = _intatts.begin(); it != _intatts.end(); ++it, i++)
|
||||
it->deserialize(token[i]);
|
||||
if (_glopts != NULL)
|
||||
_glopts->deserialize(token[i]);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
template<typename MESH_TYPE,typename UNIQUE_VIEW_ID_TYPE, typename XX_GL_OPTIONS_DERIVED_TYPE> friend class NotThreadSafeGLMeshAttributesMultiViewerBOManager;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include <igl/cut_mesh_from_singularities.h>
|
||||
#include <igl/find_cross_field_singularities.h>
|
||||
#include <igl/compute_frame_field_bisectors.h>
|
||||
#include <igl/comiso/miq.h>
|
||||
#include <igl/copyleft/comiso/miq.h>
|
||||
#include <vcg/complex/algorithms/parametrization/uv_utils.h>
|
||||
#include <vcg/complex/algorithms/mesh_to_matrix.h>
|
||||
|
||||
|
|
@ -74,6 +74,8 @@ public:
|
|||
bool crease_as_feature;
|
||||
//true if roound selected vert
|
||||
bool round_selected;
|
||||
//the anisotropy in MIQ sense (see paper)
|
||||
double miqAnisotropy;
|
||||
|
||||
MIQParameters()
|
||||
{
|
||||
|
|
@ -89,6 +91,7 @@ public:
|
|||
Ndir=4;
|
||||
crease_thr=0.2;
|
||||
hexaLine=false;
|
||||
miqAnisotropy=1;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -163,9 +166,9 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
igl::miq(V,F,X1,X2,UV,FUV,MiqP.gradient,MiqP.stiffness,MiqP.directRound,
|
||||
igl::copyleft::comiso::miq(V,F,X1,X2,UV,FUV,MiqP.gradient,MiqP.stiffness,MiqP.directRound,
|
||||
MiqP.stiffness_iter,MiqP.local_iter,MiqP.doRound,MiqP.round_singularities,
|
||||
extra_round,hard_features);
|
||||
extra_round,hard_features,MiqP.miqAnisotropy);
|
||||
|
||||
// then copy UV
|
||||
for (size_t i=0;i<trimesh.face.size();i++)
|
||||
|
|
@ -287,7 +290,7 @@ private:
|
|||
// MMatch,isSingularity,singularityIndex,Seams,
|
||||
// UV,FUV,MiqP.gradient,MiqP.stiffness,MiqP.directRound,
|
||||
// MiqP.stiffness_iter,MiqP.local_iter,MiqP.doRound,MiqP.round_singularities,extra_round,hard_features);
|
||||
igl::miq(V,F,X1_combed,X2_combed,
|
||||
igl::copyleft::comiso::miq(V,F,X1_combed,X2_combed,
|
||||
UV,FUV,MiqP.gradient,MiqP.stiffness,MiqP.directRound,
|
||||
MiqP.stiffness_iter,MiqP.local_iter,MiqP.doRound,MiqP.round_singularities,extra_round,hard_features);
|
||||
|
||||
|
|
@ -336,8 +339,8 @@ public:
|
|||
static void MIQParametrize(MeshType &trimesh,
|
||||
MIQParameters &MiqP)
|
||||
{
|
||||
if (MiqP.crease_as_feature)
|
||||
SetCreases(trimesh,MiqP.crease_thr);
|
||||
// if (MiqP.crease_as_feature)
|
||||
// SetCreases(trimesh,MiqP.crease_thr);
|
||||
|
||||
if (MiqP.Ndir==4)
|
||||
CrossFieldParam(trimesh,MiqP);
|
||||
|
|
|
|||
|
|
@ -341,11 +341,8 @@ public:
|
|||
Ndir=4;
|
||||
curvRing=2;
|
||||
alpha_curv=0.0;
|
||||
|
||||
align_borders=false;
|
||||
|
||||
SmoothM=SMMiq;
|
||||
|
||||
sharp_thr=0.0;
|
||||
curv_thr=0.4;
|
||||
}
|
||||
|
|
@ -488,10 +485,10 @@ public:
|
|||
//for the moment only cross and line field
|
||||
|
||||
//initialize direction by curvature if needed
|
||||
if ((SParam.alpha_curv>0)||
|
||||
(SParam.sharp_thr>0)||
|
||||
(SParam.curv_thr>0))
|
||||
InitByCurvature(mesh,SParam.curvRing);
|
||||
// if ((SParam.alpha_curv>0)||
|
||||
// (SParam.sharp_thr>0)||
|
||||
// (SParam.curv_thr>0))
|
||||
InitByCurvature(mesh,SParam.curvRing);
|
||||
|
||||
SelectConstraints(mesh,SParam);
|
||||
//then do the actual smooth
|
||||
|
|
|
|||
|
|
@ -109,33 +109,33 @@ public:
|
|||
printf("%d\n",period);
|
||||
fscanf(f,"%c",&final);
|
||||
fseek(f, -1, SEEK_CUR);
|
||||
printf("%s\n",&final[0]);
|
||||
//printf("%s\n",&final[0]);
|
||||
}while(strcmp(final,"\"")!=0);
|
||||
|
||||
// printf("%s\n",skipstr);
|
||||
fflush(stdout);
|
||||
// for (int i=0;i<mesh.fn;i++)
|
||||
// {
|
||||
// int i0=-1;
|
||||
// int i1=-1;
|
||||
// int i2=-1;
|
||||
// double u0,v0,u1,v1,u2,v2;
|
||||
// int readed1=fscanf(f,"%d %d %d %lf %lf %lf %lf %lf %lf",&i0,&i1,&i2,&u0,&v0,&u1,&v1,&u2,&v2);
|
||||
// assert(readed1==9);
|
||||
// vcg::Point2<ScalarType> UV[3];
|
||||
// UV[0]= vcg::Point2<ScalarType>(u0,v0);
|
||||
// UV[1]= vcg::Point2<ScalarType>(u1,v1);
|
||||
// UV[2]= vcg::Point2<ScalarType>(u2,v2);
|
||||
// CoordType dir1;
|
||||
// CoordType dir2;
|
||||
// vcg::tri::CrossField<MeshType>::GradientToCross(mesh.face[i],UV[0],UV[1],UV[2],dir1,dir2);
|
||||
// dir1.Normalize();
|
||||
// dir2.Normalize();
|
||||
// mesh.face[i].PD1()=dir1;
|
||||
// mesh.face[i].PD2()=dir2;
|
||||
// }
|
||||
// fclose(f);
|
||||
// return true;
|
||||
for (int i=0;i<mesh.fn;i++)
|
||||
{
|
||||
int i0=-1;
|
||||
int i1=-1;
|
||||
int i2=-1;
|
||||
double u0,v0,u1,v1,u2,v2;
|
||||
int readed1=fscanf(f,"%d %d %d %lf %lf %lf %lf %lf %lf",&i0,&i1,&i2,&u0,&v0,&u1,&v1,&u2,&v2);
|
||||
assert(readed1==9);
|
||||
vcg::Point2<ScalarType> UV[3];
|
||||
UV[0]= vcg::Point2<ScalarType>(u0,v0);
|
||||
UV[1]= vcg::Point2<ScalarType>(u1,v1);
|
||||
UV[2]= vcg::Point2<ScalarType>(u2,v2);
|
||||
CoordType dir1;
|
||||
CoordType dir2;
|
||||
vcg::tri::CrossField<MeshType>::GradientToCross(mesh.face[i],UV[0],UV[1],UV[2],dir1,dir2);
|
||||
dir1.Normalize();
|
||||
dir2.Normalize();
|
||||
mesh.face[i].PD1()=dir1;
|
||||
mesh.face[i].PD2()=dir2;
|
||||
}
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
///load a field on the mesh, it could be a vfield file (per vertex)
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ struct LoadPly_VertAux
|
|||
S p[3];
|
||||
S n[3];
|
||||
int flags;
|
||||
float q; // the confidence
|
||||
S q; // the confidence
|
||||
float intensity;
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
|
|
@ -189,7 +189,7 @@ static const PropDescriptor &VertDesc(int i)
|
|||
/*27*/ {"vertex", "nx", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) ,0,0,0,0,0 ,0},
|
||||
/*28*/ {"vertex", "ny", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 1*sizeof(ScalarType),0,0,0,0,0 ,0},
|
||||
/*29*/ {"vertex", "nz", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,n) + 2*sizeof(ScalarType),0,0,0,0,0 ,0},
|
||||
/*30*/ {"vertex", "radius", ply::T_DOUBLE, ply::T_FLOAT, offsetof(LoadPly_VertAux<ScalarType>,radius),0,0,0,0,0 ,0},
|
||||
/*30*/ {"vertex", "radius", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,radius),0,0,0,0,0 ,0},
|
||||
/*31*/ {"vertex", "quality", ply::T_DOUBLE, PlyType<ScalarType>(),offsetof(LoadPly_VertAux<ScalarType>,q),0,0,0,0,0 ,0}
|
||||
};
|
||||
return pv[i];
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ namespace nanoply
|
|||
{ PlyEntity::NNP_K2DIR, NameVector({ "k2dir" }) },
|
||||
{ PlyEntity::NNP_EDGE_V1, NameVector({ "vertex1", "v1" }) },
|
||||
{ PlyEntity::NNP_EDGE_V2, NameVector({ "vertex2", "v2" }) },
|
||||
{ PlyEntity::NNP_FACE_VERTEX_LIST, NameVector({ "vertex_index", "vertex_indices" }) },
|
||||
{ PlyEntity::NNP_FACE_VERTEX_LIST, NameVector({ "vertex_indices", "vertex_index" }) },
|
||||
{ PlyEntity::NNP_FACE_WEDGE_COLOR, NameVector({ "color" }) },
|
||||
{ PlyEntity::NNP_FACE_WEDGE_NORMAL, NameVector({ "normal" }) },
|
||||
{ PlyEntity::NNP_FACE_WEDGE_TEX, NameVector({ "texcoord" }) }
|
||||
|
|
@ -463,7 +463,7 @@ namespace nanoply
|
|||
if (fileStream.fail())
|
||||
return false;
|
||||
bufferOffset = 0;
|
||||
//fileStream.setf(std::ios::fixed, std::ios::floatfield);
|
||||
fileStream.setf(std::ios::fixed, std::ios::floatfield);
|
||||
//fileStream.precision(7);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -476,7 +476,7 @@ namespace nanoply
|
|||
std::getline(fileStream, line);
|
||||
std::transform(line.begin(), line.end(), line.begin(), ::tolower);
|
||||
last = false;
|
||||
if (line == "end_header")
|
||||
if (line.find("end_header") != std::string::npos)
|
||||
last = true;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -583,6 +583,10 @@ namespace nanoply
|
|||
PlyEntity elem; /**< Property entity. */
|
||||
bool validToWrite; /**< Property validity (necessary to write the header). */
|
||||
|
||||
|
||||
inline PlyProperty() {}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor that sets the type and the entity of a standard PLY property.
|
||||
*
|
||||
|
|
@ -1139,7 +1143,7 @@ namespace nanoply
|
|||
token = strtok(tempStr, " \t");
|
||||
if (strstr(token, "element") == NULL)
|
||||
return false;
|
||||
token = strtok(0, " \t\n");
|
||||
token = strtok(0, " \t\r\n");
|
||||
name = std::string(token);
|
||||
plyElem = PlyElemEntity::NNP_UNKNOWN_ELEM;
|
||||
ElementMapIterator iter = mapElem.begin();
|
||||
|
|
@ -1162,7 +1166,7 @@ namespace nanoply
|
|||
}
|
||||
iter++;
|
||||
}
|
||||
token = strtok(0, " \t\n");
|
||||
token = strtok(0, " \t\r\n");
|
||||
cnt = atoi(token);
|
||||
for (size_t i = 0; i < propStr.size(); i++)
|
||||
if (!AddProperty(propStr[i]))
|
||||
|
|
@ -1512,7 +1516,7 @@ namespace nanoply
|
|||
{
|
||||
this->filename = filename;
|
||||
this->errInfo = NNP_OK;
|
||||
std::ifstream input(filename, std::ios::binary);
|
||||
std::ifstream input(filename);
|
||||
if (!input.good())
|
||||
{
|
||||
this->errInfo = NNP_UNABLE_TO_OPEN;
|
||||
|
|
@ -1732,7 +1736,7 @@ namespace nanoply
|
|||
* @param _s Name of the PlyProperty.
|
||||
* @param _b Pointer to the memory location that contains the data of the property.
|
||||
*/
|
||||
inline DescriptorInterface(std::string& _s, void *_b) :curPos(0), elem(PlyEntity::NNP_UNKNOWN_ENTITY), name(_s), base(_b){};
|
||||
inline DescriptorInterface(const std::string& _s, void *_b) :curPos(0), elem(PlyEntity::NNP_UNKNOWN_ENTITY), name(_s), base(_b){};
|
||||
|
||||
/**
|
||||
* Restart the descriptor.
|
||||
|
|
@ -1990,18 +1994,336 @@ namespace nanoply
|
|||
|
||||
|
||||
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
class DescriptorHelper
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
template<typename C>
|
||||
static void ReadBinary(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
{
|
||||
char * buffer = nullptr;
|
||||
int size;
|
||||
int count = prop.CountValue();
|
||||
int typeSize = prop.TypeSize();
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
{
|
||||
file.ReadBinaryData(buffer, sizeof(char));
|
||||
const int cntList = int(*(reinterpret_cast<unsigned char *>(buffer)));
|
||||
size = typeSize * cntList;
|
||||
count = cntList;
|
||||
}
|
||||
else
|
||||
size = typeSize * count;
|
||||
file.ReadBinaryData(buffer, size);
|
||||
|
||||
if (typeSize > 1 && fixEndian)
|
||||
adjustEndianess(reinterpret_cast<unsigned char *>(buffer), typeSize, count);
|
||||
|
||||
unsigned char* baseProp = (unsigned char*)descr.base + descr.curPos * sizeof(ContainerType);
|
||||
C* temp = (C*)buffer;
|
||||
if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA))
|
||||
{
|
||||
float norm = 1.0f;
|
||||
if (std::is_same<ScalarType, float>::value && std::is_same<C, unsigned char>::value)
|
||||
norm = 1.0f / 255.0f;
|
||||
else if (std::is_same<ScalarType, unsigned char>::value && std::is_same<C, float>::value)
|
||||
norm = 255.0f;
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
*((ScalarType *)(baseProp + i * sizeof(ScalarType))) = ScalarType(temp[i] * norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
*((ScalarType *)(baseProp + i * sizeof(ScalarType))) = ScalarType(temp[i]);
|
||||
}
|
||||
++(descr.curPos);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static void ReadAscii(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop)
|
||||
{
|
||||
int count = prop.CountValue();
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
file.ReadAsciiData(count);
|
||||
|
||||
C* temp = new C[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
file.ReadAsciiData(temp[i]);
|
||||
|
||||
unsigned char* baseProp = (unsigned char*)descr.base + descr.curPos * sizeof(ContainerType);
|
||||
if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA))
|
||||
{
|
||||
float norm = 1.0f;
|
||||
if (std::is_same<ScalarType, float>::value && prop.type == NNP_UINT8)
|
||||
norm = 1.0f / 255.0f;
|
||||
else if (std::is_same<ScalarType, unsigned char>::value && prop.type == NNP_FLOAT32)
|
||||
norm = 255.0f;
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
*((ScalarType *)(baseProp + i * sizeof(ScalarType))) = ScalarType(temp[i] * norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
*((ScalarType *)(baseProp + i * sizeof(ScalarType))) = ScalarType(temp[i]);
|
||||
}
|
||||
delete[] temp;
|
||||
++(descr.curPos);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static void WriteBinary(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
{
|
||||
(void)fixEndian;
|
||||
int count = prop.CountValue();
|
||||
C data[VectorSize];
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
{
|
||||
if (prop.IsSigned())
|
||||
{
|
||||
char listSize = (char)VectorSize;
|
||||
file.WriteBinaryData(&listSize, 1);
|
||||
count = VectorSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char listSize = (unsigned char)VectorSize;
|
||||
file.WriteBinaryData(&listSize, 1);
|
||||
count = VectorSize;
|
||||
}
|
||||
}
|
||||
|
||||
C temp = 0;
|
||||
unsigned char* baseProp = (unsigned char*)descr.base + descr.curPos * sizeof(ContainerType);
|
||||
if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA))
|
||||
{
|
||||
float norm = 1.0f;
|
||||
if (std::is_same<ScalarType, float>::value && std::is_same<C, unsigned char>::value)
|
||||
norm = 255.0f;
|
||||
else if (std::is_same<ScalarType, unsigned char>::value && std::is_same<C, float>::value)
|
||||
norm = 1.0f / 255.0f;
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
data[i] = (C)((*(ScalarType*)(baseProp + i * sizeof(ScalarType))) * norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
data[i] = (C)((*(ScalarType*)(baseProp + i * sizeof(ScalarType))));
|
||||
}
|
||||
|
||||
if (sizeof(C) > 1 && fixEndian)
|
||||
adjustEndianess((unsigned char*)data, sizeof(C), std::min(VectorSize, count));
|
||||
|
||||
file.WriteBinaryData(data, sizeof(C)*std::min(VectorSize, count));
|
||||
for (int i = 0; i < (count - VectorSize); i++)
|
||||
file.WriteBinaryData(&temp, sizeof(C));
|
||||
++(descr.curPos);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static void WriteAscii(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop)
|
||||
{
|
||||
int count = prop.CountValue();
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
{
|
||||
if (prop.IsSigned())
|
||||
{
|
||||
int listSize = (int)VectorSize;
|
||||
file.WriteAsciiData(listSize);
|
||||
count = VectorSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int listSize = (unsigned int)VectorSize;
|
||||
file.WriteAsciiData(listSize);
|
||||
count = VectorSize;
|
||||
}
|
||||
file.WriteAsciiData(std::string(" "));
|
||||
}
|
||||
|
||||
C data[VectorSize];
|
||||
unsigned char* baseProp = (unsigned char*)descr.base + descr.curPos * sizeof(ContainerType);
|
||||
if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA))
|
||||
{
|
||||
float norm = 1.0;
|
||||
if (std::is_same<ScalarType, float>::value && prop.type == NNP_UINT8)
|
||||
norm = 255.0f;
|
||||
else if (std::is_same<ScalarType, unsigned char>::value && prop.type == NNP_FLOAT32)
|
||||
norm = 1.0f / 255.0f;
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
data[i] = (C)((*(ScalarType*)(baseProp + i * sizeof(ScalarType))) * norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
data[i] = (C)((*(ScalarType*)(baseProp + i * sizeof(ScalarType))));
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < (count - VectorSize); i++)
|
||||
data[i] = 0;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
file.WriteAsciiData(data[i]);
|
||||
if (i < count - 1)
|
||||
file.WriteAsciiData(std::string(" "));
|
||||
}
|
||||
++(descr.curPos);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template<class ContainerType, typename ScalarType>
|
||||
class DescriptorHelper<ContainerType, 0, ScalarType>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
template<typename C>
|
||||
static void ReadBinary(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
{
|
||||
char * buffer = nullptr;
|
||||
int size;
|
||||
int count = prop.CountValue();
|
||||
int typeSize = prop.TypeSize();
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
{
|
||||
file.ReadBinaryData(buffer, sizeof(char));
|
||||
const int cntList = int(*(reinterpret_cast<unsigned char *>(buffer)));
|
||||
size = typeSize * cntList;
|
||||
count = cntList;
|
||||
}
|
||||
else
|
||||
size = typeSize * count;
|
||||
file.ReadBinaryData(buffer, size);
|
||||
|
||||
if (typeSize > 1 && fixEndian)
|
||||
adjustEndianess(reinterpret_cast<unsigned char *>(buffer), typeSize, count);
|
||||
|
||||
C* temp = (C*)buffer;
|
||||
|
||||
ContainerType* container = (ContainerType*)((unsigned char*)descr.base + descr.curPos * sizeof(ContainerType));
|
||||
(*container).resize(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
(*container)[i] = (ScalarType)(temp[i]);
|
||||
++(descr.curPos);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static void ReadAscii(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop)
|
||||
{
|
||||
int count = prop.CountValue();
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
file.ReadAsciiData(count);
|
||||
|
||||
C* temp = new C[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
file.ReadAsciiData(temp[i]);
|
||||
|
||||
ContainerType* container = (ContainerType*)((unsigned char*)descr.base + descr.curPos * sizeof(ContainerType));
|
||||
(*container).resize(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
(*container)[i] = (ScalarType)(temp[i]);
|
||||
delete[] temp;
|
||||
++(descr.curPos);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static void WriteBinary(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
{
|
||||
size_t count = prop.CountValue();
|
||||
ContainerType* list = (ContainerType*)((unsigned char*)descr.base + descr.curPos * sizeof(ContainerType));
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
{
|
||||
if (prop.IsSigned())
|
||||
{
|
||||
char listSize = (char)list->size();
|
||||
file.WriteBinaryData(&listSize, 1);
|
||||
count = list->size();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char listSize = (unsigned char)list->size();
|
||||
file.WriteBinaryData(&listSize, 1);
|
||||
count = list->size();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<C> data(count);
|
||||
|
||||
for (int i = 0; i < std::min(count, list->size()); i++)
|
||||
data[i] = (C)((*list)[i]);
|
||||
|
||||
if (sizeof(C) > 1 && fixEndian)
|
||||
adjustEndianess((unsigned char*)data.data(), sizeof(C), std::min(count, list->size()));
|
||||
|
||||
file.WriteBinaryData(data.data(), sizeof(C)*std::min(count, list->size()));
|
||||
C temp = 0;
|
||||
for (int i = 0; i < (count - list->size()); i++)
|
||||
file.WriteBinaryData(&temp, sizeof(C));
|
||||
++(descr.curPos);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static void WriteAscii(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop)
|
||||
{
|
||||
size_t count = prop.CountValue();
|
||||
ContainerType* list = (ContainerType*)((unsigned char*)descr.base + descr.curPos * sizeof(ContainerType));
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
{
|
||||
if (prop.IsSigned())
|
||||
{
|
||||
int listSize = (int)list->size();
|
||||
file.WriteAsciiData(listSize);
|
||||
count = list->size();
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int listSize = (unsigned int)list->size();
|
||||
file.WriteAsciiData(listSize);
|
||||
count = list->size();
|
||||
}
|
||||
file.WriteAsciiData(std::string(" "));
|
||||
}
|
||||
|
||||
std::vector<C> data(count);
|
||||
for (int i = 0; i < std::min(count, list->size()); i++)
|
||||
data[i] = (C)((*list)[i]);
|
||||
|
||||
for (int i = 0; i < (count - list->size()); i++)
|
||||
data[i] = 0;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
file.WriteAsciiData(data[i]);
|
||||
if (i < count - 1)
|
||||
file.WriteAsciiData(std::string(" "));
|
||||
}
|
||||
++(descr.curPos);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** Memory descriptor of a vector of properties.
|
||||
* The class defines how a vector of PlyProperty is saved in memory.
|
||||
*
|
||||
* @tparam CointainerType Type of the container of the property
|
||||
* @tparam ContainerType Type of the container of the property
|
||||
* @tparam VectorSize Number of values stored in the property.
|
||||
* @tparam ScalarType Type of the values stored in the property.
|
||||
*/
|
||||
template<class CointainerType, int VectorSize, typename ScalarType>
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
class DataDescriptor : public DescriptorInterface
|
||||
{
|
||||
public:
|
||||
|
||||
DescriptorHelper<ContainerType, VectorSize, ScalarType> helper;
|
||||
|
||||
inline DataDescriptor();
|
||||
|
||||
/**
|
||||
|
|
@ -2018,7 +2340,7 @@ namespace nanoply
|
|||
* @param _s Name of the PlyProperty.
|
||||
* @param _b Pointer to the memory location that contains the data of the property.
|
||||
*/
|
||||
inline DataDescriptor(std::string& _s, void *_b) :DescriptorInterface(_s, _b){};
|
||||
inline DataDescriptor(const std::string& _s, void *_b) :DescriptorInterface(_s, _b){};
|
||||
|
||||
inline void Restart();
|
||||
|
||||
|
|
@ -2029,75 +2351,18 @@ namespace nanoply
|
|||
inline bool WriteElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian);
|
||||
|
||||
inline bool WriteElemAscii(PlyFile &file, PlyProperty &prop);
|
||||
|
||||
private:
|
||||
|
||||
template<typename C>
|
||||
inline void ReadBinary(PlyFile &file, PlyProperty &prop, bool fixEndian);
|
||||
|
||||
template<typename C>
|
||||
inline void ReadAscii(PlyFile &file, PlyProperty &prop);
|
||||
|
||||
template<typename C>
|
||||
inline void WriteBinary(PlyFile &file, PlyProperty &prop, bool fixEndian);
|
||||
|
||||
template<typename C>
|
||||
inline void WriteAscii(PlyFile &file, PlyProperty &prop);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<class CointainerType, int VectorSize, typename ScalarType>
|
||||
inline void DataDescriptor<CointainerType, VectorSize, ScalarType>::Restart()
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
void DataDescriptor<ContainerType, VectorSize, ScalarType>::Restart()
|
||||
{
|
||||
this->curPos = 0;
|
||||
}
|
||||
|
||||
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
template<typename C>
|
||||
inline void DataDescriptor<ContainerType, VectorSize, ScalarType>::ReadBinary(PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
{
|
||||
char * buffer = nullptr;
|
||||
int size;
|
||||
int count = prop.CountValue();
|
||||
int typeSize = prop.TypeSize();
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
{
|
||||
file.ReadBinaryData(buffer, sizeof(char));
|
||||
const int cntList = int(*(reinterpret_cast<unsigned char *>(buffer)));
|
||||
size = typeSize * cntList;
|
||||
count = cntList;
|
||||
}
|
||||
else
|
||||
size = typeSize * count;
|
||||
file.ReadBinaryData(buffer, size);
|
||||
|
||||
if (typeSize > 1 && fixEndian)
|
||||
adjustEndianess(reinterpret_cast<unsigned char *>(buffer), typeSize, count);
|
||||
|
||||
unsigned char* baseProp = (unsigned char*)base + this->curPos*sizeof(ContainerType);
|
||||
C* temp = (C*)buffer;
|
||||
if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA))
|
||||
{
|
||||
float norm = 1.0f;
|
||||
if (std::is_same<ScalarType, float>::value && std::is_same<C, unsigned char>::value)
|
||||
norm = 1.0f / 255.0f;
|
||||
else if (std::is_same<ScalarType, unsigned char>::value && std::is_same<C, float>::value)
|
||||
norm = 255.0f;
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
*((ScalarType *)(baseProp + i*sizeof(ScalarType))) = ScalarType(temp[i] * norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
*((ScalarType *)(baseProp + i*sizeof(ScalarType))) = ScalarType(temp[i]);
|
||||
}
|
||||
++(this->curPos);
|
||||
}
|
||||
|
||||
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
inline bool DataDescriptor<ContainerType, VectorSize, ScalarType>::ReadElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
bool DataDescriptor<ContainerType, VectorSize, ScalarType>::ReadElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
{
|
||||
if (prop.elem != elem)
|
||||
return false;
|
||||
|
|
@ -2105,70 +2370,35 @@ namespace nanoply
|
|||
{
|
||||
case NNP_LIST_INT8_INT8:
|
||||
case NNP_LIST_UINT8_INT8:
|
||||
case NNP_INT8: this->ReadBinary<char>(file, prop, fixEndian); break;
|
||||
case NNP_INT8: helper.ReadBinary<char>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_UINT8:
|
||||
case NNP_LIST_UINT8_UINT8:
|
||||
case NNP_UINT8: this->ReadBinary<unsigned char>(file, prop, fixEndian); break;
|
||||
case NNP_UINT8: helper.ReadBinary<unsigned char>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_INT16:
|
||||
case NNP_LIST_UINT8_INT16:
|
||||
case NNP_INT16: this->ReadBinary<short>(file, prop, fixEndian); break;
|
||||
case NNP_INT16: helper.ReadBinary<short>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_UINT16:
|
||||
case NNP_LIST_UINT8_UINT16:
|
||||
case NNP_UINT16: this->ReadBinary<unsigned short>(file, prop, fixEndian); break;
|
||||
case NNP_UINT16: helper.ReadBinary<unsigned short>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_FLOAT32:
|
||||
case NNP_LIST_UINT8_FLOAT32:
|
||||
case NNP_FLOAT32: this->ReadBinary<float>(file, prop, fixEndian); break;
|
||||
case NNP_FLOAT32: helper.ReadBinary<float>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_UINT8_INT32:
|
||||
case NNP_LIST_INT8_INT32:
|
||||
case NNP_INT32: this->ReadBinary<int>(file, prop, fixEndian); break;
|
||||
case NNP_INT32: helper.ReadBinary<int>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_UINT8_UINT32:
|
||||
case NNP_LIST_INT8_UINT32:
|
||||
case NNP_UINT32: this->ReadBinary<unsigned int>(file, prop, fixEndian); break;
|
||||
case NNP_UINT32: helper.ReadBinary<unsigned int>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_FLOAT64:
|
||||
case NNP_LIST_UINT8_FLOAT64:
|
||||
case NNP_FLOAT64: this->ReadBinary<double>(file, prop, fixEndian); break;
|
||||
case NNP_FLOAT64: helper.ReadBinary<double>(*this, file, prop, fixEndian); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
template<typename C>
|
||||
inline void DataDescriptor<ContainerType, VectorSize, ScalarType>::ReadAscii(PlyFile &file, PlyProperty &prop)
|
||||
{
|
||||
int count = prop.CountValue();
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
file.ReadAsciiData(count);
|
||||
|
||||
C* temp = new C[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
file.ReadAsciiData(temp[i]);
|
||||
|
||||
unsigned char* baseProp = (unsigned char*)base + this->curPos*sizeof(ContainerType);
|
||||
if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA))
|
||||
{
|
||||
float norm = 1.0f;
|
||||
if (std::is_same<ScalarType, float>::value && prop.type == NNP_UINT8)
|
||||
norm = 1.0f / 255.0f;
|
||||
else if (std::is_same<ScalarType, unsigned char>::value && prop.type == NNP_FLOAT32)
|
||||
norm = 255.0f;
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
*((ScalarType *)(baseProp + i*sizeof(ScalarType))) = ScalarType(temp[i] * norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
*((ScalarType *)(baseProp + i*sizeof(ScalarType))) = ScalarType(temp[i]);
|
||||
}
|
||||
delete[] temp;
|
||||
++(this->curPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
inline bool DataDescriptor<ContainerType, VectorSize, ScalarType>::ReadElemAscii(PlyFile &file, PlyProperty &prop)
|
||||
bool DataDescriptor<ContainerType, VectorSize, ScalarType>::ReadElemAscii(PlyFile &file, PlyProperty &prop)
|
||||
{
|
||||
if (prop.elem != elem)
|
||||
return false;
|
||||
|
|
@ -2176,87 +2406,35 @@ namespace nanoply
|
|||
{
|
||||
case NNP_LIST_UINT8_INT8:
|
||||
case NNP_LIST_INT8_INT8:
|
||||
case NNP_INT8: this->ReadAscii<int>(file, prop); break;
|
||||
case NNP_INT8: helper.ReadAscii<int>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_UINT8:
|
||||
case NNP_LIST_INT8_UINT8:
|
||||
case NNP_UINT8: this->ReadAscii<unsigned int>(file, prop); break;
|
||||
case NNP_UINT8: helper.ReadAscii<unsigned int>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_INT16:
|
||||
case NNP_LIST_INT8_INT16:
|
||||
case NNP_INT16: this->ReadAscii<short>(file, prop); break;
|
||||
case NNP_INT16: helper.ReadAscii<short>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_UINT16:
|
||||
case NNP_LIST_INT8_UINT16:
|
||||
case NNP_UINT16: this->ReadAscii<unsigned short>(file, prop); break;
|
||||
case NNP_UINT16: helper.ReadAscii<unsigned short>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_FLOAT32:
|
||||
case NNP_LIST_INT8_FLOAT32:
|
||||
case NNP_FLOAT32: this->ReadAscii<float>(file, prop); break;
|
||||
case NNP_FLOAT32: helper.ReadAscii<float>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_INT32:
|
||||
case NNP_LIST_INT8_INT32:
|
||||
case NNP_INT32: this->ReadAscii<int>(file, prop); break;
|
||||
case NNP_INT32: helper.ReadAscii<int>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_UINT32:
|
||||
case NNP_LIST_INT8_UINT32:
|
||||
case NNP_UINT32: this->ReadAscii<unsigned int>(file, prop); break;
|
||||
case NNP_UINT32: helper.ReadAscii<unsigned int>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_FLOAT64:
|
||||
case NNP_LIST_INT8_FLOAT64:
|
||||
case NNP_FLOAT64: this->ReadAscii<double>(file, prop); break;
|
||||
case NNP_FLOAT64: helper.ReadAscii<double>(*this, file, prop); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
template<typename C>
|
||||
inline void DataDescriptor<ContainerType, VectorSize, ScalarType>::WriteBinary(PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
{
|
||||
(void)fixEndian;
|
||||
int count = prop.CountValue();
|
||||
C data[VectorSize];
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
{
|
||||
if (prop.IsSigned())
|
||||
{
|
||||
char listSize = (char)VectorSize;
|
||||
file.WriteBinaryData(&listSize, 1);
|
||||
count = VectorSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char listSize = (unsigned char)VectorSize;
|
||||
file.WriteBinaryData(&listSize, 1);
|
||||
count = VectorSize;
|
||||
}
|
||||
}
|
||||
|
||||
C temp = 0;
|
||||
unsigned char* baseProp = (unsigned char*)base + this->curPos*sizeof(ContainerType);
|
||||
if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA))
|
||||
{
|
||||
float norm = 1.0f;
|
||||
if (std::is_same<ScalarType, float>::value && std::is_same<C, unsigned char>::value)
|
||||
norm = 255.0f;
|
||||
else if (std::is_same<ScalarType, unsigned char>::value && std::is_same<C, float>::value)
|
||||
norm = 1.0f / 255.0f;
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
data[i] = (C)((*(ScalarType*)(baseProp + i*sizeof(ScalarType))) * norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
data[i] = (C)((*(ScalarType*)(baseProp + i*sizeof(ScalarType))));
|
||||
}
|
||||
|
||||
if (sizeof(C) > 1 && fixEndian)
|
||||
adjustEndianess((unsigned char*)data, sizeof(C), std::min(VectorSize, count));
|
||||
|
||||
file.WriteBinaryData(data, sizeof(C)*std::min(VectorSize, count));
|
||||
for (int i = 0; i < (count - VectorSize); i++)
|
||||
file.WriteBinaryData(&temp, sizeof(C));
|
||||
++(this->curPos);
|
||||
}
|
||||
|
||||
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
inline bool DataDescriptor<ContainerType, VectorSize, ScalarType>::WriteElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
bool DataDescriptor<ContainerType, VectorSize, ScalarType>::WriteElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian)
|
||||
{
|
||||
if (prop.elem != elem)
|
||||
return false;
|
||||
|
|
@ -2264,89 +2442,35 @@ namespace nanoply
|
|||
{
|
||||
case NNP_LIST_INT8_INT8:
|
||||
case NNP_LIST_UINT8_INT8:
|
||||
case NNP_INT8: this->WriteBinary<char>(file, prop, fixEndian); break;
|
||||
case NNP_INT8: helper.WriteBinary<char>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_UINT8:
|
||||
case NNP_LIST_UINT8_UINT8:
|
||||
case NNP_UINT8: this->WriteBinary<unsigned char>(file, prop, fixEndian); break;
|
||||
case NNP_UINT8: helper.WriteBinary<unsigned char>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_INT16:
|
||||
case NNP_LIST_UINT8_INT16:
|
||||
case NNP_INT16: this->WriteBinary<short>(file, prop, fixEndian); break;
|
||||
case NNP_INT16: helper.WriteBinary<short>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_UINT16:
|
||||
case NNP_LIST_UINT8_UINT16:
|
||||
case NNP_UINT16: this->WriteBinary<unsigned short>(file, prop, fixEndian); break;
|
||||
case NNP_UINT16: helper.WriteBinary<unsigned short>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_FLOAT32:
|
||||
case NNP_LIST_UINT8_FLOAT32:
|
||||
case NNP_FLOAT32: this->WriteBinary<float>(file, prop, fixEndian); break;
|
||||
case NNP_FLOAT32: helper.WriteBinary<float>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_UINT8_INT32:
|
||||
case NNP_LIST_INT8_INT32:
|
||||
case NNP_INT32: this->WriteBinary<int>(file, prop, fixEndian); break;
|
||||
case NNP_INT32: helper.WriteBinary<int>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_UINT8_UINT32:
|
||||
case NNP_LIST_INT8_UINT32:
|
||||
case NNP_UINT32: this->WriteBinary<unsigned int>(file, prop, fixEndian); break;
|
||||
case NNP_UINT32: helper.WriteBinary<unsigned int>(*this, file, prop, fixEndian); break;
|
||||
case NNP_LIST_INT8_FLOAT64:
|
||||
case NNP_LIST_UINT8_FLOAT64:
|
||||
case NNP_FLOAT64: this->WriteBinary<double>(file, prop, fixEndian); break;
|
||||
case NNP_FLOAT64: helper.WriteBinary<double>(*this, file, prop, fixEndian); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
template<typename C>
|
||||
inline void DataDescriptor<ContainerType, VectorSize, ScalarType>::WriteAscii(PlyFile &file, PlyProperty &prop)
|
||||
{
|
||||
int count = prop.CountValue();
|
||||
if (prop.type >= NNP_LIST_UINT8_UINT32)
|
||||
{
|
||||
if (prop.IsSigned())
|
||||
{
|
||||
int listSize = (int)VectorSize;
|
||||
file.WriteAsciiData(listSize);
|
||||
count = VectorSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int listSize = (unsigned int)VectorSize;
|
||||
file.WriteAsciiData(listSize);
|
||||
count = VectorSize;
|
||||
}
|
||||
file.WriteAsciiData(std::string(" "));
|
||||
}
|
||||
|
||||
C data[VectorSize];
|
||||
unsigned char* baseProp = (unsigned char*)base + this->curPos*sizeof(ContainerType);
|
||||
if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA))
|
||||
{
|
||||
float norm = 1.0;
|
||||
if (std::is_same<ScalarType, float>::value && prop.type == NNP_UINT8)
|
||||
norm = 255.0f;
|
||||
else if (std::is_same<ScalarType, unsigned char>::value && prop.type == NNP_FLOAT32)
|
||||
norm = 1.0f / 255.0f;
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
data[i] = (C)((*(ScalarType*)(baseProp + i*sizeof(ScalarType))) * norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < std::min(VectorSize, count); i++)
|
||||
data[i] = (C)((*(ScalarType*)(baseProp + i*sizeof(ScalarType))));
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < (count - VectorSize); i++)
|
||||
data[i] = 0;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
file.WriteAsciiData(data[i]);
|
||||
if (i < count - 1)
|
||||
file.WriteAsciiData(std::string(" "));
|
||||
}
|
||||
++(this->curPos);
|
||||
}
|
||||
|
||||
|
||||
template<class ContainerType, int VectorSize, typename ScalarType>
|
||||
inline bool DataDescriptor<ContainerType, VectorSize, ScalarType>::WriteElemAscii(PlyFile &file, PlyProperty& prop)
|
||||
bool DataDescriptor<ContainerType, VectorSize, ScalarType>::WriteElemAscii(PlyFile &file, PlyProperty& prop)
|
||||
{
|
||||
if (prop.elem != elem)
|
||||
return false;
|
||||
|
|
@ -2356,28 +2480,28 @@ namespace nanoply
|
|||
{
|
||||
case NNP_LIST_UINT8_INT8:
|
||||
case NNP_LIST_INT8_INT8:
|
||||
case NNP_INT8: this->WriteAscii<int>(file, prop); break;
|
||||
case NNP_INT8: helper.WriteAscii<int>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_UINT8:
|
||||
case NNP_LIST_INT8_UINT8:
|
||||
case NNP_UINT8: this->WriteAscii<unsigned int>(file, prop); break;
|
||||
case NNP_UINT8: helper.WriteAscii<unsigned int>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_INT16:
|
||||
case NNP_LIST_INT8_INT16:
|
||||
case NNP_INT16: this->WriteAscii<short>(file, prop); break;
|
||||
case NNP_INT16: helper.WriteAscii<short>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_UINT16:
|
||||
case NNP_LIST_INT8_UINT16:
|
||||
case NNP_UINT16: this->WriteAscii<unsigned short>(file, prop); break;
|
||||
case NNP_UINT16: helper.WriteAscii<unsigned short>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_FLOAT32:
|
||||
case NNP_LIST_INT8_FLOAT32:
|
||||
case NNP_FLOAT32: this->WriteAscii<float>(file, prop); break;
|
||||
case NNP_FLOAT32: helper.WriteAscii<float>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_INT32:
|
||||
case NNP_LIST_INT8_INT32:
|
||||
case NNP_INT32: this->WriteAscii<int>(file, prop); break;
|
||||
case NNP_INT32: helper.WriteAscii<int>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_UINT32:
|
||||
case NNP_LIST_INT8_UINT32:
|
||||
case NNP_UINT32: this->WriteAscii<unsigned int>(file, prop); break;
|
||||
case NNP_UINT32: helper.WriteAscii<unsigned int>(*this, file, prop); break;
|
||||
case NNP_LIST_UINT8_FLOAT64:
|
||||
case NNP_LIST_INT8_FLOAT64:
|
||||
case NNP_FLOAT64: this->WriteAscii<double>(file, prop); break;
|
||||
case NNP_FLOAT64: helper.WriteAscii<double>(*this, file, prop); break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -16,31 +16,55 @@ template <class ShotType>
|
|||
if(QString::compare(node.nodeName(),"VCGCamera")==0)
|
||||
{
|
||||
QDomNamedNodeMap attr = node.attributes();
|
||||
Point3x tra;
|
||||
tra[0] = attr.namedItem("TranslationVector").nodeValue().section(' ',0,0).toDouble();
|
||||
tra[1] = attr.namedItem("TranslationVector").nodeValue().section(' ',1,1).toDouble();
|
||||
tra[2] = attr.namedItem("TranslationVector").nodeValue().section(' ',2,2).toDouble();
|
||||
shot.Extrinsics.SetTra(-tra);
|
||||
if (attr.contains("BinaryData") && attr.namedItem("BinaryData").nodeValue().toInt() == 1)
|
||||
{
|
||||
Point3x tra;
|
||||
QString str = attr.namedItem("TranslationVector").nodeValue();
|
||||
QByteArray value = QByteArray::fromBase64(str.toLocal8Bit());
|
||||
memcpy(tra.V(), value.data(), sizeof(ScalarType) * 3);
|
||||
shot.Extrinsics.SetTra(-tra);
|
||||
|
||||
vcg::Matrix44<ScalarType> rot;
|
||||
QStringList values = attr.namedItem("RotationMatrix").nodeValue().split(" ", QString::SkipEmptyParts);
|
||||
for(int y = 0; y < 4; y++)
|
||||
for(int x = 0; x < 4; x++)
|
||||
rot[y][x] = values[x + 4*y].toDouble();
|
||||
shot.Extrinsics.SetRot(rot);
|
||||
vcg::Matrix44<ScalarType> rot;
|
||||
str = attr.namedItem("RotationMatrix").nodeValue();
|
||||
value = QByteArray::fromBase64(str.toLocal8Bit());
|
||||
memcpy(rot.V(), value.data(), sizeof(ScalarType) * 16);
|
||||
shot.Extrinsics.SetRot(rot);
|
||||
|
||||
vcg::Camera<ScalarType> &cam = shot.Intrinsics;
|
||||
if(attr.contains("CameraType")) cam.cameraType = attr.namedItem("CameraType").nodeValue().toInt();
|
||||
cam.FocalMm = attr.namedItem("FocalMm").nodeValue().toDouble();
|
||||
cam.ViewportPx.X() = attr.namedItem("ViewportPx").nodeValue().section(' ',0,0).toInt();
|
||||
cam.ViewportPx.Y() = attr.namedItem("ViewportPx").nodeValue().section(' ',1,1).toInt();
|
||||
cam.CenterPx[0] = attr.namedItem("CenterPx").nodeValue().section(' ', 0, 0).toDouble();
|
||||
cam.CenterPx[1] = attr.namedItem("CenterPx").nodeValue().section(' ', 1, 1).toDouble();
|
||||
cam.PixelSizeMm[0] = attr.namedItem("PixelSizeMm").nodeValue().section(' ',0,0).toDouble();
|
||||
cam.PixelSizeMm[1] = attr.namedItem("PixelSizeMm").nodeValue().section(' ',1,1).toDouble();
|
||||
cam.k[0] = attr.namedItem("LensDistortion").nodeValue().section(' ',0,0).toDouble();
|
||||
cam.k[1] = attr.namedItem("LensDistortion").nodeValue().section(' ',1,1).toDouble();
|
||||
vcg::Camera<ScalarType> &cam = shot.Intrinsics;
|
||||
if (attr.contains("CameraType")) cam.cameraType = attr.namedItem("CameraType").nodeValue().toInt();
|
||||
memcpy(&cam.FocalMm, QByteArray::fromBase64(attr.namedItem("FocalMm").nodeValue().toLocal8Bit()).data(), sizeof(ScalarType));
|
||||
memcpy(&cam.ViewportPx, QByteArray::fromBase64(attr.namedItem("ViewportPx").nodeValue().toLocal8Bit()).data(), sizeof(int) * 2);
|
||||
memcpy(&cam.CenterPx, QByteArray::fromBase64(attr.namedItem("CenterPx").nodeValue().toLocal8Bit()).data(), sizeof(ScalarType)*2);
|
||||
memcpy(&cam.PixelSizeMm, QByteArray::fromBase64(attr.namedItem("PixelSizeMm").nodeValue().toLocal8Bit()).data(), sizeof(ScalarType) * 2);
|
||||
memcpy(&cam.k, QByteArray::fromBase64(attr.namedItem("LensDistortion").nodeValue().toLocal8Bit()).data(), sizeof(ScalarType) * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Point3x tra;
|
||||
tra[0] = attr.namedItem("TranslationVector").nodeValue().section(' ', 0, 0).toDouble();
|
||||
tra[1] = attr.namedItem("TranslationVector").nodeValue().section(' ', 1, 1).toDouble();
|
||||
tra[2] = attr.namedItem("TranslationVector").nodeValue().section(' ', 2, 2).toDouble();
|
||||
shot.Extrinsics.SetTra(-tra);
|
||||
|
||||
vcg::Matrix44<ScalarType> rot;
|
||||
QStringList values = attr.namedItem("RotationMatrix").nodeValue().split(" ", QString::SkipEmptyParts);
|
||||
for (int y = 0; y < 4; y++)
|
||||
for (int x = 0; x < 4; x++)
|
||||
rot[y][x] = values[x + 4 * y].toDouble();
|
||||
shot.Extrinsics.SetRot(rot);
|
||||
|
||||
vcg::Camera<ScalarType> &cam = shot.Intrinsics;
|
||||
if (attr.contains("CameraType")) cam.cameraType = attr.namedItem("CameraType").nodeValue().toInt();
|
||||
cam.FocalMm = attr.namedItem("FocalMm").nodeValue().toDouble();
|
||||
cam.ViewportPx.X() = attr.namedItem("ViewportPx").nodeValue().section(' ', 0, 0).toInt();
|
||||
cam.ViewportPx.Y() = attr.namedItem("ViewportPx").nodeValue().section(' ', 1, 1).toInt();
|
||||
cam.CenterPx[0] = attr.namedItem("CenterPx").nodeValue().section(' ', 0, 0).toDouble();
|
||||
cam.CenterPx[1] = attr.namedItem("CenterPx").nodeValue().section(' ', 1, 1).toDouble();
|
||||
cam.PixelSizeMm[0] = attr.namedItem("PixelSizeMm").nodeValue().section(' ', 0, 0).toDouble();
|
||||
cam.PixelSizeMm[1] = attr.namedItem("PixelSizeMm").nodeValue().section(' ', 1, 1).toDouble();
|
||||
cam.k[0] = attr.namedItem("LensDistortion").nodeValue().section(' ', 0, 0).toDouble();
|
||||
cam.k[1] = attr.namedItem("LensDistortion").nodeValue().section(' ', 1, 1).toDouble();
|
||||
}
|
||||
// scale correction should no more exist !!!
|
||||
// float scorr = attr.namedItem("ScaleCorr").nodeValue().toDouble();
|
||||
// if(scorr != 0.0) {
|
||||
|
|
@ -120,6 +144,7 @@ template <class ShotType>
|
|||
const vcg::Camera<ScalarType> &cam = shot.Intrinsics;
|
||||
|
||||
shotElem.setAttribute("CameraType", cam.cameraType);
|
||||
shotElem.setAttribute("BinaryData", 0);
|
||||
|
||||
shotElem.setAttribute( "FocalMm", cam.FocalMm);
|
||||
|
||||
|
|
@ -142,4 +167,50 @@ template <class ShotType>
|
|||
}
|
||||
|
||||
|
||||
template <class ShotType>
|
||||
QDomElement WriteShotToQDomNodeBinary(
|
||||
const ShotType &shot, /// the shot to be written node
|
||||
QDomDocument &doc) /// The XML node to be read
|
||||
{
|
||||
typedef typename ShotType::ScalarType ScalarType;
|
||||
|
||||
QDomElement shotElem = doc.createElement("VCGCamera");
|
||||
vcg::Point3<ScalarType> tra = -(shot.Extrinsics.Tra());
|
||||
|
||||
QByteArray value = QByteArray::fromRawData((char *)tra.V(), sizeof(ScalarType) * 3).toBase64();
|
||||
shotElem.setAttribute("TranslationVector", QString(value));
|
||||
|
||||
vcg::Matrix44<ScalarType> rot = shot.Extrinsics.Rot();
|
||||
value = QByteArray::fromRawData((char *)rot.V(), sizeof(ScalarType) * 16).toBase64();
|
||||
shotElem.setAttribute("RotationMatrix", QString(value));
|
||||
|
||||
const vcg::Camera<ScalarType> &cam = shot.Intrinsics;
|
||||
|
||||
shotElem.setAttribute("CameraType", cam.cameraType);
|
||||
|
||||
shotElem.setAttribute("BinaryData", 1);
|
||||
|
||||
value = QByteArray::fromRawData((char *)&cam.FocalMm, sizeof(ScalarType)).toBase64();
|
||||
shotElem.setAttribute("FocalMm", QString(value));
|
||||
|
||||
value = QByteArray::fromRawData((char *)&cam.k, sizeof(ScalarType) * 2).toBase64();
|
||||
shotElem.setAttribute("LensDistortion", QString(value));
|
||||
|
||||
value = QByteArray::fromRawData((char *)&cam.PixelSizeMm, sizeof(ScalarType) * 2).toBase64();
|
||||
shotElem.setAttribute("PixelSizeMm", QString(value));
|
||||
|
||||
value = QByteArray::fromRawData((char *)&cam.ViewportPx, sizeof(int) * 2).toBase64();
|
||||
shotElem.setAttribute("ViewportPx", QString(value));
|
||||
|
||||
//str = QString("%1 %2").arg(cam.CenterPx[0]).arg(cam.CenterPx[1]);
|
||||
value = QByteArray::fromRawData((char *)&cam.CenterPx, sizeof(ScalarType) * 2).toBase64();
|
||||
shotElem.setAttribute("CenterPx", QString(value));
|
||||
|
||||
//scale correction should no more exist !!!
|
||||
//str = QString("%1").arg((double) 1);
|
||||
//shotElem.setAttribute( "ScaleCorr", str);
|
||||
return shotElem;
|
||||
}
|
||||
|
||||
|
||||
#endif // SHOT_QT_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue