1 #ifndef _DIAMONDTOPOLOGY 2 #define _DIAMONDTOPOLOGY 3 4 #include <algorithm> 5 #include <ctime> 6 #include <vcg/complex/algorithms/refine.h> 7 #include <vcg/complex/complex.h> 8 #include <vcg/space/color4.h> 9 #include <vcg/space/intersection2.h> 10 11 class DiamTopology 12 { 13 typedef struct DiamondPatch 14 { 15 int FFp[4]; 16 int FFi[4]; 17 18 AbstractFace *f; 19 int edgeInd; 20 DiamondPatchDiamondPatch21 DiamondPatch(){ 22 FFp[0]=-1; 23 FFp[1]=-1; 24 FFp[2]=-1; 25 FFp[3]=-1; 26 FFi[0]=-1; 27 FFi[1]=-1; 28 FFi[2]=-1; 29 FFi[3]=-1; 30 } 31 }; 32 33 std::vector<DiamondPatch> patches; 34 IsoParametrization *isoParam; 35 typedef std::pair<AbstractFace*,int> TriEdge; 36 37 std::vector<DiamondPatch> DDAdiacency; 38 std::map<TriEdge,int> edgeMap; 39 InsertEdges()40 void InsertEdges() 41 { 42 //insert all the edges 43 AbstractMesh *domain=isoParam->AbsMesh(); 44 int index=0; 45 for (int i=0;i<domain->fn;i++) 46 { 47 AbstractFace *f0=&(domain->face[i]); 48 if (!f0->IsD()) 49 { 50 for(int j=0;j<3;j++) 51 { 52 AbstractFace * f1=f0->FFp(j); 53 if (f1>f0) 54 { 55 DDAdiacency.push_back(DiamondPatch()); 56 DDAdiacency[index].f=f0; 57 DDAdiacency[index].edgeInd=j; 58 TriEdge key=TriEdge(f0,j); 59 edgeMap.insert(std::pair<TriEdge,int>(key,index)); 60 index++; 61 } 62 } 63 } 64 65 } 66 } 67 68 69 SetTopology()70 void SetTopology() 71 { 72 73 ///data used to calculate topology 74 typedef std::pair<AbstractVertex*,AbstractFace*> DiamEdge; 75 struct InfoAdiacency 76 { 77 int index_global; 78 int index_local; 79 }; 80 81 std::map<DiamEdge,InfoAdiacency> EdgeDiamMap; 82 83 for (unsigned int i=0;i<DDAdiacency.size();i++) 84 { 85 int indexEdge=DDAdiacency[i].edgeInd; 86 AbstractFace* face=DDAdiacency[i].f; 87 AbstractVertex *v0=face->V0(indexEdge); 88 AbstractVertex *v1=face->V1(indexEdge); 89 AbstractFace *f0=face; 90 AbstractFace *f1=face->FFp(indexEdge); 91 92 ///set right order 93 if (v1<v0) 94 std::swap(v0,v1); 95 if (f1<f0) 96 std::swap(f0,f1); 97 98 ///then put in the map the various edge 99 DiamEdge de[4]; 100 de[0]=DiamEdge(v0,f0); 101 de[1]=DiamEdge(v1,f0); 102 de[2]=DiamEdge(v1,f1); 103 de[3]=DiamEdge(v0,f1); 104 105 for (int j=0;j<4;j++) 106 { 107 ///find if already exist 108 std::map<DiamEdge,InfoAdiacency>::iterator ItMap=EdgeDiamMap.find(de[j]); 109 110 ///first time insert in the table 111 if (ItMap==EdgeDiamMap.end()) 112 { 113 InfoAdiacency InfAd; 114 InfAd.index_global=i; 115 InfAd.index_local=j; 116 EdgeDiamMap.insert(std::pair<DiamEdge,InfoAdiacency>(de[j],InfAd)); 117 } 118 else 119 { 120 int index_global=(*ItMap).second.index_global; 121 int index_local =(*ItMap).second.index_local; 122 DDAdiacency[index_global].FFp[index_local]=i; 123 DDAdiacency[index_global].FFi[index_local]=j; 124 DDAdiacency[i].FFp[j]=index_global; 125 DDAdiacency[i].FFi[j]=index_local; 126 } 127 } 128 } 129 } 130 TestTopology()131 bool TestTopology() 132 { 133 for (unsigned int i=0;i<DDAdiacency.size();i++) 134 { 135 for (int j=0;j<4;j++) 136 { 137 int index_global=DDAdiacency[i].FFp[j]; 138 int index_local=DDAdiacency[i].FFi[j]; 139 if ((index_global==-1)||(index_local==-1)) 140 return false; 141 142 int opposite0=DDAdiacency[index_global].FFp[index_local]; 143 int index_local1=DDAdiacency[index_global].FFi[index_local]; 144 ///int opposite1=DDAdiacency[i].FFp[index_local]; 145 if (opposite0!=i) 146 return false; 147 if (index_local1!=j) 148 return false; 149 } 150 } 151 return true; 152 } 153 154 155 public: 156 157 158 ///initialize the parameterization Init(IsoParametrization * _isoParam)159 void Init(IsoParametrization *_isoParam) 160 { 161 162 isoParam=_isoParam; 163 164 ///initialize edges 165 InsertEdges(); 166 167 ///then set topology 168 SetTopology(); 169 170 assert(TestTopology()); 171 172 } 173 174 }; 175 #endif