stable allocate and tetra complex
This commit is contained in:
parent
13d79bc428
commit
b0384f68d1
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
@ -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();}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>{};
|
||||
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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] ;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue