00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __VCGLIB_ZONOHEDRON
00025 #define __VCGLIB_ZONOHEDRON
00026
00027 namespace vcg {
00028 namespace tri {
00053 template <class Scalar>
00054 class Zonohedron{
00055 public:
00056
00057 typedef Point3<Scalar> Vec3;
00058
00059 Zonohedron(){}
00060
00061 void addVector(Scalar x, Scalar y, Scalar z);
00062 void addVector(Vec3 v);
00063 void addVectors(const std::vector< Vec3 > );
00064
00065 const std::vector< Vec3 >& vectors() const {
00066 return vec;
00067 }
00068
00069 template<class MeshType>
00070 void createMesh( MeshType& output );
00071
00072 private:
00073
00074
00075
00076
00077 typedef int VecIndex;
00078
00079
00080 struct Signature {
00081 std::vector< bool > v;
00082 Signature(){}
00083 Signature(int n){ v.resize(n,false); }
00084
00085 bool operator == (const Signature & b) const {
00086 return (b.v == v);
00087 }
00088 bool operator < (const Signature & b) const {
00089 return (b.v < v);
00090 }
00091 Signature& set(VecIndex i, bool value){
00092 v[i] = value;
00093 return *this;
00094 }
00095 Signature& set(VecIndex i, bool valueI, VecIndex j, bool valueJ){
00096 v[i] = valueI;
00097 v[j] = valueJ;
00098 return *this;
00099 }
00100 };
00101
00102 struct Face {
00103 int vert[4];
00104 };
00105
00106
00107 std::vector< Vec3 > precomputedCross;
00108
00109 void precompteAllCrosses(){
00110 precomputedCross.resize(n*n);
00111 for (int i=0; i<n; i++) for (int j=0; j<n; j++) {
00112 precomputedCross[i*n+j] = vec[i] ^ vec[j] ;
00113 }
00114 }
00115
00116 Vec3 cross(VecIndex i, VecIndex j){
00117 return precomputedCross[i*n+j];
00118 }
00119
00120
00121 static Vec3 uniqueVerse(Vec3 v){
00122 if (v.X()>0) return v;
00123 else if (v.X()<0) return -v;
00124 else if (v.Y()>0) return v;
00125 else if (v.Y()<0) return -v;
00126 else if (v.Z()>0) return v;
00127 return -v;
00128 }
00129
00130 static Vec3 altVec(int i) {
00131 return Vec3(1, i, i*i);
00132 }
00133
00134 static Scalar tripleProduct( const Vec3 &a, const Vec3 &b, const Vec3 & c){
00135 return ( a ^ b ) * c;
00136 }
00137
00138
00139 bool signOf_IxJoK(VecIndex i, VecIndex j, VecIndex k){
00140 const float EPSILON_SQUARED = 1e-12;
00141 bool invert = false;
00142
00143 if (i<j) { std::swap(i,j); invert = !invert; }
00144 if (j<k) { std::swap(j,k); invert = !invert;
00145 if (i<j) { std::swap(i,j); invert = !invert; }
00146 }
00147
00148
00149 Scalar res = cross( i , j ) * vec[k] ;
00150
00151 if (res*res<=EPSILON_SQUARED) {
00152
00153
00154
00155 res = tripleProduct( altVec(i), vec[j], vec[k]) +
00156 tripleProduct( vec[i], altVec(j), vec[k]) +
00157 tripleProduct( vec[i], vec[j], altVec(k)) ;
00158 if (res*res<=EPSILON_SQUARED) {
00159
00160 res = tripleProduct( vec[i], altVec(j), altVec(k)) +
00161 tripleProduct( altVec(i), vec[j], altVec(k)) +
00162 tripleProduct( altVec(i), altVec(j), vec[k]) ;
00163 }
00164 if (res*res<=EPSILON_SQUARED) {
00165
00166 res = tripleProduct( altVec(i), altVec(j), altVec(k) );
00167 }
00168 }
00169
00170 return ( (res>=0) != invert );
00171 }
00172
00173 int n;
00174 std::vector<Vec3> vec;
00175
00176 int vertCount;
00177 std::vector<Face> _face;
00178
00179 typedef std::map< Signature, int > VertexMap;
00180 VertexMap vertexMap;
00181
00182
00183 VecIndex vertexIndex(const Signature &s){
00184 typename VertexMap::iterator i;
00185
00186 i = vertexMap.find( s );
00187 if (i!= vertexMap.end() ) return i->second;
00188 else {
00189 int newVertex = vertCount++;
00190
00191 vertexMap[s] = newVertex;
00192 return newVertex;
00193 }
00194 }
00195
00196
00197 Face& face(VecIndex i, VecIndex j){
00198 assert(i!=j);
00199 assert( i*n + j < (int) _face.size() );
00200 return _face[i*n + j];
00201 }
00202
00203 Vec3 toPos(const Signature &s) const{
00204 Vec3 res(0,0,0);
00205 for (int i=0; i<n; i++)
00206 if (s.v[i]) res += vec[i];
00207 return res;
00208 }
00209
00210 void createInternalMesh() {
00211
00212 n = vec.size();
00213 precompteAllCrosses();
00214
00215
00216 _face.resize( n*n );
00217
00218 vertCount = 0;
00219 vertexMap.clear();
00220
00221 for (int i=0; i<n; i++) {
00222
00223 for (int j=0; j<n; j++) if(i!=j) {
00224 Signature s(n);
00225 for (int k=0; k<n; k++) if ((k!=j) && (k!=i))
00226 {
00227 s.set( k , signOf_IxJoK( i,j,k ) );
00228 }
00229 face(i,j).vert[0] = vertexIndex( s.set(i,false, j,false) );
00230 face(i,j).vert[1] = vertexIndex( s.set(i,false, j,true ) );
00231 face(i,j).vert[2] = vertexIndex( s.set(i,true, j,true ) );
00232 face(i,j).vert[3] = vertexIndex( s.set(i,true, j,false) );
00233 }
00234 }
00235 }
00236
00237
00238 };
00239
00240
00241 template<class Scalar>
00242 void Zonohedron<Scalar>::addVectors(std::vector< Zonohedron<Scalar>::Vec3 > input){
00243 for (size_t i=0; i<input.size(); i++) {
00244 addVector( input[i]);
00245 }
00246 }
00247
00248 template<class Scalar>
00249 void Zonohedron<Scalar>::addVector(Scalar x, Scalar y, Scalar z) {
00250 addVector( Vec3(x,y,z) );
00251 }
00252
00253
00254 template<class Scalar>
00255 void Zonohedron<Scalar>::addVector(Zonohedron<Scalar>::Vec3 v){
00256 vec.push_back(v);
00257 }
00258
00259
00260 template<class Scalar>
00261 template<class MeshType>
00262 void Zonohedron<Scalar>::createMesh(MeshType &m){
00263 typedef MeshType Mesh;
00264 typedef typename Mesh::VertexPointer MeshVertexPointer;
00265 typedef typename Mesh::VertexIterator MeshVertexIterator;
00266 typedef typename Mesh::FaceIterator MeshFaceIterator;
00267 typedef typename Mesh::FaceType MeshFace;
00268
00269 createInternalMesh();
00270
00271 m.Clear();
00272 Allocator<MeshType>::AddVertices(m,vertexMap.size());
00273 Allocator<MeshType>::AddFaces(m,n*(n-1) * 2);
00274
00275
00276 MeshVertexIterator vi=m.vert.begin();
00277 for (typename VertexMap::iterator i=vertexMap.begin(); i!=vertexMap.end(); i++){
00278 (vi + i->second )->P() = toPos( i->first );
00279 }
00280
00281
00282 MeshFaceIterator fi=m.face.begin();
00283
00284 for (int i=0; i<n; i++) {
00285 for (int j=0; j<n; j++) if (i!=j) {
00286 const Face &f( face(i,j) );
00287 for (int k=0; k<2; k++) {
00288 for (int w=0; w<3; w++) {
00289 fi->V(w) = &* (vi + f.vert[(w+k*2)%4] );
00290 }
00291 if (tri::HasPerFaceNormal(m)) {
00292 fi->N() = cross(i,j).normalized();
00293 }
00294 if (tri::HasPerFaceFlags(m)) {
00295 fi->SetF(2);
00296 }
00297 fi++;
00298 }
00299 }
00300 }
00301
00302
00303 }
00304
00305
00307
00308 }
00309 }
00310
00311 #endif // __VCGLIB_ZONOHEDRON