stable allocate and tetra complex

This commit is contained in:
T.Alderighi 2018-05-03 15:05:42 +02:00
parent 13d79bc428
commit b0384f68d1
15 changed files with 1345 additions and 694 deletions

View File

@ -64,7 +64,7 @@ namespace tri {
typedef std::vector< typename TYPESPOOL::HEdgeType > CONTH;
typedef CONTV VertContainer;
typedef _Vertex VertexType;
typedef typename CONTV::value_type VertexType;
typedef typename TYPESPOOL::VertexPointer VertexPointer;
typedef const typename TYPESPOOL::VertexPointer ConstVertexPointer;
typedef bool CoordType;

View File

@ -225,7 +225,7 @@ public:
}
for (TetraIterator ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
if (!(*ti.IsD()))
if (!(*ti).IsD())
for (int i = 0; i < 4; ++i)
if ((*ti).cV(i) != 0)
pu.Update((*ti).V(i));
@ -660,12 +660,12 @@ public:
pu.Update((*ei).EFp());
}
if (HasHFAdjacency(m))
{
for (HEdgeIterator hi = m.hedge.begin(); hi != m.hedge.end(); ++hi)
if (!(*hi).IsD() && (*hi).cHFp() != 0)
pu.Update((*hi).HFp());
}
// if (HasHFAdjacency(m))
// {
// for (HEdgeIterator hi = m.hedge.begin(); hi != m.hedge.end(); ++hi)
// if (!(*hi).IsD() && (*hi).cHFp() != 0)
// pu.Update((*hi).HFp());
// }
}
return firstNewFace;
}
@ -699,7 +699,7 @@ public:
else
{
pu.oldBase = &*m.tetra.begin();
pu.oldEnd = &*m.tetra.back() + 1;
pu.oldEnd = &m.tetra.back() + 1;
}
//resize the tetra list and update tetra count
@ -719,7 +719,7 @@ public:
//do the update
pu.newBase = &*m.tetra.begin();
pu.newEnd = &*m.tetra.back() + 1;
pu.newEnd = &m.tetra.back() + 1;
if (pu.NeedUpdate())
{
if (HasVTAdjacency(m))
@ -739,9 +739,8 @@ public:
}
//do edge and face adjacency
if (HasTTAdjacency(m))
for (TetraPointer ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
for (TetraIterator ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
if (!ti->IsD())
{
pu.Update(ti->TTp(0));
@ -804,6 +803,11 @@ public:
VertexPointer v2 = &*vi++;
VertexPointer v3 = &*vi++;
v0->P() = p0;
v1->P() = p1;
v2->P() = p2;
v3->P() = p3;
return AddTetra(m, v0, v1, v2, v3);
}
@ -920,19 +924,6 @@ public:
}
//TODO:
// static void PermutateTetraVector(MeshType & m, PointerUpdater<TetraPointer> & pu)
// {
// if (m.tetra.empty())
// return;
// for (size_t i = 0; i < m.tetra.size(); ++i)
// {
// if (pu.remap[i] < size_t(m.tn))
// {
// }
// }
// }
/*
Function to rearrange the vertex vector according to a given index permutation
the permutation is vector such that after calling this function
@ -1159,6 +1150,7 @@ public:
CompactEdgeVector(m, pu);
}
/*!
\brief Compact face vector by removing deleted elements.
@ -1278,6 +1270,127 @@ public:
CompactFaceVector(m, pu);
}
/*!
\brief Compact tetra vector by removing deleted elements.
Deleted elements are put to the end of the vector and the vector is resized.
Order between elements is preserved, but not their position (hence the PointerUpdater)
Immediately after calling this function the \c IsD() test during the scanning a vector, is no more necessary.
\warning It should not be called when some TemporaryData is active (but works correctly if attributes are present)
*/
static void CompactTetraVector(MeshType & m, PointerUpdater<TetraPointer> & pu)
{
//nothing to do
if (size_t(m.tn) == m.tetra.size())
return;
//init the remap
pu.remap.resize(m.tetra.size(), std::numeric_limits<size_t>::max());
//cycle over all the tetras, pos is the last not D() position, I is the index
//when pos != i and !tetra[i].IsD() => we need to compact and update adj
size_t pos = 0;
for (size_t i = 0; i < m.tetra.size(); ++i)
{
if (!m.tetra.IsD())
{
if (pos != i)
{
//import data
m.tetra[pos].ImportData(m.tetra[i]);
//import vertex refs
for (int j = 0; j < 4; ++j)
m.tetra[pos].V(j) = m.tetra[i].cV(j);
//import VT adj
if (HasVTAdjacency(m))
for (int j = 0; j < 4; ++j)
{
if (m.tetra[i].IsVTInitialized(j))
{
m.tetra[pos].VTp(j) = m.tetra[i].VTp(j);
m.tetra[pos].VTi(j) = m.tetra[i].VTi(j);
}
else
m.tetra[pos].VTClear();
}
//import TT adj
if (HasTTAdjacency(m))
for (int j = 0; j < 4; ++j)
{
m.tetra[pos].TTp(j) = m.tetra[i].cTTp(j);
m.tetra[pos].TTi(j) = m.tetra[i].cTTi(j);
}
}
//update remapping and advance pos
pu.remap[i] = pos;
++pos;
}
}
assert(size_t(m.tn) == pos);
//reorder the optional attributes in m.tetra_attr
ReorderAttribute(m.tetra_attr, pu.remap, m);
// resize the optional atttributes in m.tetra_attr to reflect the changes
ResizeAttribute(m.tetra_attr, m.tn, m);
// Loop on the tetras to correct VT and TT relations
pu.oldBase = &m.tetra[0];
pu.oldEnd = &m.tetra.back() + 1;
m.tetra.resize(m.tn);
pu.newBase = (m.tetra.empty()) ? 0 : &m.tetra[0];
pu.newEnd = (m.tetra.empty()) ? 0 : &m.tetra.back() + 1;
TetraPointer tbase = &m.tetra[0];
//Loop on the vertices to correct VT relation (since we moved things around)
if (HasVTAdjacency(m))
{
for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
if (!(*vi).IsD())
{
if ((*vi).IsVTInitialized() && (*vi).VTp() != 0)
{
size_t oldIndex = (*vi).cVTp() - tbase;
assert(tbase <= (*vi).cVTp() && oldIndex < pu.remap.size());
(*vi).VTp() = tbase + pu.remap[oldIndex];
}
}
}
// Loop on the tetras to correct the VT and TT relations
for (TetraIterator ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
if (!(*ti).IsD())
{
//VT
if (HasVTAdjacency(m))
for (int i = 0; i < 4; ++i)
if ((*ti).IsVTInitialized(i) && (*ti).VTp(i) != 0)
{
size_t oldIndex = (*ti).VTp(i) - fbase;
assert(tbase <= (*ti).VTp(i) && oldIndex < pu.remap.size());
(*ti).VTp(i) = tbase + pu.remap[oldIndex];
}
//TT
if (HasTTAdjacency(m))
for (int i = 0; i < 4; ++i)
if ((*ti).cTTp(i) != 0)
{
size_t oldIndex = (*ti).TTp(i) - tbase;
assert(tbase <= (*ti).TTp(i) && oldIndex < pu.remap.size());
(*ti).TTp(i) = tbase + pu.remap[oldIndex];
}
}
}
/*! \brief Wrapper without the PointerUpdater. */
static void CompactTetraVector(MeshType &m)
{
PointerUpdater<TetraPointer> pu;
CompactTetraVector(m, pu);
}
public:
/*! \brief Check if an handle to a Per-Vertex Attribute is valid
*/

View File

@ -0,0 +1,456 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#ifndef __VCGLIB_TETRAAPPEND
#define __VCGLIB_TETRAAPPEND
#ifndef __VCG_TETRA_MESH
#error "This file should not be included alone. It is automatically included by complex.h"
#endif
namespace vcg {
namespace tetra {
/** \ingroup trimesh */
/*! \brief Class to safely duplicate and append (portion of) meshes.
Adding elements to a mesh, like faces and vertices can involve the reallocation of the vectors of the involved elements.
This class provide the only safe methods to add elements of a mesh to another one.
\sa \ref allocation
*/
template<class MeshLeft, class ConstMeshRight>
class Append
{
public:
typedef typename MeshLeft::ScalarType ScalarLeft;
typedef typename MeshLeft::CoordType CoordLeft;
typedef typename MeshLeft::VertexType VertexLeft;
typedef typename MeshLeft::EdgeType EdgeLeft;
typedef typename MeshLeft::FaceType FaceLeft;
typedef typename MeshLeft::TetraType TetraLeft;
// typedef typename MeshLeft::HEdgeType HEdgeLeft;
typedef typename MeshLeft::VertexPointer VertexPointerLeft;
typedef typename MeshLeft::VertexIterator VertexIteratorLeft;
typedef typename MeshLeft::EdgeIterator EdgeIteratorLeft;
// typedef typename MeshLeft::HEdgeIterator HEdgeIteratorLeft;
typedef typename MeshLeft::FaceIterator FaceIteratorLeft;
typedef typename MeshLeft::TetraIterator TetraIteratorLeft;
typedef typename MeshLeft::TetraPointer TetraPointerLeft;
typedef typename ConstMeshRight::ScalarType ScalarRight;
typedef typename ConstMeshRight::CoordType CoordRight;
typedef typename ConstMeshRight::VertexType VertexRight;
typedef typename ConstMeshRight::EdgeType EdgeRight;
// typedef typename ConstMeshRight::HEdgeType HEdgeRight;
typedef typename ConstMeshRight::FaceType FaceRight;
typedef typename ConstMeshRight::VertexPointer VertexPointerRight;
typedef typename ConstMeshRight::VertexIterator VertexIteratorRight;
typedef typename ConstMeshRight::EdgeIterator EdgeIteratorRight;
// typedef typename ConstMeshRight::HEdgeIterator HEdgeIteratorRight;
typedef typename ConstMeshRight::FaceIterator FaceIteratorRight;
typedef typename ConstMeshRight::FacePointer FacePointerRight;
typedef typename ConstMeshRight::TetraType TetraTypeRight;
typedef typename ConstMeshRight::TetraPointer TetraPointerRight;
typedef typename ConstMeshRight::TetraIterator TetraIteratorRight;
struct Remap{
static size_t InvalidIndex() { return std::numeric_limits<size_t>::max(); }
std::vector<size_t> vert,face,edge, /*hedge,*/ tetra;
};
static void ImportVertexAdj(MeshLeft &ml, ConstMeshRight &mr, VertexLeft &vl, VertexRight &vr, Remap &remap ){
// Vertex to Edge Adj
if(HasVEAdjacency(ml) && HasVEAdjacency(mr) && vr.cVEp() != 0){
size_t i = Index(mr,vr.cVEp());
vl.VEp() = (i>ml.edge.size())? 0 : &ml.edge[remap.edge[i]];
vl.VEi() = vr.VEi();
}
// Vertex to Face Adj
if(HasPerVertexVFAdjacency(ml) && HasPerVertexVFAdjacency(mr) && vr.cVFp() != 0 ){
size_t i = Index(mr,vr.cVFp());
vl.VFp() = (i>ml.face.size())? 0 :&ml.face[remap.face[i]];
vl.VFi() = vr.VFi();
}
if (HasPerVertexVTAdjacency(ml) && HasPerVertexVTAdjacency(mr) && vr.cVTp() != 0) {
size_t i = Index(mr, vr.cVTp());
vl.VTp() = (i > ml.tetra.size()) ? 0 : &ml.tetra[remap.tetra[i]];
vl.VTi() = vt.VTi();
}
// // Vertex to HEdge Adj
// if(HasVHAdjacency(ml) && HasVHAdjacency(mr) && vr.cVHp() != 0){
// vl.VHp() = &ml.hedge[remap.hedge[Index(mr,vr.cVHp())]];
// vl.VHi() = vr.VHi();
// }
}
static void ImportEdgeAdj(MeshLeft &ml, ConstMeshRight &mr, EdgeLeft &el, const EdgeRight &er, Remap &remap)
{
// Edge to Edge Adj
if(HasEEAdjacency(ml) && HasEEAdjacency(mr))
for(unsigned int vi = 0; vi < 2; ++vi)
{
size_t idx = Index(mr,er.cEEp(vi));
el.EEp(vi) = (idx>ml.edge.size())? 0 : &ml.edge[remap.edge[idx]];
el.EEi(vi) = er.cEEi(vi);
}
// Edge to Face Adj
if(HasEFAdjacency(ml) && HasEFAdjacency(mr)){
size_t idx = Index(mr,er.cEFp());
el.EFp() = (idx>ml.face.size())? 0 :&ml.face[remap.face[idx]];
el.EFi() = er.cEFi();
}
// // Edge to HEdge Adj
// if(HasEHAdjacency(ml) && HasEHAdjacency(mr))
// el.EHp() = &ml.hedge[remap.hedge[Index(mr,er.cEHp())]];
}
static void ImportFaceAdj(MeshLeft &ml, ConstMeshRight &mr, FaceLeft &fl, const FaceRight &fr, Remap &remap )
{
// Face to Edge Adj
if(HasFEAdjacency(ml) && HasFEAdjacency(mr)){
assert(fl.VN() == fr.VN());
for( int vi = 0; vi < fl.VN(); ++vi ){
size_t idx = remap.edge[Index(mr,fr.cFEp(vi))];
if(idx!=Remap::InvalidIndex())
fl.FEp(vi) = &ml.edge[idx];
}
}
// Face to Face Adj
if(HasFFAdjacency(ml) && HasFFAdjacency(mr)){
assert(fl.VN() == fr.VN());
for( int vi = 0; vi < fl.VN(); ++vi ){
size_t idx = remap.face[Index(mr,fr.cFFp(vi))];
if(idx!=Remap::InvalidIndex()){
fl.FFp(vi) = &ml.face[idx];
fl.FFi(vi) = fr.cFFi(vi);
}
}
}
// // Face to HEedge Adj
// if(HasFHAdjacency(ml) && HasFHAdjacency(mr))
// fl.FHp() = &ml.hedge[remap.hedge[Index(mr,fr.cFHp())]];
}
static void ImportTetraAdj(MeshLeft & ml, ConstMeshRight & mr, TetraLeft & tl, const TetraTypeRight &tr, Remap &remap )
{
// TT Adj
if(HasTTAdjacency(ml) && HasTTAdjacency(mr)){
for( int vi = 0; vi < 4; ++vi ){
size_t idx = remap.tetra[Index(mr,tr.cTTp(vi))];
if(idx!=Remap::InvalidIndex()){
tl.TTp(vi) = &ml.tetra[idx];
tl.TTi(vi) = fr.cTTi(vi);
}
}
}
// // Face to HEedge Adj
// if(HasFHAdjacency(ml) && HasFHAdjacency(mr))
// fl.FHp() = &ml.hedge[remap.hedge[Index(mr,fr.cFHp())]];
}
// static void ImportHEdgeAdj(MeshLeft &ml, ConstMeshRight &mr, HEdgeLeft &hl, const HEdgeRight &hr, Remap &remap, bool /*sel*/ ){
// // HEdge to Vertex Adj
// if(HasHVAdjacency(ml) && HasHVAdjacency(mr))
// hl.HVp() = &ml.vert[remap.vert[Index(mr,hr.cHVp())]];
// // HEdge to Edge Adj
// if(HasHEAdjacency(ml) && HasHEAdjacency(mr)){
// size_t idx = Index(mr,hr.cHEp()) ;
// hl.HEp() = (idx>ml.edge.size())? 0 : &ml.edge[remap.edge[idx]];
// }
// // HEdge to Face Adj
// if(HasHFAdjacency(ml) && HasHFAdjacency(mr)){
// size_t idx = Index(mr,hr.cHFp());
// hl.HFp() = (idx>ml.face.size())? 0 :&ml.face[remap.face[idx]];
// }
// // HEdge to Opposite HEdge Adj
// if(HasHOppAdjacency(ml) && HasHOppAdjacency(mr))
// hl.HOp() = &ml.hedge[remap.hedge[Index(mr,hr.cHOp())]];
// // HEdge to Next HEdge Adj
// if(HasHNextAdjacency(ml) && HasHNextAdjacency(mr))
// hl.HNp() = &ml.hedge[remap.hedge[Index(mr,hr.cHNp())]];
// // HEdge to Next HEdge Adj
// if(HasHPrevAdjacency(ml) && HasHPrevAdjacency(mr))
// hl.HPp() = &ml.hedge[remap.hedge[Index(mr,hr.cHPp())]];
// }
// Append Right Mesh to the Left Mesh
// Append::Mesh(ml, mr) is equivalent to ml += mr.
// Note MeshRigth could be costant...
/*! \brief %Append the second mesh to the first one.
The first mesh is not destroyed and no attempt of avoid duplication of already present elements is done.
If requested only the selected elements are appended to the first one.
The second mesh is not changed at all (it could be constant) with the exception of the selection (see below note).
\note If the the selection of the vertexes is not consistent with the face selection
the append could build faces referencing non existent vertices
so it is mandatory that the selection of the vertices reflects the loose selection
from edges and faces (e.g. if a face is selected then all its vertices must be selected).
\note Attributes. This function will copy only those attributes that are present in both meshes.
Two attributes in different meshes are considered the same iff they have the same
name and the same type. This may be deceiving because they could in fact have
different semantic, but this is up to the developer.
If the left mesh has attributes that are not in the right mesh, their values for the elements
of the right mesh will be uninitialized
*/
//TODO:
static void Mesh(MeshLeft& ml, ConstMeshRight& mr, const bool selected = false, const bool adjFlag = false)
{
// Note that if the the selection of the vertexes is not consistent with the face selection
// the append could build faces referencing non existent vertices
// so it is mandatory that the selection of the vertices reflects the loose selection
// from edges and faces (e.g. if a face is selected all its vertices must be selected).
// note the use of the parameter for preserving existing vertex selection.
if(selected)
{
assert(adjFlag == false || ml.IsEmpty()); // It is rather meaningless to partially copy adj relations.
tri::UpdateSelection<ConstMeshRight>::VertexFromEdgeLoose(mr,true);
tri::UpdateSelection<ConstMeshRight>::VertexFromFaceLoose(mr,true);
}
// phase 1. allocate on ml vert,edge,face, hedge to accomodat those of mr
// and build the remapping for all
Remap remap;
// vertex
remap.vert.resize(mr.vert.size(), Remap::InvalidIndex());
VertexIteratorLeft vp;
size_t svn = UpdateSelection<ConstMeshRight>::VertexCount(mr);
if(selected)
vp=Allocator<MeshLeft>::AddVertices(ml,int(svn));
else
vp=Allocator<MeshLeft>::AddVertices(ml,mr.vn);
for(VertexIteratorRight vi=mr.vert.begin(); vi!=mr.vert.end(); ++vi)
{
if(!(*vi).IsD() && (!selected || (*vi).IsS()))
{
size_t ind=Index(mr,*vi);
remap.vert[ind]=int(Index(ml,*vp));
++vp;
}
}
// edge
remap.edge.resize(mr.edge.size(), Remap::InvalidIndex());
EdgeIteratorLeft ep;
size_t sen = UpdateSelection<ConstMeshRight>::EdgeCount(mr);
if(selected) ep=Allocator<MeshLeft>::AddEdges(ml,sen);
else ep=Allocator<MeshLeft>::AddEdges(ml,mr.en);
for(EdgeIteratorRight ei=mr.edge.begin(); ei!=mr.edge.end(); ++ei)
if(!(*ei).IsD() && (!selected || (*ei).IsS())){
size_t ind=Index(mr,*ei);
remap.edge[ind]=int(Index(ml,*ep));
++ep;
}
// face
remap.face.resize(mr.face.size(), Remap::InvalidIndex());
FaceIteratorLeft fp;
size_t sfn = UpdateSelection<ConstMeshRight>::FaceCount(mr);
if(selected) fp=Allocator<MeshLeft>::AddFaces(ml,sfn);
else fp=Allocator<MeshLeft>::AddFaces(ml,mr.fn);
for(FaceIteratorRight fi=mr.face.begin(); fi!=mr.face.end(); ++fi)
if(!(*fi).IsD() && (!selected || (*fi).IsS())){
size_t ind=Index(mr,*fi);
remap.face[ind]=int(Index(ml,*fp));
++fp;
}
// hedge
remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex());
for(HEdgeIteratorRight hi=mr.hedge.begin(); hi!=mr.hedge.end(); ++hi)
if(!(*hi).IsD() && (!selected || (*hi).IsS())){
size_t ind=Index(mr,*hi);
assert(remap.hedge[ind]==Remap::InvalidIndex());
HEdgeIteratorLeft hp = Allocator<MeshLeft>::AddHEdges(ml,1);
(*hp).ImportData(*(hi));
remap.hedge[ind]=Index(ml,*hp);
}
// phase 2.
// copy data from ml to its corresponding elements in ml and adjacencies
// vertex
for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi)
if( !(*vi).IsD() && (!selected || (*vi).IsS())){
ml.vert[remap.vert[Index(mr,*vi)]].ImportData(*vi);
if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,*vi)]],*vi,remap);
}
// edge
for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei)
if(!(*ei).IsD() && (!selected || (*ei).IsS())){
ml.edge[remap.edge[Index(mr,*ei)]].ImportData(*ei);
// Edge to Vertex Adj
EdgeLeft &el = ml.edge[remap.edge[Index(mr,*ei)]];
if(HasEVAdjacency(ml) && HasEVAdjacency(mr)){
el.V(0) = &ml.vert[remap.vert[Index(mr,ei->cV(0))]];
el.V(1) = &ml.vert[remap.vert[Index(mr,ei->cV(1))]];
}
if(adjFlag) ImportEdgeAdj(ml,mr,el,*ei,remap);
}
// face
const size_t textureOffset = ml.textures.size();
bool WTFlag = HasPerWedgeTexCoord(mr) && (textureOffset>0);
for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi)
if(!(*fi).IsD() && (!selected || (*fi).IsS()))
{
FaceLeft &fl = ml.face[remap.face[Index(mr,*fi)]];
fl.Alloc(fi->VN());
if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){
for(int i = 0; i < fl.VN(); ++i)
fl.V(i) = &ml.vert[remap.vert[Index(mr,fi->cV(i))]];
}
fl.ImportData(*fi);
if(WTFlag)
for(int i = 0; i < fl.VN(); ++i)
fl.WT(i).n() += short(textureOffset);
if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,*fi)]],*fi,remap);
}
// hedge
for(HEdgeIteratorRight hi=mr.hedge.begin();hi!=mr.hedge.end();++hi)
if(!(*hi).IsD() && (!selected || (*hi).IsS())){
ml.hedge[remap.hedge[Index(mr,*hi)]].ImportData(*hi);
ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,*hi)]],*hi,remap,selected);
}
// phase 3.
// take care of other per mesh data: textures, attributes
// At the end concatenate the vector with texture names.
ml.textures.insert(ml.textures.end(),mr.textures.begin(),mr.textures.end());
// Attributes. Copy only those attributes that are present in both meshes
// Two attributes in different meshes are considered the same if they have the same
// name and the same type. This may be deceiving because they could in fact have
// different semantic, but this is up to the developer.
// If the left mesh has attributes that are not in the right mesh, their values for the elements
// of the right mesh will be uninitialized
unsigned int id_r;
typename std::set< PointerToAttribute >::iterator al, ar;
// per vertex attributes
for(al = ml.vert_attr.begin(); al != ml.vert_attr.end(); ++al)
if(!(*al)._name.empty()){
ar = mr.vert_attr.find(*al);
if(ar!= mr.vert_attr.end()){
id_r = 0;
for(VertexIteratorRight vi=mr.vert.begin();vi!=mr.vert.end();++vi,++id_r)
if( !(*vi).IsD() && (!selected || (*vi).IsS()))
memcpy((*al)._handle->At(remap.vert[Index(mr,*vi)]),(*ar)._handle->At(id_r),
(*al)._handle->SizeOf());
}
}
// per edge attributes
for(al = ml.edge_attr.begin(); al != ml.edge_attr.end(); ++al)
if(!(*al)._name.empty()){
ar = mr.edge_attr.find(*al);
if(ar!= mr.edge_attr.end()){
id_r = 0;
for(EdgeIteratorRight ei=mr.edge.begin();ei!=mr.edge.end();++ei,++id_r)
if( !(*ei).IsD() && (!selected || (*ei).IsS()))
memcpy((*al)._handle->At(remap.edge[Index(mr,*ei)]),(*ar)._handle->At(id_r),
(*al)._handle->SizeOf());
}
}
// per face attributes
for(al = ml.face_attr.begin(); al != ml.face_attr.end(); ++al)
if(!(*al)._name.empty()){
ar = mr.face_attr.find(*al);
if(ar!= mr.face_attr.end()){
id_r = 0;
for(FaceIteratorRight fi=mr.face.begin();fi!=mr.face.end();++fi,++id_r)
if( !(*fi).IsD() && (!selected || (*fi).IsS()))
memcpy((*al)._handle->At(remap.face[Index(mr,*fi)]),(*ar)._handle->At(id_r),
(*al)._handle->SizeOf());
}
}
// per mesh attributes
// if both ml and mr have an attribute with the same name, no action is done
// if mr has an attribute that is NOT present in ml, the attribute is added to ml
//for(ar = mr.mesh_attr.begin(); ar != mr.mesh_attr.end(); ++ar)
// if(!(*ar)._name.empty()){
// al = ml.mesh_attr.find(*ar);
// if(al== ml.mesh_attr.end())
// //...
// }
}
/*! \brief Copy the second mesh over the first one.
The first mesh is destroyed. If requested only the selected elements are copied.
*/
static void MeshCopy(MeshLeft& ml, ConstMeshRight& mr, bool selected=false, const bool adjFlag = false)
{
ml.Clear();
Mesh(ml,mr,selected,adjFlag);
ml.bbox.Import(mr.bbox);
}
/*! \brief %Append only the selected elements of second mesh to the first one.
It is just a wrap of the main Append::Mesh()
*/
static void Selected(MeshLeft& ml, ConstMeshRight& mr)
{
Mesh(ml,mr,true);
}
}; // end of class Append
} // End Namespace tri
} // End Namespace vcg
#endif

View File

@ -29,22 +29,22 @@
namespace vcg
{
class PointerToAttribute
{
public:
SimpleTempDataBase *_handle; // pointer to the SimpleTempData that stores the attribute
std::string _name; // name of the attribute
int _sizeof; // size of the attribute type (used only with VMI loading)
int _padding; // padding (used only with VMI loading)
//class PointerToAttribute
//{
// public:
// SimpleTempDataBase *_handle; // pointer to the SimpleTempData that stores the attribute
// std::string _name; // name of the attribute
// int _sizeof; // size of the attribute type (used only with VMI loading)
// 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); }
// 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)){};
};
// PointerToAttribute() : _type(typeid(void)){};
//};
namespace tetra
{
@ -195,7 +195,7 @@ class TetraMesh
typedef typename TetraMesh::TetraType TetraType;
typedef typename TetraMesh::TetraPointer TetraPointer;
typedef typename TetraMesh::ConstTetraPointer ConstTetraPointer;
typedef typename TetraMesh::TetraIterator TetraIterator
typedef typename TetraMesh::TetraIterator TetraIterator;
typedef typename TetraMesh::ConstTetraIterator ConstTetraIterator;
typedef vcg::PointerToAttribute PointerToAttribute;
@ -402,7 +402,8 @@ class TetraMesh
vn = 0;
en = 0;
fn = 0;
hn = 0;
tn = 0;
// hn = 0;
imark = 0;
C() = Color4b::Gray;
}
@ -692,17 +693,19 @@ bool HasFVAdjacency(const TetraMeshType &m) { return tetra::FaceVectorHasFVAdjac
//:::::::::::TETRA::::::::::::::::
template <class TetraType>
bool TetraVectorHasVTAdjacency(const std::vector<TetraType> &) { return TetraType::HasVTAdjacency(); }
template <class TetraType>
bool TetraVectorHasTTAdjacency(const std::vector<TetraType> &) { return TetraType::HasTTAdjacency(); }
template <class TetraMeshType>
bool HasTVAdjacency(const TetraMeshType &m) { return tetra::TetraVectorHasVTAdjacency(m.tetra); }
template <class TetraMeshType>
bool HasVFAdjacency(const TetraMeshType &m) { return tetra::FaceVectorHasVFAdjacency(m.face) && tetra::VertexVectorHasVFAdjacency(m.vert); }
template <class TetraMeshType>
bool HasVEAdjacency(const TetraMeshType &m) { return tetra::EdgeVectorHasVEAdjacency(m.edge) && tetra::VertexVectorHasVEAdjacency(m.vert); }
template <class TetraMeshType>
bool HasVTAdjacency(const TetraMeshType &m) { return tetra::VertexVectorHasVTAdjacency(m.vert) && tetra::TetraVectorHasVTAdjacency(m.tetra); }
template <class TetraMeshType>
bool HasTTAdjacency(const TetraMeshType &m) { return tetra::TetraVectorHasTTAdjacency(m.tetra); }
//template < class CType0, class CType1, class CType2 , class CType3>
//bool HasVEAdjacency (const TetraMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TetraMesh < CType0 , CType1, CType2, CType3>::VertContainer::value_type::HasVEAdjacency();}

View File

@ -24,6 +24,7 @@
#ifndef __VCG_TETRA_MESH_H
#define __VCG_TETRA_MESH_H
#define __VCG_TETRA_MESH
#define __VCG_MESH
#include <cassert>
#include <cstring>
@ -43,13 +44,13 @@
#include <wrap/callback.h>
#include <vcg/complex/exception.h>
#include <vcg/container/simple_temporary_data.h>
#include <vcg/complex/used_types.h>
#include <vcg/complex/tetrahedron/base.h>
#include <vcg/complex/allocate.h>
#include <vcg/complex/tetrahedron/allocate.h>
#include <vcg/simplex/face/pos.h>
#include <vcg/simplex/face/topology.h>
#include <vcg/simplex/edge/pos.h>
#include <vcg/simplex/edge/topology.h>
#include <vcg/simplex/tetrahedron/tetrahedron.h>
#include <vcg/simplex/tetrahedron/pos.h>
#include <vcg/complex/foreach.h>
#include <vcg/complex/algorithms/update/flag.h>
@ -61,5 +62,7 @@
#include <vcg/complex/append.h>
#undef __VCG_TETRA_MESH
#undef __VCG_MESH
#endif

View File

@ -92,11 +92,11 @@ template <template <typename> class A = DefaultDeriver, template <typename> clas
template <typename> class C = DefaultDeriver, template <typename> class D = DefaultDeriver,
template <typename> class E = DefaultDeriver, template <typename> class F = DefaultDeriver,
template <typename> class G = DefaultDeriver, template <typename> class H = DefaultDeriver >
class UsedTypes: public Arity12<DummyTypes,
Use< Vertex <UsedTypes< A, B, C, D , E, F, G, H > > > :: template AsVertexType,
class UsedTypes: public Arity13<DummyTypes,
Use< Vertex <UsedTypes< A, B, C, D , E, F, G, H > > > :: template AsVertexType,
Use< Edge <UsedTypes< A, B, C, D , E, F, G, H > > > :: template AsEdgeType,
Use< Face <UsedTypes< A, B, C, D , E, F, G, H > > > :: template AsFaceType,
Use< Tetra <UsedTypes< A, B, C, D , E, F, G, H > > > :: template AsTetraType,
Use< TetraSimp <UsedTypes< A, B, C, D , E, F, G, H > > > :: template AsTetraType,
Use< HEdge <UsedTypes< A, B, C, D , E, F, G, H > > > :: template AsHEdgeType,
A, B, C, D, E, F, G, H
> {
@ -117,7 +117,7 @@ struct _UsedTypes: public UsedTypes<
struct _Vertex: public Vertex<_UsedTypes>{};
struct _Edge : public Edge<_UsedTypes>{};
struct _Face : public Face<_UsedTypes>{};
struct _Tetra : public Tetra<_UsedTypes>{};
struct _Tetra : public TetraSimp<_UsedTypes>{};
struct _HEdge : public HEdge<_UsedTypes>{};
};

View File

@ -121,7 +121,18 @@ template <
template <typename> class G, template <typename> class H,
template <typename> class I, template <typename> class J,
template <typename> class K, template <typename> class L>
class Arity12: public L<Arity11<Base, A, B, C, D, E, F, G, H, I, J, K> > {};
class Arity12: public L<Arity11<Base, A, B, C, D, E, F, G, H, I, J, K> > {};
template <
class Base,
template <typename> class A, template <typename> class B,
template <typename> class C, template <typename> class D,
template <typename> class E, template <typename> class F,
template <typename> class G, template <typename> class H,
template <typename> class I, template <typename> class J,
template <typename> class K, template <typename> class L,
template <typename> class M >
class Arity13: public L<Arity12<Base, A, B, C, D, E, F, G, H, I, J, K, L> > {};
// chain with 2 template arguments on the derivers

View File

@ -30,13 +30,16 @@ added
****************************************************************************/
// #ifndef __VCG_TETRA_MESH
// #error "This file should not be included alone. It is automatically included by complex.h"
// #endif
#ifndef __VCG_TETRA_PLUS
#define __VCG_TETRA_PLUS
#include <vcg/space/point3.h>
#include <vcg/space/texcoord2.h>
#include <vcg/space/color4.h>
#include <vcg/simplex/tetrahedron/component.h>
//#include <vcg/space/point3.h>
//#include <vcg/space/texcoord2.h>
//#include <vcg/space/color4.h>
//#include <vcg/simplex/tetrahedron/component.h>
namespace vcg {
@ -46,111 +49,150 @@ The base class of all the recusive definition chain. It is just a container of t
These typenames must be known form all the derived classes.
*/
template <class BVT, class BET, class BFT, class BTT>
class TetraTypeHolder{
// template <class BVT, class BET, class BFT, class BTT>
// class TetraTypeHolder{
// public:
// typedef BVT VertexType;
// typedef typename VertexType::CoordType CoordType;
// typedef typename VertexType::ScalarType ScalarType;
// typedef BET EdgeType;
// typedef BFT FaceType;
// typedef BTT TetraType;
// typedef BVT *VertPointer;
// typedef BET *EdgePointer;
// typedef BFT *FacePointer;
// typedef BTT *TetraPointer;
// static void Name(std::vector<std::string> & name){}
// // prot
// };
// /* The base class form which we start to add our components.
// it has the empty definition for all the standard members (coords, color flags)
// Note:
// in order to avoid both virtual classes and ambiguous definitions all
// the subsequent overrides must be done in a sequence of derivation.
// In other words we cannot derive and add in a single derivation step
// (with multiple ancestor), both the real (non-empty) normal and color but
// we have to build the type a step a time (deriving from a single ancestor at a time).
// */
// template <class BVT, class BET=DumET, class BFT=DumFT, class BTT=DumTT>
// class TetraBase: public tetra::EmptyCore<
// TetraTypeHolder <BVT, BET, BFT, BTT> > {
// };
// // Metaprogramming Core
// template <class BVT, class BET, class BFT,class BTT,
// template <typename> class A>
// class TetraArity1: public A<TetraBase<BVT,BET,BFT,BTT> > {};
// template <class BVT, class BET, typename BFT, class BTT,
// template <typename> class A, template <typename> class B>
// class TetraArity2: public B<TetraArity1<BVT,BET,BFT,BTT, A> > {};
// template <class BVT, class BET, typename BFT,class BTT,
// template <typename> class A, template <typename> class B,
// template <typename> class C >
// class TetraArity3: public C<TetraArity2<BVT,BET,BFT,BTT, A, B> > {};
// template <class BVT, class BET, typename BFT,class BTT,
// template <typename> class A, template <typename> class B,
// template <typename> class C, template <typename> class D>
// class TetraArity4: public D<TetraArity3<BVT,BET,BFT,BTT, A, B, C> > {};
// template <class BVT, class BET, typename BFT,class BTT,
// template <typename> class A, template <typename> class B,
// template <typename> class C, template <typename> class D,
// template <typename> class E >
// class TetraArity5: public E<TetraArity4<BVT,BET,BFT,BTT, A, B, C, D> > {};
// template <class BVT, class BET, typename BFT,class BTT,
// template <typename> class A, template <typename> class B,
// template <typename> class C, template <typename> class D,
// template <typename> class E, template <typename> class F >
// class TetraArity6: public F<TetraArity5<BVT,BET,BFT,BTT, A, B, C, D, E> > {};
// template <class BVT, class BET, typename BFT,class BTT,
// template <typename> class A, template <typename> class B,
// template <typename> class C, template <typename> class D,
// template <typename> class E, template <typename> class F,
// template <typename> class G >
// class TetraArity7: public G<TetraArity6<BVT,BET,BFT,BTT, A, B, C, D, E, F> > {};
// template <class BVT, class BET, typename BFT,class BTT,
// template <typename> class A, template <typename> class B,
// template <typename> class C, template <typename> class D,
// template <typename> class E, template <typename> class F,
// template <typename> class G, template <typename> class H >
// class TetraArity8: public H<TetraArity7<BVT,BET,BFT,BTT, A, B, C, D, E, F, G> > {};
// /* The Real Big Face class;
// The class __FaceArityMax__ is the one that is the Last to be derived,
// and therefore is the only one to know the real members
// (after the many overrides) so all the functions with common behaviour
// using the members defined in the various Empty/nonEmpty component classes
// MUST be defined here.
// I.e. IsD() that uses the overridden Flags() member must be defined here.
// */
// template <class BVT, class BET, typename BFT,class BTT,
// template <typename> class A, template <typename> class B,
// template <typename> class C, template <typename> class D,
// template <typename> class E, template <typename> class F,
// template <typename> class G, template <typename> class H,
// template <typename> class I >
// class TetraArityMax: public I<TetraArity8<BVT,BET,BFT,BTT, A, B, C, D, E, F, G, H> > {
template <class UserTypes>
class TetraTypeHolder: public UserTypes {
public:
typedef BVT VertexType;
typedef typename VertexType::CoordType CoordType;
typedef typename VertexType::ScalarType ScalarType;
typedef BET EdgeType;
typedef BFT FaceType;
typedef BTT TetraType;
typedef BVT *VertPointer;
typedef BET *EdgePointer;
typedef BFT *FacePointer;
typedef BTT *TetraPointer;
static void Name(std::vector<std::string> & name){}
template <class LeftT>
void ImportData(const LeftT & ){}
static void Name(std::vector<std::string> & /* name */){}
// prot
inline int VN() const { return 4;}
};
/* The base class form which we start to add our components.
it has the empty definition for all the standard members (coords, color flags)
Note:
in order to avoid both virtual classes and ambiguous definitions all
in order to avoid both virtual classes and ambiguous definitions all
the subsequent overrides must be done in a sequence of derivation.
In other words we cannot derive and add in a single derivation step
(with multiple ancestor), both the real (non-empty) normal and color but
we have to build the type a step a time (deriving from a single ancestor at a time).
In other words we cannot derive and add in a single derivation step
(with multiple ancestor), both the real (non-empty) normal and color but
we have to build the type a step a time (deriving from a single ancestor at a time).
*/
template <class BVT, class BET=DumET, class BFT=DumFT, class BTT=DumTT>
class TetraBase: public tetra::EmptyVertexRef<
tetra::EmptyAdj<
TetraTypeHolder <BVT, BET, BFT, BTT> > > {
};
// Metaprogramming Core
template <class BVT, class BET, class BFT,class BTT,
template <typename> class A>
class TetraArity1: public A<TetraBase<BVT,BET,BFT,BTT> > {};
template <class BVT, class BET, typename BFT, class BTT,
template <typename> class A, template <typename> class B>
class TetraArity2: public B<TetraArity1<BVT,BET,BFT,BTT, A> > {};
template <class BVT, class BET, typename BFT,class BTT,
template <typename> class A, template <typename> class B,
template <typename> class C >
class TetraArity3: public C<TetraArity2<BVT,BET,BFT,BTT, A, B> > {};
template <class BVT, class BET, typename BFT,class BTT,
template <typename> class A, template <typename> class B,
template <typename> class C, template <typename> class D>
class TetraArity4: public D<TetraArity3<BVT,BET,BFT,BTT, A, B, C> > {};
template <class BVT, class BET, typename BFT,class BTT,
template <typename> class A, template <typename> class B,
template <typename> class C, template <typename> class D,
template <typename> class E >
class TetraArity5: public E<TetraArity4<BVT,BET,BFT,BTT, A, B, C, D> > {};
template <class BVT, class BET, typename BFT,class BTT,
template <typename> class A, template <typename> class B,
template <typename> class C, template <typename> class D,
template <typename> class E, template <typename> class F >
class TetraArity6: public F<TetraArity5<BVT,BET,BFT,BTT, A, B, C, D, E> > {};
template <class BVT, class BET, typename BFT,class BTT,
template <typename> class A, template <typename> class B,
template <typename> class C, template <typename> class D,
template <typename> class E, template <typename> class F,
template <typename> class G >
class TetraArity7: public G<TetraArity6<BVT,BET,BFT,BTT, A, B, C, D, E, F> > {};
template <class BVT, class BET, typename BFT,class BTT,
template <typename> class A, template <typename> class B,
template <typename> class C, template <typename> class D,
template <typename> class E, template <typename> class F,
template <typename> class G, template <typename> class H >
class TetraArity8: public H<TetraArity7<BVT,BET,BFT,BTT, A, B, C, D, E, F, G> > {};
/* The Real Big Face class;
The class __FaceArityMax__ is the one that is the Last to be derived,
and therefore is the only one to know the real members
(after the many overrides) so all the functions with common behaviour
using the members defined in the various Empty/nonEmpty component classes
MUST be defined here.
I.e. IsD() that uses the overridden Flags() member must be defined here.
*/
template <class UserTypes>
class TetraSimpBase: public
tetrahedron::EmptyCore< TetraTypeHolder <UserTypes> > {
};
template <class BVT, class BET, typename BFT,class BTT,
template <typename> class A, template <typename> class B,
template <typename> class C, template <typename> class D,
template <class UserTypes,
template <typename> class A, template <typename> class B,
template <typename> class C, template <typename> class D,
template <typename> class E, template <typename> class F,
template <typename> class G, template <typename> class H,
template <typename> class I >
class TetraArityMax: public I<TetraArity8<BVT,BET,BFT,BTT, A, B, C, D, E, F, G, H> > {
template <typename> class I, template <typename> class J,
template <typename> class K, template <typename> class L>
class TetraArityMax: public Arity12<TetraSimpBase<UserTypes>, A, B, C, D, E, F, G, H, I, J, K, L> {
// ----- Flags stuff -----
public:
@ -160,7 +202,7 @@ public:
DELETED = 0x00000001, // Face is deleted from the mesh
NOTREAD = 0x00000002, // Face of the mesh is not readable
NOTWRITE = 0x00000004, // Face of the mesh is not writable
VISITED = 0x00000010, // Face has been visited. Usualy this is a per-algorithm used bit.
VISITED = 0x00000010, // Face has been visited. Usualy this is a per-algorithm used bit.
SELECTED = 0x00000020, // Face is selected. Algorithms should try to work only on selected face (if explicitly requested)
// Border _flags, it is assumed that BORDERi = BORDER0<<i
BORDER0 = 0x00000040,
@ -174,17 +216,17 @@ public:
/// checks if the Face is deleted
bool IsD() const {return (this->Flags() & DELETED) != 0;}
bool IsD() const {return (this->cFlags() & DELETED) != 0;}
/// checks if the Face is readable
bool IsR() const {return (this->Flags() & NOTREAD) == 0;}
bool IsR() const {return (this->cFlags() & NOTREAD) == 0;}
/// checks if the Face is modifiable
bool IsW() const {return (this->Flags() & NOTWRITE)== 0;}
bool IsW() const {return (this->cFlags() & NOTWRITE)== 0;}
/// This funcion checks whether the Face is both readable and modifiable
bool IsRW() const {return (this->Flags() & (NOTREAD | NOTWRITE)) == 0;}
bool IsRW() const {return (this->cFlags() & (NOTREAD | NOTWRITE)) == 0;}
/// checks if the Face is Modified
bool IsS() const {return (this->Flags() & SELECTED) != 0;}
bool IsS() const {return (this->cFlags() & SELECTED) != 0;}
/// checks if the Face is Modified
bool IsV() const {return (this->Flags() & VISITED) != 0;}
bool IsV() const {return (this->cFlags() & VISITED) != 0;}
/** Set the flag value
@param flagp Valore da inserire nel flag
@ -272,8 +314,8 @@ public:
};
template < typename T=int>
class TetraDefaultDeriver : public T {};
// template < typename T=int>
// class TetraDefaultDeriver : public T {};
/*
@ -303,22 +345,31 @@ TTAdj //topology: face face adj
*/
template <class BVT, class BET, class BFT, class BTT,
template <typename> class A = TetraDefaultDeriver, template <typename> class B = TetraDefaultDeriver,
template <typename> class C = TetraDefaultDeriver, template <typename> class D = TetraDefaultDeriver,
template <typename> class E = TetraDefaultDeriver, template <typename> class F = TetraDefaultDeriver,
template <typename> class G = TetraDefaultDeriver, template <typename> class H = TetraDefaultDeriver,
template <typename> class I = TetraDefaultDeriver >
class TetraSimp3: public TetraArityMax<BVT,BET,BFT,BTT, A, B, C, D, E, F, G, H, I> {};
class DumTT;
template <class BVT, class BET, class BFT,
template <typename> class A = TetraDefaultDeriver, template <typename> class B = TetraDefaultDeriver,
template <typename> class C = TetraDefaultDeriver, template <typename> class D = TetraDefaultDeriver,
template <typename> class E = TetraDefaultDeriver, template <typename> class F = TetraDefaultDeriver,
template <typename> class G = TetraDefaultDeriver, template <typename> class H = TetraDefaultDeriver,
template <typename> class I = TetraDefaultDeriver >
class TetraSimp2: public TetraArityMax<BVT,BET,BFT,DumTT, A, B, C, D, E, F, G, H, I> {};
// template <class BVT, class BET, class BFT, class BTT,
// template <typename> class A = TetraDefaultDeriver, template <typename> class B = TetraDefaultDeriver,
// template <typename> class C = TetraDefaultDeriver, template <typename> class D = TetraDefaultDeriver,
// template <typename> class E = TetraDefaultDeriver, template <typename> class F = TetraDefaultDeriver,
// template <typename> class G = TetraDefaultDeriver, template <typename> class H = TetraDefaultDeriver,
// template <typename> class I = TetraDefaultDeriver >
// class TetraSimp3: public TetraArityMax<BVT,BET,BFT,BTT, A, B, C, D, E, F, G, H, I> {};
// class DumTT;
// template <class BVT, class BET, class BFT,
// template <typename> class A = TetraDefaultDeriver, template <typename> class B = TetraDefaultDeriver,
// template <typename> class C = TetraDefaultDeriver, template <typename> class D = TetraDefaultDeriver,
// template <typename> class E = TetraDefaultDeriver, template <typename> class F = TetraDefaultDeriver,
// template <typename> class G = TetraDefaultDeriver, template <typename> class H = TetraDefaultDeriver,
// template <typename> class I = TetraDefaultDeriver >
// class TetraSimp2: public TetraArityMax<BVT,BET,BFT,DumTT, A, B, C, D, E, F, G, H, I> {};
template <class UserTypes,
template <typename> class A = DefaultDeriver, template <typename> class B = DefaultDeriver,
template <typename> class C = DefaultDeriver, template <typename> class D = DefaultDeriver,
template <typename> class E = DefaultDeriver, template <typename> class F = DefaultDeriver,
template <typename> class G = DefaultDeriver, template <typename> class H = DefaultDeriver,
template <typename> class I = DefaultDeriver, template <typename> class J = DefaultDeriver,
template <typename> class K = DefaultDeriver, template <typename> class L = DefaultDeriver>
class TetraSimp: public TetraArityMax<UserTypes, A, B, C, D, E, F, G, H, I, J, K, L> {
public: typedef AllTypes::ATetraType IAm; typedef UserTypes TypesPool;};
}// end namespace
#endif

View File

@ -37,7 +37,7 @@ added
#include <vcg/space/tetra3.h>
namespace vcg {
namespace tetra {
namespace tetrahedron {
/*
Some naming Rules
All the Components that can be added to a tetra should be defined in the namespace tetra:
@ -68,8 +68,8 @@ public:
ColorType &C() { static ColorType dummycolor(vcg::Color4b::White); assert(0); return dummycolor; }
ColorType cC() const { static ColorType dummycolor(vcg::Color4b::White); assert(0); return dummycolor; }
static bool HasColor() { return false; }
static bool IsColorEnabled() const { return T::TetraType::HasColor(); }
static bool HasColor() { return false; }
static bool IsColorEnabled() { return T::TetraType::HasColor(); }
//Empty Quality
typedef float QualityType;
@ -81,8 +81,8 @@ public:
static bool HasQuality() { return false; }
static bool HasQuality3() { return false; }
static bool IsQualityEnabled() const { return T::TetraType::HasQuality(); }
static bool IsQuality3Enabled() const { return T::TetraType::HasQuality3(); }
bool IsQualityEnabled() const { return T::TetraType::HasQuality(); }
bool IsQuality3Enabled() const { return T::TetraType::HasQuality3(); }
//Empty flags
int &Flags() { static int dummyflags(0); assert(0); return dummyflags; }
@ -94,12 +94,12 @@ public:
//Empty IMark
typedef int MarkType;
inline void InitIMark() { }
inline int & IMark() { assert(0); static int tmp=-1; return tmp;}
inline const int IMark() const {return 0;}
inline void InitIMark() { }
inline int & IMark() { assert(0); static int tmp=-1; return tmp;}
inline int cIMark() const {return 0;}
static bool HasMark() { return false; }
static bool HasMarkOcc() { return false; }
static bool HasMark() { return false; }
static bool HasMarkOcc() { return false; }
//Empty Adjacency
typedef int VFAdjType;
@ -109,9 +109,19 @@ public:
typename T::TetraPointer & TTp( const int ) { static typename T::TetraPointer tp=0; assert(0); return tp; }
typename T::TetraPointer const cTTp( const int ) const { static typename T::TetraPointer const tp=0; assert(0); return tp; }
char & VTi( const int j ) { static char z=0; assert(0); return z; }
char & TTi( const int j ) { static char z=0; assert(0); return z; }
char & VTi( const int j ) { static char z=0; assert(0); return z; }
char cVTi( const int j ) const { static char z=0; assert(0); return z; }
char & TTi( const int j ) { static char z=0; assert(0); return z; }
char cTTi( const int j ) const { static char z=0; assert(0); return z; }
bool IsVTInitialized(const int j) const {return static_cast<const typename T::TetraType *>(this)->cVTi(j)!=-1;}
void VTClear(int j) {
if(IsVTInitialized(j)) {
static_cast<typename T::TetraPointer>(this)->VTp(j)=0;
static_cast<typename T::TetraPointer>(this)->VTi(j)=-1;
}
}
static bool HasVTAdjacency() { return false; }
static bool HasTTAdjacency() { return false; }
static bool HasTTAdjacencyOcc() { return false; }
@ -121,10 +131,7 @@ public:
void ImportData(const RightValuteType & ) {}
static void Name(std::vector<std::string> & name) { T::Name(name); }
}
};
/*-------------------------- VERTEX ----------------------------------------*/
// template <class T> class EmptyVertexRef: public T {
// public:
@ -148,15 +155,17 @@ public:
v[2]=0;
v[3]=0;
}
typedef typename T::VertexType::CoordType CoordType;
typedef typename T::VertexType::ScalarType ScalarType;
inline typename T::VertexType * & V( const int j ) { assert(j>=0 && j<4); return v[j]; }
inline typename T::VertexType * const & V( const int j ) const { assert(j>=0 && j<4); return v[j]; }
inline typename T::VertexType * const cV( const int j ) const { assert(j>=0 && j<4); return v[j]; }
inline typename T::VertexType * & V( const int j ) { assert(j>=0 && j<4); return v[j]; }
inline typename T::VertexType * const & V( const int j ) const { assert(j>=0 && j<4); return v[j]; }
inline typename T::VertexType * const cV( const int j ) const { assert(j>=0 && j<4); return v[j]; }
// Shortcut per accedere ai punti delle facce
inline typename T::CoordType & P( const int j ) { assert(j>=0 && j<4); return v[j]->P(); }
inline const typename T::CoordType & P( const int j ) const { assert(j>=0 && j<4); return v[j]->cP(); }
inline const typename T::CoordType &cP( const int j ) const { assert(j>=0 && j<4); return v[j]->cP(); }
inline typename CoordType & P( const int j ) { assert(j>=0 && j<4); return v[j]->P(); }
inline const typename CoordType & P( const int j ) const { assert(j>=0 && j<4); return v[j]->cP(); }
inline const typename CoordType &cP( const int j ) const { assert(j>=0 && j<4); return v[j]->cP(); }
/** Return the pointer to the ((j+1)%3)-th vertex of the face.
@param j Index of the face vertex.
@ -175,18 +184,18 @@ public:
inline const typename T::VertexType * const & cV3( const int j ) const { return cV((j+3)%4);}
/// Shortcut to get vertex values
inline typename T::CoordType & P0( const int j ) { return V(j)->P();}
inline typename T::CoordType & P1( const int j ) { return V((j+1)%4)->P();}
inline typename T::CoordType & P2( const int j ) { return V((j+2)%4)->P();}
inline typename T::CoordType & P3( const int j ) { return V((j+3)%4)->P();}
inline const typename T::CoordType & P0( const int j ) const { return V(j)->P();}
inline const typename T::CoordType & P1( const int j ) const { return V((j+1)%4)->P();}
inline const typename T::CoordType & P2( const int j ) const { return V((j+2)%4)->P();}
inline const typename T::CoordType & P3( const int j ) const { return V((j+3)%4)->P();}
inline const typename T::CoordType & cP0( const int j ) const { return cV(j)->P();}
inline const typename T::CoordType & cP1( const int j ) const { return cV((j+1)%4)->P();}
inline const typename T::CoordType & cP2( const int j ) const { return cV((j+2)%4)->P();}
inline const typename T::CoordType & cP3( const int j ) const { return cV((j+3)%4)->P();}
inline typename CoordType & P0( const int j ) { return V(j)->P();}
inline typename CoordType & P1( const int j ) { return V((j+1)%4)->P();}
inline typename CoordType & P2( const int j ) { return V((j+2)%4)->P();}
inline typename CoordType & P3( const int j ) { return V((j+3)%4)->P();}
inline const typename CoordType & P0( const int j ) const { return V(j)->P();}
inline const typename CoordType & P1( const int j ) const { return V((j+1)%4)->P();}
inline const typename CoordType & P2( const int j ) const { return V((j+2)%4)->P();}
inline const typename CoordType & P3( const int j ) const { return V((j+3)%4)->P();}
inline const typename CoordType & cP0( const int j ) const { return cV(j)->P();}
inline const typename CoordType & cP1( const int j ) const { return cV((j+1)%4)->P();}
inline const typename CoordType & cP2( const int j ) const { return cV((j+2)%4)->P();}
inline const typename CoordType & cP3( const int j ) const { return cV((j+3)%4)->P();}
static bool HasVertexRef() { return true; }
static bool HasTVAdjacency() { return true; }
@ -194,7 +203,7 @@ public:
static void Name(std::vector<std::string> & name){name.push_back(std::string("VertexRef"));T::Name(name);}
template <class RightValueType>
void ImportData(const RightValuteType & rTetra) { T::ImportData(rTetra); }
void ImportData(const RightValueType & rTetra) { T::ImportData(rTetra); }
private:
typename T::VertexType *v[4];
@ -259,7 +268,7 @@ public:
typedef int FlagType;
BitFlags(){_flags=0;}
int &Flags() {return _flags; }
int Flags() const {return _flags; }
int cFlags() const {return _flags; }
template <class RightValueType>
void ImportData(const RightValueType & rightT){
@ -368,7 +377,14 @@ public:
static bool HasMarkOcc() { return false; }
inline void InitIMark() { _imark = 0; }
inline int & IMark() { return _imark;}
inline const int & IMark() const {return _imark;}
inline int cIMark() const {return _imark;}
template <class RightValueType>
void ImportData(const RightValueType & rightT){
if(rightT.IsMarkEnabled()) IMark() = rightT.cIMark();
T::ImportData(rightT);
}
static void Name(std::vector<std::string> & name){name.push_back(std::string("Mark"));T::Name(name);}
private:
@ -396,7 +412,16 @@ public:
template <class T> class VTAdj: public T {
public:
VTAdj() { _vtp[0]=0; _vtp[1]=0; _vtp[2]=0; _vtp[3]=0; }
VTAdj() {
_vtp[0]=0;
_vtp[1]=0;
_vtp[2]=0;
_vtp[3]=0;
_vti[0]=-1;
_vti[1]=-1;
_vti[2]=-1;
_vti[3]=-1;
}
typename T::TetraPointer & VTp( const int j ) { assert( j >= 0 && j < 4 ); return _vtp[j]; }
typename T::TetraPointer const VTp( const int j ) const { assert( j >= 0 && j < 4 ); return _vtp[j]; }
@ -410,6 +435,8 @@ public:
static void Name( std::vector< std::string > & name ) { name.push_back( std::string("VTAdj") ); T::Name(name); }
template <class RightValueType>
void ImportData(const RightValueType & rightT){T::ImportData(rightT);}
private:
typename T::TetraPointer _vtp[4];
char _vti[4];
@ -444,6 +471,9 @@ public:
static bool HasTTAdjacencyOcc() { return false; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("TTAdj"));T::Name(name);}
template <class RightValueType>
void ImportData(const RightValueType & rightT){T::ImportData(rightT);}
private:
typename T::TetraPointer _ttp[4] ;
char _tti[4] ;

View File

@ -23,6 +23,6 @@
#ifndef __VCGLIB_TETRAHEDRON
#define __VCGLIB_TETRAHEDRON
#define TETRA_TYPE Tetrahedron
#include <vcg/simplex/tetrahedron/base.h>
// #include <vcg/simplex/tetrahedron/base.h>
#endif

View File

@ -96,7 +96,7 @@ public:
static bool HasTexCoord() { return false; }
inline bool IsTexCoordEnabled() const { return TT::VertexType::HasTexCoord();}
typename TT::TetraPointer &VTp() { static typename TT::TetraPointer tp = 0; assert(0); return tp; }
typename TT::TetraPointer &VTp() { static typename TT::TetraPointer tp = 0; assert(0); return tp; }
typename TT::TetraPointer cVTp() const { static typename TT::TetraPointer tp = 0; assert(0); return tp; }
int &VTi() { static int z = 0; return z; }
static bool HasVTAdjacency() { return false; }

View File

@ -35,8 +35,10 @@ $Log: not supported by cvs2svn $
#ifndef __VCGLIB_TETRAEXPORT_PLY
#define __VCGLIB_TETRAEXPORT_PLY
#include<wrap/ply/io_mask.h>
#include<wrap/io_tetramesh/io_mask.h>
#include<wrap/io_tetramesh/io_ply.h>
#include<wrap/io_trimesh/precision.h>
#include <stdio.h>
@ -48,525 +50,430 @@ namespace io {
template <class SaveMeshType>
class ExporterPLY
{
// Si occupa di convertire da un tipo all'altro.
// usata nella saveply per matchare i tipi tra stotype e memtype.
// Ad es se in memoria c'e' un int e voglio salvare un float
// src sara in effetti un puntatore a int il cui valore deve
// essere convertito al tipo di ritorno desiderato (stotype)
// Si occupa di convertire da un tipo all'altro.
// usata nella saveply per matchare i tipi tra stotype e memtype.
// Ad es se in memoria c'e' un int e voglio salvare un float
// src sara in effetti un puntatore a int il cui valore deve
// essere convertito al tipo di ritorno desiderato (stotype)
template <class StoType>
static void PlyConv(int mem_type, void *src, StoType &dest)
{
switch (mem_type){
case ply::T_FLOAT : dest = (StoType) (* ((float *) src)); break;
case ply::T_DOUBLE: dest = (StoType) (* ((double *) src)); break;
case ply::T_INT : dest = (StoType) (* ((int *) src)); break;
case ply::T_SHORT : dest = (StoType) (* ((short *) src)); break;
case ply::T_CHAR : dest = (StoType) (* ((char *) src)); break;
case ply::T_UCHAR : dest = (StoType) (* ((unsigned char *)src)); break;
default : assert(0);
}
}
template <class StoType>
static void PlyConv(int mem_type, void *src, StoType &dest)
{
switch (mem_type){
case ply::T_FLOAT : dest = (StoType) (* ((float *) src)); break;
case ply::T_DOUBLE : dest = (StoType) (* ((double *) src)); break;
case ply::T_INT : dest = (StoType) (* ((int *) src)); break;
case ply::T_SHORT : dest = (StoType) (* ((short *) src)); break;
case ply::T_CHAR : dest = (StoType) (* ((char *) src)); break;
case ply::T_UCHAR : dest = (StoType) (* ((unsigned char *)src)); break;
default : assert(0);
}
}
public:
typedef ::vcg::ply::PropDescriptor PropDescriptor ;
typedef typename SaveMeshType::VertexPointer VertexPointer;
typedef typename SaveMeshType::ScalarType ScalarType;
typedef typename SaveMeshType::VertexType VertexType;
typedef typename SaveMeshType::TetraType TetraType;
typedef typename SaveMeshType::TetraPointer TetraPointer;
typedef typename SaveMeshType::VertexIterator VertexIterator;
typedef typename SaveMeshType::TetraIterator TetraIterator;
typedef ::vcg::ply::PropDescriptor PropDescriptor ;
typedef typename SaveMeshType::VertexPointer VertexPointer;
typedef typename SaveMeshType::ScalarType ScalarType;
typedef typename SaveMeshType::VertexType VertexType;
typedef typename SaveMeshType::TetraType TetraType;
typedef typename SaveMeshType::TetraPointer TetraPointer;
typedef typename SaveMeshType::VertexIterator VertexIterator;
typedef typename SaveMeshType::TetraIterator TetraIterator;
static bool Save(SaveMeshType &m, const char * filename, bool binary=true)
{
PlyInfo pi;
return Save(m,filename,binary,pi);
}
static bool Save(SaveMeshType &m, const char * filename, bool binary=true)
{
PlyInfo pi;
return Save(m,filename,binary,pi);
}
static bool Save(SaveMeshType &m, const char * filename, int savemask )
{
PlyInfo pi;
pi.mask=savemask;
return Save(m,filename,true,pi);
}
static bool Save(SaveMeshType &m, const char * filename, int savemask, bool binary=true )
{
PlyInfo pi;
pi.mask=savemask;
return Save(m,filename,binary,pi);
}
static bool Save(SaveMeshType &m, const char * filename, bool binary, PlyInfo &pi ) // V1.0
{
FILE * fpout;
int i;
const char * hbin = "binary_little_endian";
const char * hasc = "ascii";
const char * h;
static bool Save(SaveMeshType &m, const char * filename, bool binary, PlyInfo & pi ) // V1.0
{
FILE * fpout;
int i;
bool multit = false;
const char * hbin = "binary_little_endian";
const char * hasc = "ascii";
const char * h;
if(binary) h=hbin;
else h=hasc;
bool multit = false;
fpout = fopen(filename,"wb");
if(fpout==NULL) {
pi.status=::vcg::ply::E_CANTOPEN;
return false;
}
fprintf(fpout,
"ply\n"
"format %s 1.0\n"
"comment VCGLIB generated\n"
,h
);
//if( pi.mask & ply::PLYMask::PM_WEDGTEXCOORD )
//{
// //const char * TFILE = "TextureFile";
// //for(i=0;i<textures.size();++i)
// // fprintf(fpout,"comment %s %s\n", TFILE, (const char *)(textures[i]) );
// //if(textures.size()>1 && (HasPerWedgeTexture() || HasPerVertexTexture())) multit = true;
//}
//if( (pi.mask & PLYMask::PM_CAMERA) && camera.IsValid() )
/*{
fprintf(fpout,
"element camera 1\n"
"property float view_px\n"
"property float view_py\n"
"property float view_pz\n"
"property float x_axisx\n"
"property float x_axisy\n"
"property float x_axisz\n"
"property float y_axisx\n"
"property float y_axisy\n"
"property float y_axisz\n"
"property float z_axisx\n"
"property float z_axisy\n"
"property float z_axisz\n"
"property float focal\n"
"property float scalex\n"
"property float scaley\n"
"property float centerx\n"
"property float centery\n"
"property int viewportx\n"
"property int viewporty\n"
"property float k1\n"
"property float k2\n"
"property float k3\n"
"property float k4\n"
);
}*/
fprintf(fpout,
"element vertex %d\n"
"property float x\n"
"property float y\n"
"property float z\n"
,m.vn
);
const int DGT = vcg::tri::io::Precision<ScalarType>::digits();
const int DGTVQ = vcg::tri::io::Precision<typename VertexType::QualityType>::digits();
const int DGTVR = vcg::tri::io::Precision<typename VertexType::RadiusType>::digits();
const int DGTTQ = vcg::tri::io::Precision<typename TetraType::QualityType>::digits();
if( pi.mask & ply::PLYMask::PM_VERTFLAGS )
{
fprintf(fpout,
"property int flags\n"
);
}
if( HasPerVertexColor(m) && (pi.mask & ply::PLYMask::PM_VERTCOLOR) )
{
fprintf(fpout,
"property uchar red\n"
"property uchar green\n"
"property uchar blue\n"
"property uchar alpha\n"
);
}
if(binary) h=hbin;
else h=hasc;
if( m.HasPerVertexQuality() && (pi.mask & ply::PLYMask::PM_VERTQUALITY) )
{
fprintf(fpout,
"property float quality\n"
);
}
fpout = fopen(filename,"wb");
if(fpout==NULL) {
pi.status=::vcg::ply::E_CANTOPEN;
return ::vcg::ply::E_CANTOPEN;
}
for(i=0;i<pi.vdn;i++)
fprintf(fpout,"property %s %s\n",pi.VertexData[i].stotypename(),pi.VertexData[i].propname);
fprintf(fpout,
"element tetra %d\n"
"property list uchar int vertex_indices\n"
,m.tn
);
fprintf(fpout,
"ply\n"
"format %s 1.0\n"
"comment VCGLIB generated\n"
,h
);
if( pi.mask & ply::PLYMask::PM_TETRAFLAGS )
{
fprintf(fpout,
"property int flags\n"
);
}
//if( pi.mask & ply::PLYMask::PM_WEDGTEXCOORD )
//{
// //const char * TFILE = "TextureFile";
if( VertexType::HasTexture() /*|| VertexType::HasPerWedgeTexture()*/ )
{
fprintf(fpout,
"property list uchar float texcoord\n"
);
// //for(i=0;i<textures.size();++i)
// // fprintf(fpout,"comment %s %s\n", TFILE, (const char *)(textures[i]) );
if(multit)
fprintf(fpout,
"property int texnumber\n"
);
}
// //if(textures.size()>1 && (HasPerWedgeTexture() || HasPerVertexTexture())) multit = true;
//}
if( TetraType::HasTetraColor() && (pi.mask & ply::PLYMask::PM_TETRACOLOR) )
{
fprintf(fpout,
"property uchar red\n"
"property uchar green\n"
"property uchar blue\n"
"property uchar alpha\n"
);
}
//if ( m.HasPerWedgeColor() && (pi.mask & ply::PLYMask::PM_WEDGCOLOR) )
//{
// fprintf(fpout,
// "property list uchar float color\n"
// );
//}
//if( (pi.mask & PLYMask::PM_CAMERA) && camera.IsValid() )
/*{
fprintf(fpout,
"element camera 1\n"
"property float view_px\n"
"property float view_py\n"
"property float view_pz\n"
"property float x_axisx\n"
"property float x_axisy\n"
"property float x_axisz\n"
"property float y_axisx\n"
"property float y_axisy\n"
"property float y_axisz\n"
"property float z_axisx\n"
"property float z_axisy\n"
"property float z_axisz\n"
"property float focal\n"
"property float scalex\n"
"property float scaley\n"
"property float centerx\n"
"property float centery\n"
"property int viewportx\n"
"property int viewporty\n"
"property float k1\n"
"property float k2\n"
"property float k3\n"
"property float k4\n"
);
}*/
if( m.HasPerTetraQuality() && (pi.mask & ply::PLYMask::PM_TETRAQUALITY) )
{
fprintf(fpout,
"property float quality\n"
);
}
for(i=0;i<pi.fdn;i++)
fprintf(fpout,"property %s %s\n",pi.TetraData[i].stotypename(),pi.TetraData[i].propname);
fprintf(fpout, "end_header\n" );
// Salvataggio camera
//if( (pi.mask & ply::PLYMask::PM_CAMERA) && camera.IsValid() )
//{
//if(binary)
//{
// float t[17];
// t[ 0] = camera.view_p[0];
// t[ 1] = camera.view_p[1];
// t[ 2] = camera.view_p[2];
// t[ 3] = camera.x_axis[0];
// t[ 4] = camera.x_axis[1];
// t[ 5] = camera.x_axis[2];
// t[ 6] = camera.y_axis[0];
// t[ 7] = camera.y_axis[1];
// t[ 8] = camera.y_axis[2];
// t[ 9] = camera.z_axis[0];
// t[10] = camera.z_axis[1];
// t[11] = camera.z_axis[2];
// t[12] = camera.f;
// t[13] = camera.s[0];
// t[14] = camera.s[1];
// t[15] = camera.c[0];
// t[16] = camera.c[1];
// fwrite(t,sizeof(float),17,fpout);
// fwrite( camera.viewport,sizeof(int),2,fpout );
// t[ 0] = camera.k[0];
// t[ 1] = camera.k[1];
// t[ 2] = camera.k[2];
// t[ 3] = camera.k[3];
// fwrite(t,sizeof(float),4,fpout);
//}
//else
//{
// fprintf(fpout,"%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d %d %g %g %g %g\n"
// ,camera.view_p[0]
// ,camera.view_p[1]
// ,camera.view_p[2]
// ,camera.x_axis[0]
// ,camera.x_axis[1]
// ,camera.x_axis[2]
// ,camera.y_axis[0]
// ,camera.y_axis[1]
// ,camera.y_axis[2]
// ,camera.z_axis[0]
// ,camera.z_axis[1]
// ,camera.z_axis[2]
// ,camera.f
// ,camera.s[0]
// ,camera.s[1]
// ,camera.c[0]
// ,camera.c[1]
// ,camera.viewport[0]
// ,camera.viewport[1]
// ,camera.k[0]
// ,camera.k[1]
// ,camera.k[2]
// ,camera.k[3]
// );
//}
//}
// VERT
const char* vttp = vcg::tri::io::Precision<ScalarType>::typeName();
fprintf(fpout,"element vertex %d\n",m.vn);
fprintf(fpout,"property %s x\n",vttp);
fprintf(fpout,"property %s y\n",vttp);
fprintf(fpout,"property %s z\n",vttp);
int j;
std::vector<int> FlagV;
VertexPointer vp;
VertexIterator vi;
for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi)
{
vp=&(*vi);
FlagV.push_back(vp->Flags()); // Salva in ogni caso flag del vertice
if( ! vp->IsD() )
{
if(binary)
{
float t;
if( HasPerVertexFlags(m) &&( pi.mask & Mask::IOM_VERTFLAGS) )
{
fprintf(fpout,
"property int flags\n"
);
}
t = float(vp->P()[0]); fwrite(&t,sizeof(float),1,fpout);
t = float(vp->P()[1]); fwrite(&t,sizeof(float),1,fpout);
t = float(vp->P()[2]); fwrite(&t,sizeof(float),1,fpout);
if( pi.mask & ply::PLYMask::PM_VERTFLAGS )
fwrite(&(vp->Flags()),sizeof(int),1,fpout);
if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
{
fprintf(fpout,
"property uchar red\n"
"property uchar green\n"
"property uchar blue\n"
"property uchar alpha\n"
);
}
if( HasPerVertexColor(m) && (pi.mask & ply::PLYMask::PM_VERTCOLOR) )
fwrite(&( vp->C() ),sizeof(char),4,fpout);
if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
{
const char* vqtp = vcg::tri::io::Precision<typename VertexType::ScalarType>::typeName();
fprintf(fpout,"property %s quality\n",vqtp);
}
if( m.HasPerVertexQuality() && (pi.mask & ply::PLYMask::PM_VERTQUALITY) )
fwrite(&( vp->Q() ),sizeof(float),1,fpout);
for(i=0;i<pi.vdn;i++)
fprintf(fpout,"property %s %s\n",pi.VertexData[i].stotypename(),pi.VertexData[i].propname);
// TETRA
fprintf(fpout,
"element tetra %d\n"
"property list uchar int vertex_indices\n"
,m.tn
);
if( pi.mask & Mask::IOM_TETRAFLAGS)
{
fprintf(fpout,
"property int flags\n"
);
}
if( (pi.mask & Mask::IOM_TETRACOLOR) )
{
fprintf(fpout,
"property uchar red\n"
"property uchar green\n"
"property uchar blue\n"
"property uchar alpha\n"
);
}
if( (pi.mask & Mask::IOM_TETRAQUALITY) )
{
const char* vqtp = vcg::tri::io::Precision<typename TetraType::ScalarType>::typeName();
fprintf(fpout,"property %s quality\n",vqtp);
}
for(i=0;i<pi.fdn;i++)
fprintf(fpout,"property %s %s\n",pi.TetraData[i].stotypename(),pi.TetraData[i].propname);
fprintf(fpout, "end_header\n" );
// Salvataggio camera
//if( (pi.mask & ply::PLYMask::PM_CAMERA) && camera.IsValid() )
//{
//if(binary)
//{
// float t[17];
// t[ 0] = camera.view_p[0];
// t[ 1] = camera.view_p[1];
// t[ 2] = camera.view_p[2];
// t[ 3] = camera.x_axis[0];
// t[ 4] = camera.x_axis[1];
// t[ 5] = camera.x_axis[2];
// t[ 6] = camera.y_axis[0];
// t[ 7] = camera.y_axis[1];
// t[ 8] = camera.y_axis[2];
// t[ 9] = camera.z_axis[0];
// t[10] = camera.z_axis[1];
// t[11] = camera.z_axis[2];
// t[12] = camera.f;
// t[13] = camera.s[0];
// t[14] = camera.s[1];
// t[15] = camera.c[0];
// t[16] = camera.c[1];
// fwrite(t,sizeof(float),17,fpout);
// fwrite( camera.viewport,sizeof(int),2,fpout );
// t[ 0] = camera.k[0];
// t[ 1] = camera.k[1];
// t[ 2] = camera.k[2];
// t[ 3] = camera.k[3];
// fwrite(t,sizeof(float),4,fpout);
//}
//else
//{
// fprintf(fpout,"%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d %d %g %g %g %g\n"
// ,camera.view_p[0]
// ,camera.view_p[1]
// ,camera.view_p[2]
// ,camera.x_axis[0]
// ,camera.x_axis[1]
// ,camera.x_axis[2]
// ,camera.y_axis[0]
// ,camera.y_axis[1]
// ,camera.y_axis[2]
// ,camera.z_axis[0]
// ,camera.z_axis[1]
// ,camera.z_axis[2]
// ,camera.f
// ,camera.s[0]
// ,camera.s[1]
// ,camera.c[0]
// ,camera.c[1]
// ,camera.viewport[0]
// ,camera.viewport[1]
// ,camera.k[0]
// ,camera.k[1]
// ,camera.k[2]
// ,camera.k[3]
// );
//}
//}
for(i=0;i<pi.vdn;i++)
{
double td; float tf;int ti;short ts; char tc; unsigned char tuc;
switch (pi.VertexData[i].stotype1)
{
case ply::T_FLOAT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
case ply::T_DOUBLE : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
case ply::T_INT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
case ply::T_SHORT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
case ply::T_CHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
case ply::T_UCHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
default : assert(0);
}
}
}
else // ***** ASCII *****
{
fprintf(fpout,"%g %g %g " ,vp->P()[0],vp->P()[1],vp->P()[2]);
SimpleTempData<typename SaveMeshType::VertContainer,int> indices(m.vert);
if( pi.mask & ply::PLYMask::PM_VERTFLAGS )
fprintf(fpout,"%d ",vp->Flags());
int j;
std::vector<int> FlagV;
VertexPointer vp;
VertexIterator vi;
for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi)
{
vp=&(*vi);
indices[vi] = j;
FlagV.push_back(vp->Flags()); // Salva in ogni caso flag del vertice
if( ! vp->IsD() )
{
if(binary)
{
float t;
if( HasPerVertexColor(m) && (pi.mask & ply::PLYMask::PM_VERTCOLOR) )
fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] );
t = float(vp->P()[0]); fwrite(&t,sizeof(float),1,fpout);
t = float(vp->P()[1]); fwrite(&t,sizeof(float),1,fpout);
t = float(vp->P()[2]); fwrite(&t,sizeof(float),1,fpout);
if( m.HasPerVertexQuality() && (pi.mask & ply::PLYMask::PM_VERTQUALITY) )
fprintf(fpout,"%g ",vp->Q());
if( pi.mask & Mask::IOM_VERTFLAGS )
fwrite(&(vp->Flags()),sizeof(int),1,fpout);
for(i=0;i<pi.vdn;i++)
{
float tf; double td;
int ti;
switch (pi.VertexData[i].memtype1)
{
case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
default : assert(0);
}
}
if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
fwrite(&( vp->C() ),sizeof(char),4,fpout);
fprintf(fpout,"\n");
}
vp->Flags()=j; // Trucco! Nascondi nei flags l'indice del vertice non deletato!
j++;
}
}
assert(j==m.vn);
char c = 4;
unsigned char b9 = 9;
unsigned char b6 = 6;
TetraPointer fp;
int vv[4];
TetraIterator fi;
int fcnt=0;
for(j=0,fi=m.tetra.begin();fi!=m.tetra.end();++fi)
{
fp=&(*fi);
if( ! fp->IsD() )
{ fcnt++;
if(binary)
{
vv[0]=fp->cV(0)->Flags();
vv[1]=fp->cV(1)->Flags();
vv[2]=fp->cV(2)->Flags();
vv[3]=fp->cV(2)->Flags();
fwrite(&c,1,1,fpout);
fwrite(vv,sizeof(int),4,fpout);
if( pi.mask & ply::PLYMask::PM_TETRAFLAGS )
fwrite(&(fp->Flags()),sizeof(int),1,fpout);
if( m.HasPerVertexTexture() && (pi.mask & ply::PLYMask::PM_VERTTEXCOORD) )
{
fwrite(&b6,sizeof(char),1,fpout);
float t[6];
for(int k=0;k<4;++k)
{
t[k*2+0] = fp->V(k)->T().u();
t[k*2+1] = fp->V(k)->T().v();
}
fwrite(t,sizeof(float),6,fpout);
}
//else if( m.HasPerWedgeTexture() && (pi.mask & ply::PLYMask::PM_WEDGTEXCOORD) )
//{
// fwrite(&b6,sizeof(char),1,fpout);
// float t[6];
// for(int k=0;k<3;++k)
// {
// t[k*2+0] = fp->WT(k).u();
// t[k*2+1] = fp->WT(k).v();
// }
// fwrite(t,sizeof(float),6,fpout);
//}
/* if(multit)
{
int t = fp->WT(0).n();
fwrite(&t,sizeof(int),1,fpout);
}
if( m.HasPerTetraColor() && (pi.mask & ply::PLYMask::PM_TETRACOLOR) )
fwrite(&( fp->C() ),sizeof(char),4,fpout);*/
if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
fwrite(&( vp->Q() ),DGTVQ,1,fpout);
//if( m.HasPerWedgeColor() && (pi.mask & ply::PLYMask::PM_WEDGCOLOR) )
//{
// fwrite(&b9,sizeof(char),1,fpout);
// float t[3];
// for(int z=0;z<3;++z)
// {
// t[0] = float(fp->WC(z)[0])/255;
// t[1] = float(fp->WC(z)[1])/255;
// t[2] = float(fp->WC(z)[2])/255;
// fwrite( t,sizeof(float),3,fpout);
// }
//}
for(i=0;i<pi.vdn;i++)
{
double td; float tf;int ti;short ts; char tc; unsigned char tuc;
switch (pi.VertexData[i].stotype1)
{
case ply::T_FLOAT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
case ply::T_DOUBLE : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
case ply::T_INT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
case ply::T_SHORT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
case ply::T_CHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
case ply::T_UCHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
default : assert(0);
}
}
}
else // ***** ASCII *****
{
fprintf(fpout,"%g %g %g " ,vp->P()[0],vp->P()[1],vp->P()[2]);
if( TetraType::HasTetraQuality() && (pi.mask & ply::PLYMask::PM_TETRAQUALITY) )
fwrite( &(fp->Q()),sizeof(float),1,fpout);
if( pi.mask & Mask::IOM_VERTFLAGS )
fprintf(fpout,"%d ",vp->Flags());
if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] );
if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
fprintf(fpout,"%g ",vp->Q());
for(i=0;i<pi.vdn;i++)
{
float tf; double td;
int ti;
switch (pi.VertexData[i].memtype1)
{
case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
default : assert(0);
}
}
fprintf(fpout,"\n");
}
vp->Flags()=j; // Trucco! Nascondi nei flags l'indice del vertice non deletato!
j++;
}
}
assert(j==m.vn);
char c = 4;
unsigned char b9 = 9;
unsigned char b6 = 6;
TetraPointer fp;
int vv[4];
TetraIterator fi;
int fcnt=0;
for(j=0,fi=m.tetra.begin();fi!=m.tetra.end();++fi)
{
fp=&(*fi);
if( ! fp->IsD() )
{ fcnt++;
if(binary)
{
vv[0]=indices[fp->cV(0)];
vv[1]=indices[fp->cV(1)];
vv[2]=indices[fp->cV(2)];
vv[3]=indices[fp->cV(3)];
fwrite(&c,1,1,fpout);
fwrite(vv,sizeof(int),4,fpout);
if( pi.mask & Mask::IOM_TETRAFLAGS )
fwrite(&(fp->Flags()),sizeof(int),1,fpout);
if( (pi.mask & Mask::IOM_TETRACOLOR) )
fwrite(&( fp->C() ), sizeof(char),4,fpout);
if( (pi.mask & Mask::IOM_TETRAQUALITY) )
fwrite( &(fp->Q()), DGTTQ,1,fpout);
for(i=0;i<pi.fdn;i++)
{
double td; float tf;int ti;short ts; char tc; unsigned char tuc;
switch (pi.TetraData[i].stotype1){
case ply::T_FLOAT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
case ply::T_DOUBLE : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
case ply::T_INT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
case ply::T_SHORT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
case ply::T_CHAR : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
case ply::T_UCHAR : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
default : assert(0);
}
}
}
else // ***** ASCII *****
{
fprintf(fpout,"3 %d %d %d ",
fp->cV(0)->Flags(), fp->cV(1)->Flags(), fp->cV(2)->Flags() );
for(i=0;i<pi.fdn;i++)
{
double td; float tf;int ti;short ts; char tc; unsigned char tuc;
switch (pi.TetraData[i].stotype1){
case ply::T_FLOAT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
case ply::T_DOUBLE : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
case ply::T_INT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
case ply::T_SHORT : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
case ply::T_CHAR : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
case ply::T_UCHAR : PlyConv(pi.TetraData[i].memtype1, ((char *)fp)+pi.TetraData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
default : assert(0);
}
}
}
else // ***** ASCII *****
{
fprintf(fpout,"%d %d %d %d ",
indices[fp->cV(0)], indices[fp->cV(1)], indices[fp->cV(2)], indices[fp->cV(3)]);
if( pi.mask & ply::PLYMask::PM_TETRAFLAGS )
fprintf(fpout,"%d ",fp->Flags());
if( pi.mask & Mask::IOM_TETRAFLAGS )
fprintf(fpout,"%d ",fp->Flags());
if( m.HasPerVertexTexture() && (pi.mask & ply::PLYMask::PM_VERTTEXCOORD) )
{
fprintf(fpout,"6 ");
for(int k=0;k<4;++k)
fprintf(fpout,"%g %g "
,fp->V(k)->T().u()
,fp->V(k)->T().v()
);
}
//else if( m.HasPerWedgeTexture() && (pi.mask & ply::PLYMask::PM_WEDGTEXCOORD) )
//{
// fprintf(fpout,"6 ");
// for(int k=0;k<3;++k)
// fprintf(fpout,"%g %g "
// ,fp->WT(k).u()
// ,fp->WT(k).v()
// );
//}
if( TetraType::HasColor() && (pi.mask & Mask::IOM_TETRACOLOR) )
fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] );
/* if(multit)
{
fprintf(fpout,"%d ",fp->WT(0).n());
}*/
if( TetraType::HasTetraColor() && (pi.mask & ply::PLYMask::PM_TETRACOLOR) )
{
float t[3];
t[0] = float(fp->C()[0])/255;
t[1] = float(fp->C()[1])/255;
t[2] = float(fp->C()[2])/255;
fprintf(fpout,"9 ");
fprintf(fpout,"%g %g %g ",t[0],t[1],t[2]);
fprintf(fpout,"%g %g %g ",t[0],t[1],t[2]);
fprintf(fpout,"%g %g %g ",t[0],t[1],t[2]);
}
//else if( m.HasPerWedgeColor() && (pi.mask & ply::PLYMask::PM_WEDGCOLOR) )
//{
// fprintf(fpout,"9 ");
// for(int z=0;z<3;++z)
// fprintf(fpout,"%g %g %g "
// ,double(fp->WC(z)[0])/255
// ,double(fp->WC(z)[1])/255
// ,double(fp->WC(z)[2])/255
// );
//}
if((pi.mask & Mask::IOM_TETRAQUALITY) )
fprintf(fpout,"%g ",fp->Q());
if( m.HasPerTetraQuality() && (pi.mask & ply::PLYMask::PM_TETRAQUALITY) )
fprintf(fpout,"%g ",fp->Q());
for(i=0;i<pi.fdn;i++)
{
float tf; double td;
int ti;
switch (pi.TetraData[i].memtype1)
{
case ply::T_FLOAT : tf=*( (float *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_DOUBLE : td=*( (double *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_INT : ti=*( (int *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_SHORT : ti=*( (short *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_CHAR : ti=*( (char *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
default : assert(0);
}
}
for(i=0;i<pi.fdn;i++)
{
float tf; double td;
int ti;
switch (pi.TetraData[i].memtype1)
{
case ply::T_FLOAT : tf=*( (float *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_DOUBLE : td=*( (double *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%g ",tf); break;
case ply::T_INT : ti=*( (int *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_SHORT : ti=*( (short *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_CHAR : ti=*( (char *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)fp)+pi.TetraData[i].offset1)); fprintf(fpout,"%i ",ti); break;
default : assert(0);
}
}
fprintf(fpout,"\n");
}
}
}
assert(fcnt==m.tn);
fclose(fpout);
fprintf(fpout,"\n");
}
}
}
assert(fcnt==m.tn);
fclose(fpout);
// Recupera i flag originali
for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi)
(*vi).Flags()=FlagV[j++];
return 0;
}
// Recupera i flag originali
for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi)
(*vi).Flags()=FlagV[j++];
return 0;
}
@ -575,7 +482,7 @@ static bool Save(SaveMeshType &m, const char * filename, bool binary, PlyInfo &
} // end namespace tri
} // end namespace tetra
} // end namespace io
} // end namespace vcg

View File

@ -33,11 +33,8 @@ created
#include<wrap/callback.h>
#include<wrap/ply/plylib.h>
#include<wrap/ply/io_mask.h>
#include<wrap/io_tetramesh/io_mask.h>
#include<wrap/io_tetramesh/io_ply.h>
#include<vcg/complex/tetramesh/allocate.h>
namespace vcg {
namespace tetra {
@ -219,7 +216,7 @@ static const PropDescriptor &TetraDesc(int i)
/// Standard call for reading a mesh
static int Open( OpenMeshType &m, const char * filename, CallBackPos *cb=0)
{
PlyInfo pi;
PlyInfo pi;
pi.cb=cb;
return Open(m, filename, pi);
}
@ -235,7 +232,7 @@ static int Open( OpenMeshType &m, const char * filename, int & loadmask, CallBac
/// read a mesh with all the possible option specified in the PlyInfo obj.
static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
static int Open( OpenMeshType &m, const char * filename, PlyInfo & pi )
{
assert(filename!=0);
vector<VertexPointer> index;

View File

@ -0,0 +1,80 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#ifndef __VCGLIB_IOTETRAMESH_IO_MASK
#define __VCGLIB_IOTETRAMESH_IO_MASK
namespace vcg {
namespace tetra {
namespace io {
/**
@name Input/output data mask
*/
//@{
class Mask
{
public:
/*
Bitmask for specifying what data has to be loaded or saved or it is present in a given plyfile;
*/
enum {
IOM_NONE = 0x00000,
IOM_VERTCOORD = 0x00001,
IOM_VERTFLAGS = 0x00002,
IOM_VERTCOLOR = 0x00004,
IOM_VERTQUALITY = 0x00008,
IOM_VERTRADIUS = 0x10000,
IOM_EDGEINDEX = 0x80000,
IOM_TETRAINDEX = 0x00010,
IOM_TETRAFLAGS = 0x00020,
IOM_TETRACOLOR = 0x00040,
IOM_TETRAQUALITY = 0x00080,
IOM_CAMERA = 0x08000,
IOM_FLAGS = IOM_VERTFLAGS + IOM_TETRAFLAGS,
IOM_ALL = 0xFFFFF
};
template <class MeshType>
static void ClampMask(MeshType &m, int &mask)
{
if( (mask & IOM_TETRACOLOR) && !HasPerTetraColor(m) ) mask = mask & (~IOM_TETRACOLOR);
if( (mask & IOM_VERTCOLOR) && !HasPerVertexColor(m) ) mask = mask & (~IOM_VERTCOLOR);
}
}; // end class
//@}
} // end namespace tetra
} // end namespace io
} // end namespace vcg
#endif

View File

@ -37,8 +37,8 @@ Revision 1.1 2004/03/03 15:00:51 cignoni
Initial commit
****************************************************************************/
#ifndef __VCGLIB_IOTRIMESH_IO_PLY
#define __VCGLIB_IOTRIMESH_IO_PLY
#ifndef __VCGLIB_IOTETRAMESH_IO_PLY
#define __VCGLIB_IOTETRAMESH_IO_PLY
/**