From 638dfc64fb9f0f23166f2f796455a39a918b14f3 Mon Sep 17 00:00:00 2001 From: nicopietroni Date: Wed, 1 Sep 2004 13:16:34 +0000 Subject: [PATCH] files moved to tetra_mesh path --- vcg/complex/tetramesh/modify/edge_collapse.h | 901 ------------------- vcg/complex/tetramesh/modify/edge_split.h | 478 ---------- 2 files changed, 1379 deletions(-) delete mode 100644 vcg/complex/tetramesh/modify/edge_collapse.h delete mode 100644 vcg/complex/tetramesh/modify/edge_split.h diff --git a/vcg/complex/tetramesh/modify/edge_collapse.h b/vcg/complex/tetramesh/modify/edge_collapse.h deleted file mode 100644 index 0eb88002..00000000 --- a/vcg/complex/tetramesh/modify/edge_collapse.h +++ /dev/null @@ -1,901 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* 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. * -* * -****************************************************************************/ -/**************************************************************************** - History -****************************************************************************/ - -#ifndef __VCG_TETRA_EDGE_COLLAPSE -#define __VCG_TETRA_EDGE_COLLAPSE - -#include -#include -#include - -namespace vcg{ -namespace tetra{ - -/** \addtogroup tetramesh */ -/*@{*/ -/// This Class is used for the edge collapse -template -class EdgeCollapse -{ - public: - /// The tetrahedral mesh type - typedef typename TETRA_MESH_TYPE TetraMeshType; - /// The tetrahedron type - typedef typename TetraMeshType::TetraType TetraType; - /// The vertex type - typedef typename TetraType::VertexType VertexType; - /// The vertex iterator type - typedef typename TetraMeshType::VertexIterator VertexIterator; - /// The tetra iterator type - typedef typename TetraMeshType::TetraIterator TetraIterator; - /// The coordinate type - typedef typename TetraType::VertexType::CoordType CoordType; - /// The scalar type - typedef typename TetraMeshType::VertexType::ScalarType ScalarType; - ///the container of tetrahedron type - typedef typename TetraMeshType::TetraContainer TetraContainer; - ///the container of vertex type - typedef typename TetraMeshType::VertexContainer VertexContainer; - /// The HEdgePos type - typedef Pos PosType; - /// The HEdgePos Loop type - typedef PosLoop PosLType; - /// The topology updater type - typedef vcg::tetra::UpdateTetraTopology Topology; - ///the normal updater type - typedef vcg::tetra::UpdateNormals UpdateNormals; - - - /// Default Constructor - EdgeCollapse() - { - }; - - ~EdgeCollapse() - { - }; - - private: - typedef pair FacePair; - struct Face - { - VertexType* v[3]; - - Face( VertexType* a, VertexType* b,VertexType* c) - { - assert((a!=b)&&(b!=c)&&(a!=c)); - v[0]=a; - v[1]=b; - v[2]=c; - sort(v,v+3); - } - - const bool operator <(const Face & f) const - { - return ((v[0]==f.v[0])?((v[1]==f.v[1])?(v[2] v0; - std::vector v1; - std::vector v0_U_v1; - std::vector no_E; - std::vector E; - std::vector indexE; - std::vector indexv0; - std::vector indexv1; - - void clear() - { - v0.clear(); - v1.clear(); - v0_U_v1.clear(); - no_E.clear(); - E.clear(); - } -}; - - - - - -static map & _EdgeMark(){ - static map em; - return em; -}; - -static map & _FaceMark(){ - static map fm; - return fm; -} - -static VertexType &_DummyV(){ - static VertexType _dv; - return _dv; -} - -static TetraSets &_Sets(){ - static TetraSets _s; - return _s; -} - - -///select the 2 faces that does not share the edge -static FacePair _FindNoEdgeFace(TetraType *t,int edge) -{ - //as first I find the 2 faces on the opposite sides of the egde - int fa0=Tetra::FofE(edge,0); - int fa1=Tetra::FofE(edge,1); - - //then find the faces that remain - int fa2=(fa0+1)%4; - while ((fa2==fa0)||(fa2==fa1)) - { - fa2=(fa2+1)%4; - } - int fa3=(fa2+1)%4; - while ((fa3==fa0)||(fa3==fa1)||(fa3==fa2)) - { - fa3=(fa3+1)%4; - } - return FacePair(fa2,fa3); -} - -#ifdef _DEBUG -static void _AssertingVolume(TetraType *t) -{ - assert(t->ComputeVolume() >0); -} -#endif - - -///collpse de edge specified by pos (the first vertex on edge remain) -static int _Collapse(PosType p,CoordType NewP) -{ - int n_deleted=0; - vector To_Del; - VertexType *Vrem=(p.T()->V(Tetra::VofE(p.E(),0))); - VertexType *Vdel=(p.T()->V(Tetra::VofE(p.E(),1))); - //Vrem->P()=(Vrem->P()*alfa)+(Vdel->P()*(1.f-alfa)); - Vrem->P()=NewP; - PosLType pos(p.T(),p.F(),p.E(),p.V()); - pos.Reset(); - To_Del.reserve(40); - To_Del.clear(); - while (!pos.LoopEnd()) - { - //get the two faces that doesn't share the edge - FacePair fp=_FindNoEdgeFace(pos.T(),pos.E()); - int fa0=fp.first; - int fa1=fp.second; - - //now set the T-T topology on that faces - TetraType *tleft=pos.T()->TTp(fa0); - TetraType *tright=pos.T()->TTp(fa1); - int ileft=pos.T()->TTi(fa0); - int iright=pos.T()->TTi(fa1); - - //in this case I cannot do the collapse - assert (!((pos.T()==tleft)&&(pos.T()==tright))); - - //case no one is extern face - if ((!pos.T()->IsBorderF(fa0))&&(!pos.T()->IsBorderF(fa1))) - //connect the 2 tetrahedrons - Topology::_AttachTTTopology(tleft,ileft,tright,iright); - else - //case f2 is an extern face - if (pos.T()->IsBorderF(fa0)) - { - tright->TTp(iright)=tright; - tright->TTi(iright)=iright; - } - - else //case fa1 is an extern face - //if ((pos.T()->IsBorderF(fa3)) - { - tleft->TTp(ileft)=tleft; - tleft->TTi(ileft)=ileft; - } - - //end setting T-T topology - - //setting the V-T topology - - //i remove the tetrahedrons that have the edge - // to collapse - Topology::DetachVTTopology(pos.T()); - //end setting the V-T topology - To_Del.push_back(pos.T()); - pos.NextT(); - - n_deleted++; -// tm.tn--; - } - - //delting old tetrahedrons - vector::iterator ti; - for (ti=To_Del.begin();tiSetD(); - - //now I cycle on the tetrahedron that had the old vertex - //reassegning the new one. - - VTIterator< TetraType> VTi(Vdel->VTb(),Vdel->VTi()); - while (!VTi.End()) - { - TetraType *T_Change=VTi.Vt(); - int index=VTi.Vi(); - //VTi++; - //assegning the vertex that remain - T_Change->V(index)=Vrem; - Topology::DetachVTTopology(Vdel,T_Change); - Topology::InsertVTTopology(Vrem,index,T_Change); - //that's cause i restart everytime in the chain - //from the vertex - VTi.Vt()=Vdel->VTb(); - VTi.Vi()=Vdel->VTi(); -#ifdef _DEBUG - _AssertingVolume(T_Change); -#endif - - } - if (Vdel->IsB()) - Vrem->SetB(); - //set as deleted the vertex - Vdel->SetD(); -// tm.vn--; - return n_deleted; -} - - -static void orMarkE(Edge E,char M) -{ - map::iterator EI; - EI=_EdgeMark().find(E); - if (EI==_EdgeMark().end()) - _EdgeMark().insert (pair(E,M)); - else - (*EI).second|=M; -} - -static bool isMarkedE(Edge E,char M) -{ - map::iterator EI; - EI=_EdgeMark().find(E); - if (EI==_EdgeMark().end()) - return false; - else return ((*EI).second & M); -} - -static void orMarkF(Face F,char M) -{ - map::iterator FI; - FI=_FaceMark().find(F); - if (FI==_FaceMark().end()) - _FaceMark().insert (pair(F,M)); - else - (*FI).second|=M; -} - -static bool isMarkedF(Face F,char M) -{ - map::iterator FI; - FI=_FaceMark().find(F); - if (FI==_FaceMark().end()) - return false; - else return ((*FI).second & M); -} - -///this structure is used to find the sets that are used in link conditions and more - -///verify the link conditions on faces -static bool _LinkConditionsF(PosType pos) -{ - const int LINK_V0 = 0x00000001; - const int LINK_EE = 0x00000002; - - _EdgeMark().clear(); - - // Mark edges of ve0 - vector< TetraType *>::iterator ti=_Sets().v0.begin(); - vector< char >::iterator en=_Sets().indexv0.begin(); - while (ti!=_Sets().v0.end()) - { - //put dummy face - for (int f=0;f<3;f++) - { - int f_test=Tetra::FofV((*en),f); - if ((*ti)->IsBorderF(f_test)) - { - orMarkF(Face((*ti)->V(Tetra::VofF(f_test,0)),(*ti)->V(Tetra::VofF(f_test,1)),&_DummyV()),LINK_V0); - orMarkF(Face((*ti)->V(Tetra::VofF(f_test,1)),(*ti)->V(Tetra::VofF(f_test,2)),&_DummyV()),LINK_V0); - orMarkF(Face((*ti)->V(Tetra::VofF(f_test,2)),(*ti)->V(Tetra::VofF(f_test,0)),&_DummyV()),LINK_V0); - } - } - ti++; - en++; - } - - ti=_Sets().E.begin(); - en=_Sets().indexE.begin(); - //mark them as intersection - while (ti!=_Sets().E.end()) - { - //faces on the edge - int f0=Tetra::FofE((*en),0); - int f1=Tetra::FofE((*en),1); - - if ((*ti)->IsBorderF(f0)) - { - orMarkF(Face((*ti)->V(Tetra::VofF(f0,0)),(*ti)->V(Tetra::VofF(f0,1)),&_DummyV()),LINK_EE); - orMarkF(Face((*ti)->V(Tetra::VofF(f0,1)),(*ti)->V(Tetra::VofF(f0,2)),&_DummyV()),LINK_EE); - orMarkF(Face((*ti)->V(Tetra::VofF(f0,2)),(*ti)->V(Tetra::VofF(f0,0)),&_DummyV()),LINK_EE); - } - - if ((*ti)->IsBorderF(f1)) - { - orMarkF(Face((*ti)->V(Tetra::VofF(f1,0)),(*ti)->V(Tetra::VofF(f1,1)),&_DummyV()),LINK_EE); - orMarkF(Face((*ti)->V(Tetra::VofF(f1,1)),(*ti)->V(Tetra::VofF(f1,2)),&_DummyV()),LINK_EE); - orMarkF(Face((*ti)->V(Tetra::VofF(f1,2)),(*ti)->V(Tetra::VofF(f1,0)),&_DummyV()),LINK_EE); - } - - ti++; - en++; - } - - //and at the end I verify if the intersection is equal to the star of the edge - ti=_Sets().v1.begin(); - en=_Sets().indexv1.begin(); - while (ti!=_Sets().v1.end()) - { - - //dummy edges control - for (int f=0;f<3;f++) - { - int f_test=Tetra::FofV((*en),f); - if ((*ti)->IsBorderF(f_test)) - { - //control all the 3 edges - Face f_test0=Face((*ti)->V(Tetra::VofF(f_test,0)),(*ti)->V(Tetra::VofF(f_test,1)),&_DummyV()); - Face f_test1=Face((*ti)->V(Tetra::VofF(f_test,1)),(*ti)->V(Tetra::VofF(f_test,2)),&_DummyV()); - Face f_test2=Face((*ti)->V(Tetra::VofF(f_test,2)),(*ti)->V(Tetra::VofF(f_test,0)),&_DummyV()); - if (((isMarkedF(f_test0,LINK_V0))&&(!isMarkedF(f_test0,LINK_EE)))|| - ((isMarkedF(f_test1,LINK_V0))&&(!isMarkedF(f_test1,LINK_EE)))|| - ((isMarkedF(f_test2,LINK_V0))&&(!isMarkedF(f_test2,LINK_EE)))) - return false; - } - } - ti++; - en++; - } - return true; -} - -///verify the link conditions on edges -static bool _LinkConditionsE(PosType pos) -{ - const int LINK_V0 = 0x00000001; - const int LINK_EE = 0x00000002; - - _FaceMark().clear(); - - // Mark edges of ve0 - vector< TetraType *>::iterator ti=_Sets().v0.begin(); - vector< char >::iterator en=_Sets().indexv0.begin(); - while (ti!=_Sets().v0.end()) - { - //put dummy edge - for (int f=0;f<3;f++) - { - int f_test=Tetra::FofV((*en),f); - if ((*ti)->IsBorderF(f_test)) - { - orMarkE(Edge((*ti)->V(Tetra::VofF(f_test,0)),&_DummyV()),LINK_V0); - orMarkE(Edge((*ti)->V(Tetra::VofF(f_test,1)),&_DummyV()),LINK_V0); - orMarkE(Edge((*ti)->V(Tetra::VofF(f_test,2)),&_DummyV()),LINK_V0); - } - } - ti++; - en++; - } - - ti=_Sets().E.begin(); - en=_Sets().indexE.begin(); - //mark them as intersection - while (ti!=_Sets().E.end()) - { - //faces on the edge - int f0=Tetra::FofE((*en),0); - int f1=Tetra::FofE((*en),1); - - if ((*ti)->IsBorderF(f0)) - { - orMarkE(Edge((*ti)->V(Tetra::VofF(f0,0)),&_DummyV()),LINK_EE); - orMarkE(Edge((*ti)->V(Tetra::VofF(f0,1)),&_DummyV()),LINK_EE); - orMarkE(Edge((*ti)->V(Tetra::VofF(f0,2)),&_DummyV()),LINK_EE); - } - - if ((*ti)->IsBorderF(f1)) - { - orMarkE(Edge((*ti)->V(Tetra::VofF(f1,0)),&_DummyV()),LINK_EE); - orMarkE(Edge((*ti)->V(Tetra::VofF(f1,1)),&_DummyV()),LINK_EE); - orMarkE(Edge((*ti)->V(Tetra::VofF(f1,2)),&_DummyV()),LINK_EE); - } - - ti++; - en++; - } - - //and at the end I verify if the intersection is equal to the star of the edge - ti=_Sets().v1.begin(); - en=_Sets().indexv1.begin(); - while (ti!=_Sets().v1.end()) - { - - //dummy edges control - for (int f=0;f<3;f++) - { - int f_test=Tetra::FofV((*en),f); - if ((*ti)->IsBorderF(f_test)) - { - //control all the 3 edges - Edge e_test0=Edge((*ti)->V(Tetra::VofF(f_test,0)),&_DummyV()); - Edge e_test1=Edge((*ti)->V(Tetra::VofF(f_test,1)),&_DummyV()); - Edge e_test2=Edge((*ti)->V(Tetra::VofF(f_test,2)),&_DummyV()); - if (((isMarkedE(e_test0,LINK_V0))&&(!isMarkedE(e_test0,LINK_EE)))|| - ((isMarkedE(e_test1,LINK_V0))&&(!isMarkedE(e_test1,LINK_EE)))|| - ((isMarkedE(e_test2,LINK_V0))&&(!isMarkedE(e_test2,LINK_EE)))) - return false; - } - } - ti++; - en++; - } - return true; -} - - -///verify the link conditions on vertices -static bool _LinkConditionsV() -{ - const int LINK_V0 = VertexType::NewUserBit(); - const int LINK_V1 = VertexType::NewUserBit(); - const int LINK_EE = VertexType::NewUserBit(); - - const int NOT_LINKED = ~(LINK_V0 | LINK_V1 | LINK_EE); - _DummyV().Flags() &= NOT_LINKED; - - VertexType *vt0; - VertexType *vt1; - VertexType *vt2; - VertexType *vt3; - - - vector< TetraType *>::iterator ti=_Sets().v0_U_v1.begin(); - - //reset all link flags - while (ti!=_Sets().v0_U_v1.end()) - { - for(int i=0;i<4;i++) - (*ti)->V(i)->Flags() &= NOT_LINKED; - ti++; - } - - - //also in the ones that appartain to the edge - vector< char >::iterator en; - ti=_Sets().E.begin(); - en=_Sets().indexE.begin(); - //reset all link flags for intersection and in the same - //time mark them as intersection - while (ti!=_Sets().E.end()) - { - for(int i=0;i<4;i++) - { - (*ti)->V(i)->Flags() &= NOT_LINKED; - (*ti)->V(i)->Flags() |= LINK_EE; - } - - //dummy vertex - - //faces on the edge - int f0=Tetra::FofE((*en),0); - int f1=Tetra::FofE((*en),1); - - if (((*ti)->IsBorderF(f0))||((*ti)->IsBorderF(f1))) - _DummyV().Flags() |= LINK_EE; - - ti++; - en++; - } - - - // Mark vertices of ve0 - ti=_Sets().v0.begin(); - en=_Sets().indexv0.begin(); - - while (ti!=_Sets().v0.end()) - { - for(int i=0;i<4;i++) - (*ti)->V(i)->Flags() |= LINK_V0; - - //dummy faces on the vertex - int f0=Tetra::FofV((*en),0); - int f1=Tetra::FofV((*en),1); - int f2=Tetra::FofV((*en),2); - - if (((*ti)->IsBorderF(f0))||((*ti)->IsBorderF(f1))||((*ti)->IsBorderF(f2))) - _DummyV().Flags() |= LINK_V0; - - ti++; - en++; - } - - //and at the end I verify if the intersection is equal to the star of the edge - bool correct=true; - ti=_Sets().v1.begin(); - en=_Sets().indexv1.begin(); - - while (ti!=_Sets().v1.end()) - { - vt0=(*ti)->V(0); - vt1=(*ti)->V(1); - vt2=(*ti)->V(2); - vt3=(*ti)->V(3); - - if ((vt0->Flags()& LINK_V0)&&(!(vt0->Flags()& LINK_EE))) - correct=false; - else - if ((vt1->Flags()& LINK_V0)&&(!(vt1->Flags()& LINK_EE))) - correct=false; - else - if ((vt2->Flags()& LINK_V0)&&(!(vt2->Flags()& LINK_EE))) - correct=false; - else - if ((vt3->Flags()& LINK_V0)&&(!(vt3->Flags()& LINK_EE))) - correct=false; - - //dummy vertex control - int f0=Tetra::FofV((*en),0); - int f1=Tetra::FofV((*en),1); - int f2=Tetra::FofV((*en),2); - - if (((*ti)->IsBorderF(f0))||((*ti)->IsBorderF(f1))||((*ti)->IsBorderF(f2))) - if ((_DummyV().Flags()& LINK_V0)&&(!(_DummyV().Flags()& LINK_EE))) - correct=false; - - if (!correct) - { - VertexType::DeleteUserBit(LINK_EE); - VertexType::DeleteUserBit(LINK_V1); - VertexType::DeleteUserBit(LINK_V0); - return (false); - } - en++; - ti++; - } - VertexType::DeleteUserBit(LINK_EE); - VertexType::DeleteUserBit(LINK_V1); - VertexType::DeleteUserBit(LINK_V0); - return true; -} - -///verify the flip condition -static bool _FlipCondition(PosType pos,CoordType NewP) -{ - int edge=pos.E(); - VertexType *ve0=pos.T()->V(Tetra::VofE(edge,0)); - VertexType *ve1=pos.T()->V(Tetra::VofE(edge,1)); - CoordType oldpos0; - CoordType oldpos1; - //CoordType newpos=((ve0->P()*alfa)+(ve1->P()*(1.f-alfa))); - - vector< TetraType *>::iterator ti=_Sets().no_E.begin(); - - //verification - oldpos0 = ve0->P(); - oldpos1 = ve1->P(); - - //assegning new position - ve0->P() =NewP; - ve1->P() =NewP; - - while (ti!=_Sets().no_E.end()) - { - assert(!(*ti)->IsD()); - assert((((*ti)->V(0)==ve0)||((*ti)->V(1)==ve0)||((*ti)->V(2)==ve0)||((*ti)->V(3)==ve0))^ - (((*ti)->V(0)==ve1)||((*ti)->V(1)==ve1)||((*ti)->V(2)==ve1)||((*ti)->V(3)==ve1))); - - /* Tetra3 T=Tetra3(); - T.P0(0)=(*ti)->V(0)->cP(); - T.P1(0)=(*ti)->V(1)->cP(); - T.P2(0)=(*ti)->V(2)->cP(); - T.P3(0)=(*ti)->V(3)->cP();*/ - //flip comes if volume is less or equal to zero - ScalarType tv = vcg::ComputeVolume(**ti); - if (vcg::ComputeVolume(**ti)<=0) - { - ve0->P()=oldpos0; - ve1->P()=oldpos1; - return false; - } - ti++; - } - - //reset initial value - ve0->P()=oldpos0; - ve1->P()=oldpos1; - - return true; -} - -///update the normal of the modified tetrahedrons ond the normal of the vertex that remain after collapse -static void _InitTetrahedronValues(VertexType* v) -{ - - VTIterator VTi=VTIterator(v->VTb(),v->VTi()); - while (!VTi.End()) - { - if (TetraType::HasTetraQuality()) - { - VTi.Vt()->ComputeAspectRatio(); - } - - if (TetraType::HasTetraNormal()) - { - VTi.Vt()->ComputeNormal(); - } - - VTi++; - } - - VTi.Vt()=v->VTb(); - VTi.Vi()=v->VTi(); - while (!VTi.End()) - { - for (int i=0;i<4;i++) - { - if (VTi.Vt()->V(i)->IsB()) - { - if (VertexType::HasNormal) - UpdateNormals::PerVertex(VTi.Vt()->V(i)); - } - - } - ++VTi; - } - -} - -public: - - -///Return the aspect Ratio media of the tetrahedrons -///that share the adge to collapse -static ScalarType AspectRatioCollapsed(PosType p) -{ - PosL pos=PosL(p.T(),p.F(),p.E(),p.V()); - pos.Reset(); - int num=0; - ScalarType ratio_media=0.f; - while(!pos.end()) - { - ratio_media+=pos.T()->AspectRatio(); - pos.NextT(); - num++; - } - ratio_media=ratio_media/num; - return (ratio_media); -} - - -///check the topologycal preserving conditions for the collapse indicated by pos -static bool CheckPreconditions(PosType pos,CoordType NewP) -{ - VertexType *v0=pos.T()->V(Tetra::VofE(pos.E(),0)); - VertexType *v1=pos.T()->V(Tetra::VofE(pos.E(),1)); - //if the two vertices are of border and the edge is not a border edge - //we can do it. - bool border0=v0->IsB(); - bool border1=v1->IsB(); - bool bordere=Topology::IsExternEdge(pos.T(),pos.E()); - - //first case vertex external and edge internal - if ((border0 && border1)&&(!bordere)) - return false; - else - //if both vertex are internal so is enougth to verify flip conditions - if ((!border0) && (!border1)) - return (_FlipCondition(pos,NewP)); - else - //if the edge is internal is enougth to verify link condition on vertex - if (!bordere) - return((_FlipCondition(pos,NewP))&&(_LinkConditionsV())); - else - //at the end if trh edge is on the border we must verify also with the complete test - return ((_FlipCondition(pos,NewP))&&(_LinkConditionsV())&&(_LinkConditionsE(pos))&&(_LinkConditionsF(pos))); - //return false; -} - -///return the sum of volumes of the union of stars on vertices (the original volume of tetrahedrons) -static ScalarType VolumeOriginal() -{ - vector< TetraType *>::iterator ti=_Sets().v0_U_v1.begin(); - ScalarType vol=0; - while (ti!=_Sets().v0_U_v1.end()) - { - vol+=(*ti)->Volume(); - ti++; - } - return vol; -} - -///Calculate the volume on the vertex resulting after collapse... -static ScalarType VolumeSimulateCollapse(PosType Pos,CoordType newP) -{ - VertexType *Vrem=(Pos.T()->V(Tetra::VofE(Pos.E(),0))); - VertexType *Vdel=(Pos.T()->V(Tetra::VofE(Pos.E(),1))); - - if (Vrem!=Pos.T()->V(Pos.V())) - swap(Vdel,Vrem); - - ScalarType vol=0; - CoordType oldpos = Vrem->P(); - -//move vertex that remain in the new position - Vrem->P() = newP; - - vector< TetraType *>::iterator ti=_Sets().no_E.begin(); - - while (ti!=_Sets().no_E.end()) - { - /* Tetra3 T=Tetra3(); - T.P0(0)=(*ti)->V(0)->cP(); - T.P1(0)=(*ti)->V(1)->cP(); - T.P2(0)=(*ti)->V(2)->cP(); - T.P3(0)=(*ti)->V(3)->cP(); - - vol+=T.ComputeVolume(); */ -// vol+= vcg::ComputeVolume(*((Tetra3*)&*ti)); - - vol+= vcg::ComputeVolume(**ti); - ti++; - } - Vrem->P()=oldpos; - return vol; -} - -///finds sets used for all test in edge collapse -static void FindSets(vcg::tetra::Pos pos) -{ - - _Sets().clear(); - int size=40; - _Sets().v0.reserve(size); - _Sets().indexv0.reserve(size); - _Sets().v1.reserve(size); - _Sets().indexv1.reserve(size); - _Sets().v0_U_v1.reserve(size*2); - _Sets().no_E.reserve(size*2); - _Sets().E.reserve(size); - _Sets().indexE.reserve(size); - - int edge =pos.E(); - - VertexType *ve0=pos.T()->V(Tetra::VofE(edge,0)); - VertexType *ve1=pos.T()->V(Tetra::VofE(edge,1)); - - // put all tetrahedrons in the first one vector and in the union - VTIterator vf0(ve0->VTb(),ve0->VTi()); - while (!vf0.End()) - { - //set of ve0 - _Sets().v0.push_back(vf0.Vt()); - _Sets().indexv0.push_back(vf0.Vi()); - //set of union - _Sets().v0_U_v1.push_back(vf0.Vt()); - //set of union minus intersection - if ((vf0.Vt()->V(0)!=ve1)&&(vf0.Vt()->V(1)!=ve1)&&(vf0.Vt()->V(2)!=ve1)&&(vf0.Vt()->V(3)!=ve1)) - _Sets().no_E.push_back(vf0.Vt()); - vf0++; - } - - //second vertex iteration - vf0.Vt()=ve1->VTb(); - vf0.Vi()=ve1->VTi(); - - while (!vf0.End()) - { - //set of ve1 - _Sets().v1.push_back(vf0.Vt()); - _Sets().indexv1.push_back(vf0.Vi()); - //set of union - _Sets().v0_U_v1.push_back(vf0.Vt()); - //set of union minus intersection - if ((vf0.Vt()->V(0)!=ve0)&&(vf0.Vt()->V(1)!=ve0)&&(vf0.Vt()->V(2)!=ve0)&&(vf0.Vt()->V(3)!=ve0)) - _Sets().no_E.push_back(vf0.Vt()); - vf0++; - } - - //erase duplicated tetrahedrons from the union set - sort(_Sets().v0_U_v1.begin(),_Sets().v0_U_v1.end()); - unique(_Sets().v0_U_v1.begin(),_Sets().v0_U_v1.end()); - - //now compute the intersection - PosLType PL(pos.T(),pos.F(),pos.E(),pos.V()); - - //mark the vertex on the edge - while (!PL.LoopEnd()) - { - _Sets().E.push_back(PL.T()); - _Sets().indexE.push_back(PL.E()); - PL.NextT(); - } - -} - -///do the collapse on the edge in postype p -static int DoCollapse(PosType p,CoordType newP) -{ - VertexType *v=p.T()->V(p.V()); - assert(p.T()->HasVTAdjacency()); - int n_deleted = _Collapse(p,newP); - _InitTetrahedronValues(v); - return n_deleted; -} - - -}; -}//end namespace -}//end namespace -#endif \ No newline at end of file diff --git a/vcg/complex/tetramesh/modify/edge_split.h b/vcg/complex/tetramesh/modify/edge_split.h deleted file mode 100644 index d4e6c16d..00000000 --- a/vcg/complex/tetramesh/modify/edge_split.h +++ /dev/null @@ -1,478 +0,0 @@ -/**************************************************************************** -* VCGLib o o * -* Visual and Computer Graphics Library o o * -* _ O _ * -* Copyright(C) 2004 \/)\/ * -* 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. * -* * -****************************************************************************/ -/**************************************************************************** - History - -****************************************************************************/ -#ifndef __VCG_TETRA_EDGE_SPLIT -#define __VCG_TETRA_EDGE_SPLIT - -#include -#include -#include -#include -namespace vcg{ -namespace tetra{ - -/** \addtogroup tetramesh */ -/*@{*/ -/// This Class is used for split the edges - -template -class EdgeSplit - { - public: - /// The tetrahedral mesh type - typedef typename TETRA_MESH_TYPE TetraMeshType; - /// The tetrahedron type - typedef typename TetraMeshType::TetraType TetraType; - /// The vertex type - typedef typename TetraType::VertexType VertexType; - /// The vertex iterator type - typedef typename TetraMeshType::VertexIterator VertexIterator; - /// The tetra iterator type - typedef typename TetraMeshType::TetraIterator TetraIterator; - /// The coordinate type - typedef typename TetraType::VertexType::CoordType CoordType; - ///the container of tetrahedron type - typedef typename TetraMeshType::TetraContainer TetraContainer; - ///the container of vertex type - typedef typename TetraMeshType::VertexContainer VertexContainer; - /// The HEdgePos type - typedef PosLoop PosType; - /// The topology updater type - typedef vcg::tetra::UpdateTetraTopology Topology; - /// The allocator type - typedef vcg::tetra::Allocator TetraAllocator; - /// Default Constructor - EdgeSplit() - { - }; - - ~EdgeSplit() - { - }; - -private: -///the tetrahedron that must mark as Deleted after substitution -TetraType* _toDel[30]; -///The number of tetrahedrons that are substituted -int _nT; - -Topology _Topo; - -///add a vertex into the edge at distance alfa ( 0 All= Allocator(); - VertexIterator vn=All.AddVertices(tm,1); - vn->Flags()=0; - vn->VTb()=NULL; - vn->VTi()=-1; - vn->P()=(v0->P()*alfa)+(v1->P()*(1.0f-alfa)); - return (&(*vn)); -} - -///set the default v-t topology -void _SetDefultVTTopology(TetraType *t) -{ -unsigned int j; -for (j=0;j<4;j++) -{ - t->TVp(j) = NULL; - t->TVi(j) = -1; -} -} - -/// Transform the vertex index according to rotation of the tetraedron -/// that trasform it in the basic case -static int _GetMapVertEdgeRot(const int &indexE,const int &indexV) - { - static int mapvertedgerot[12][4]={ - {0,3,1,2}, - {0,1,2,3}, - {0,2,3,1}, - {1,3,2,0}, - {1,0,3,2}, - {2,1,3,0}, - - {1,2,0,3}, - {2,3,0,1}, - {3,1,0,2}, - {2,0,1,3}, - {3,2,1,0}, - {3,0,2,1}, - }; - assert ((indexE<12)&&(indexV<4)); - return mapvertedgerot[indexE][indexV]; - } - -/// Transform the face index according to rotation of the tetraedron -/// that trasform it in the basic case - static int _GetMapFaceEdgeRot(const int &indexE,const int &indexF) - { - static int mapfaceedgerot[12][4]={ - {1,2,0,3}, - {0,1,2,3}, - {2,0,1,3}, - {3,1,0,2}, - {1,0,3,2}, - {3,0,2,1}, - - {0,3,1,2}, - {2,3,0,1}, - {1,3,2,0}, - {0,2,3,1}, - {3,2,1,0}, - {2,1,3,0}, - }; - assert ((indexE<12)&&(indexF<4)); - return mapfaceedgerot[indexE][indexF]; - } - -/// Returns the rotation sense during the loop on the edge to divide -/// according to rotation of the tetraedron that trasform it in the basic case - static int _GetDirRot(int indexE,int indexF) - { - static int mapfaceedgerot[12][4]={ - {2,0,-1,-1}, - {0,-1,2,-1}, - {-1,2,0,-1}, - {2,-1,-1,0}, - {-1,0,-1,2}, - {-1,-1,2,0}, - - {0,2,-1,-1}, - {2,-1,0,-1}, - {-1,0,2,-1}, - {0,-1,-1,2}, - {-1,2,-1,0}, - {-1,-1,0,2}, - }; - - assert ((indexE<12)&&(indexF<4)); - return mapfaceedgerot[indexE][indexF]; - } - -///Built an Half edge on tetrahedron t using edge edge -PosType _FindPos(TetraType *t,int edge) -{ - int face0=Tetra::FofE(edge,0); - int ve0=Tetra::VofE(edge,0); - PosType pos(t,face0,edge,ve0); - return pos; -} - -///Assert the right order of vertex that compose the tetrahedron -void _AssertOrder(TetraType *t,VertexType *v0,VertexType *v1,VertexType *v2,VertexType *v3) -{ - assert(t->V(0)==v0); - assert(t->V(1)==v1); - assert(t->V(2)==v2); - assert(t->V(3)==v3); -} - -///Connect trought Tetrahedron-Tetrahedron Topology t0 and t1 with faces i0 and i1 -void _ConnectTTTopology(TetraType *t0,int i0,TetraType *t1,int i1) -{ - assert((i0>=0)&&(i0<4)); - assert((i1>=0)&&(i1<4)); - assert((!t0->IsD())&&(!t1->IsD())); - t0->TTp(i0)=t1; - t0->TTi(i0)=i1; - t1->TTp(i1)=t0; - t1->TTi(i1)=i0; - assert( (((t0->TTp(i0))->TTp(t0->TTi(i0)))==t0)); - assert( (((t1->TTp(i1))->TTp(t1->TTi(i1)))==t1)); -} - -///Divide the tetrahadron in pos in two tetrahedrons using the new vertex vnew -void _Divide(PosType pos,VertexType *vnew,TetraType *newtp0,TetraType *newtp1,bool invert) -{ - int curredge=pos.E(); - - //control if the edge vertices arein the right order for the table - if (invert) - curredge+=6; - - //find the new position to vertex according - int ie0=_GetMapVertEdgeRot(curredge,0); - int ie1=_GetMapVertEdgeRot(curredge,2); - int in0=_GetMapVertEdgeRot(curredge,1); - int in1=_GetMapVertEdgeRot(curredge,3); - - //as first the ones that appartain to the selected curredge - VertexType *ve0=pos.T()->V(ie0); - VertexType *ve1=pos.T()->V(ie1); - - //and after the others that will be in the cutting plane - VertexType *vn0=pos.T()->V(in0); - VertexType *vn1=pos.T()->V(in1); - - newtp0->V(0)=ve0; - newtp0->V(1)=vn0; - newtp0->V(2)=vnew; - newtp0->V(3)=vn1; - - newtp1->V(0)=vnew; - newtp1->V(1)=vn0; - newtp1->V(2)=ve1; - newtp1->V(3)=vn1; - - //right order of the vertices -#ifdef _DEBUG - _AssertOrder(newtp0,ve0,vn0,vnew,vn1); - _AssertOrder(newtp1,vnew,vn0,ve1,vn1); - //end asserts -#endif -} - -bool _InvertRotation(PosType pos) -{ - return (pos.V()!=Tetra::VofE(pos.E(),0)); -} - -///substitute the told tetrahedon on VT topology with newtp0 and newtp1 as created -void _SubstituteVTTopology(TetraType *told,TetraType *newtp0,TetraType *newtp1) -{ - _SetDefultVTTopology(newtp0); - _SetDefultVTTopology(newtp1); - - //detach the old tetrahedron from VTtopology - _Topo.DetachVTTopology(told); - //tetrahedron 0 - _Topo.InsertVTTopology(newtp0); - //tetrahedron 1 - _Topo.InsertVTTopology(newtp1); -} - -///control if the connections between tetrahedron created have the right shared vertices -void _ControlConnection(TetraType *oldtp0,TetraType *newtp0) -{ - VertexType *v00=oldtp0->V(0); - VertexType *v01=oldtp0->V(1); - VertexType *v02=oldtp0->V(2); - VertexType *v03=oldtp0->V(3); - - VertexType *v10=newtp0->V(0); - VertexType *v11=newtp0->V(1); - VertexType *v12=newtp0->V(2); - VertexType *v13=newtp0->V(3); - - assert(((v00==v10)&&(v02==v12))||((v00==v12)&&(v02==v10))); - assert(((v01==v13)&&(v03!=v11))||((v01!=v13)&&(v03==v11))); -} - -///set as extern the 4 faces of the tetrahedron -void _SetDefaultTTExtern(TetraType *t) -{ - for (int y=0;y<4;y++) - { - t->TTp(y)=t; - t->TTi(y)=y; - } -} - -///substitute in Tetra Tetra Topology the tetrahedron old_t with new_t in according -///to face and edge - -void _SubstituteTTTopology(TetraType *old_t,TetraType *new_t,int edgerot,int face) -{ - int indexface=_GetMapFaceEdgeRot(edgerot,face); - - if (old_t->IsBorderF(indexface)) - { - new_t->TTp(face)=new_t; - new_t->TTi(face)=face; - } - else - { - TetraType *tetrad=old_t->TTp(indexface); - int fad=old_t->TTi(indexface); - _ConnectTTTopology(new_t,face,tetrad,fad); - assert (!tetrad->IsD()); - } -} - -/// sobstitute the old tetrahedrons that share the edge in pos with new ones -/// that share the vertex vnew that divide the old edge - -void _AddNewTetrahedrons(TetraMeshType &tm,PosType pos,VertexType *vnew) -{ - - TetraType *oldtp0=NULL; - TetraType *oldtp1=NULL; - - TetraType *newtp0; - TetraType *newtp1; - - TetraType *firsttp0=NULL; - TetraType *firsttp1=NULL; - - - int curredge; - int direction=-1; - bool invert=false; - -TetraAllocator All=TetraAllocator(); -pos.Reset(); -_nT=0; - -while (!pos.LoopEnd()) - { - assert(!pos.T()->IsD()); - - invert=_InvertRotation(pos); - - //CREATE THE NEW TETRAHEDRONS - - //create the new ones putting the veritices in the right order - TetraIterator ti=All.AddTetra(tm,2); - newtp0 = &(*ti); - ti++; - newtp1 = &(*ti); - - - _Divide(pos,vnew,newtp0,newtp1,invert); - -#ifdef _DEBUG - if ((oldtp0!=NULL)&&(!pos.Jump())) - _ControlConnection(oldtp0,newtp0); - if ((oldtp1!=NULL)&&(!pos.Jump())) - _ControlConnection(oldtp1,newtp1); -#endif - - // SUBSTITUTE NEW TETRAHEDRONS ON VT TOPOLOGY - if (tm.HasVTTopology()) - _SubstituteVTTopology(pos.T(),newtp0,newtp1); - - - //THEN SET THE T-T TOPOLOGY - - _SetDefaultTTExtern(newtp0); - _SetDefaultTTExtern(newtp1); - - curredge=pos.E(); - if (invert) - curredge+=6; - - //face3 - _SubstituteTTTopology(pos.T(),newtp1,curredge,3); - - //face1 - _SubstituteTTTopology(pos.T(),newtp0,curredge,1); - - //now I set t-t topology between themselfes - - _ConnectTTTopology(newtp0,3,newtp1,1); - - if (pos.Jump()) - { - vnew->SetB(); - oldtp0=NULL; - oldtp1=NULL; - } - - direction=_GetDirRot(curredge,pos.F()); - assert(direction!=-1); - //control the direction of moving - if ((oldtp0!=NULL)&&(oldtp1!=NULL)) - { - //direction=_GetDirRot(oldtp0,newtp0); - - //find direction of moving - if (direction==0) - { - _ConnectTTTopology(oldtp0,0,newtp0,2); - _ConnectTTTopology(oldtp1,0,newtp1,2); - } - else - if (direction==2) - { - _ConnectTTTopology(oldtp0,2,newtp0,0); - _ConnectTTTopology(oldtp1,2,newtp1,0); - } - } - //assign if it is the first one - if (firsttp0==NULL) - firsttp0=newtp0; - if (firsttp1==NULL) - firsttp1=newtp1; - - oldtp0=newtp0; - oldtp1=newtp1; - - _toDel[_nT]=pos.T(); - _nT++; - pos.NextT(); - } - - //at the end I finish the connections - if (!(pos.Jump())&&(direction==0)&&(firsttp0!=NULL)&&(firsttp1!=NULL)&&(oldtp0!=NULL)&&(oldtp1!=NULL)) - { - _ConnectTTTopology(oldtp0,0,firsttp0,2); - _ConnectTTTopology(oldtp1,0,firsttp1,2); - } - else if (!(pos.Jump())&&(direction==2)&&(firsttp0!=NULL)&&(firsttp1!=NULL)&&(oldtp0!=NULL)&&(oldtp1!=NULL)) - { - _ConnectTTTopology(oldtp0,2,firsttp0,0); - _ConnectTTTopology(oldtp1,2,firsttp1,0); - } - else if (pos.Jump()) - vnew->SetB(); - -} - -///Mark as deleted the tetrahedron that must be substituted -void _DeleteOldTetra() -{ - for (int i=0;i<_nT;i++) - _toDel[i]->SetD(); -} - -//========================================================================= - -public: - -/// Split the edge with local remeshing -/// Tetrahedron-Tetrahedron topology is required -VertexType* DoSplit(TetraMeshType &tm,TetraType *t,int edge,double alfa) -{ - assert(!t->IsD()); - assert(tm.HasTTTopology()); - assert((alfa>0)&&(alfa<1)); - assert((edge>=0)&&(edge<6)); - VertexType *vnew=_AddVertexEdge(tm,*t,edge,alfa); - _AddNewTetrahedrons(tm,_FindPos(t,edge),vnew); - _DeleteOldTetra(); - return(vnew); -} - -};//end class - -}//end namespace tetra -}//end namespace vcg -#endif \ No newline at end of file