1 /****************************************************************************
2 * VCGLib                                                            o o     *
3 * Visual and Computer Graphics Library                            o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2004-2016                                           \/)\/    *
6 * Visual Computing Lab                                            /\/|      *
7 * ISTI - Italian National Research Council                           |      *
8 *                                                                    \      *
9 * All rights reserved.                                                      *
10 *                                                                           *
11 * This program is free software; you can redistribute it and/or modify      *
12 * it under the terms of the GNU General Public License as published by      *
13 * the Free Software Foundation; either version 2 of the License, or         *
14 * (at your option) any later version.                                       *
15 *                                                                           *
16 * This program is distributed in the hope that it will be useful,           *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
20 * for more details.                                                         *
21 *                                                                           *
22 ****************************************************************************/
23 
24 #ifndef __SVOXEL_H__
25 #define __SVOXEL_H__
26 template<class SCALAR_TYPE=float>
27 class SVoxel
28 {
29 
30 private:
31     short v;          // distanza dalla superficie espressa in centesimi di voxel;
32     short q;          // come distanza dal bordo espressa   in centesimi di voxel; // nota che questo implica che non si potrebbe rasterizzare una singola mesh in un volume di lato > 3000^3
33     char n[3];
34     unsigned char cnt;
35     // se != 0 b deve essere true;
36     // b e'tenuto implicitamente usando cnt;
37     // se cnt == 0 || cnt>0 -> b=false
38     // se cnt == 255  -> b=true
39 
40 // b==false cnt==0 totalmente non inzializzato (Zero)
41 // b==false cnt >0 da normalizzare
42 // b==true  cnt==0 gia' normalizzato
43 // b==true  cnt >0 Errore!!!
44 
45 
46 
47 public:
48     typedef SCALAR_TYPE scalar;
SVoxel(SCALAR_TYPE vv,bool,Point3<scalar> & nn,scalar qq)49     SVoxel(SCALAR_TYPE vv, bool /*bb*/, Point3<scalar> &nn, scalar qq) {SetV(vv);SetN(nn);SetQ(qq);}
SVoxel(SCALAR_TYPE vv,const Point3<scalar> & nn,scalar qq)50     SVoxel(SCALAR_TYPE vv, const Point3<scalar> &nn, scalar qq) {SetV(vv);SetN(nn);SetQ(qq);cnt=255;}
B()51     bool B() const {return cnt==255;}  // puo' essere a true solo se cnt == 0; (il che significa che e' stato gia' normalizzato
52 
SetB(bool val)53     void SetB(bool val) {
54         assert( val == (cnt==255 || cnt==0) );
55       if(val) cnt=255;
56         else if(cnt==255) cnt=0;
57     }
58 
Cnt()59     int Cnt()      {
60         if(cnt==255) return 0;
61         else return int(cnt);
62     }
SetCnt(int val)63     void SetCnt(int val) { cnt=(unsigned char)val;}
64 
65 
N()66     Point3<scalar> N() const  	{
67         return Point3<scalar>(scalar(n[0])/127.0f,scalar(n[1])/127.0f,scalar(n[2])/127.0f);
68     }
N(const int i)69     scalar N(const int i) const
70         {
71          return scalar(n[i])/127.0f;
72         }
73 
SetN(const Point3<scalar> & nn)74     void SetN(const Point3<scalar> &nn)
75         {
76             n[0]=char( nn[0]*127.0f );
77             n[1]=char( nn[1]*127.0f );
78             n[2]=char( nn[2]*127.0f );
79         }
V()80     scalar V() const
81         {
82          return scalar(v)/100.0f;
83         }
84 
Blend(SVoxel const & vx,scalar w)85     inline void Blend( SVoxel const & vx, scalar w)
86     {
87         float w1=1.0-w;
88         SetV(V()*w1+vx.V()*w);
89         SetQ(Q()*w1+vx.Q()*w);
90         SetN(N()*w1+vx.N()*w);
91         //return *this;
92     }
93 
SetV(const float & vv)94     void SetV(const float &vv)
95         {
96          v= short(vv*100.0f);
97          if(v==0) v=1;
98         }
99 
Q()100     scalar Q() const
101         {
102          return scalar(q)/20.0f;
103         }
104 
SetQ(const float & qq)105     void SetQ(const float &qq)
106         {
107          int qi = qq * 20.0f;
108          if (qi>32767) qi =32767;
109          q = qi;
110         }
111 
Merge(const SVoxel & VOX)112     void Merge(const SVoxel &VOX)
113         {
114             v=(v*Q()+VOX.Q()*VOX.v)/(Q()+VOX.Q());
115             SetQ(Q()+VOX.Q());
116         }
Set(const SVoxel & VOX)117     void Set(const SVoxel &VOX)
118         {
119             v=VOX.v;
120             n[0]=VOX.n[0];
121             n[1]=VOX.n[1];
122             n[2]=VOX.n[2];
123             q=VOX.q;
124 
125         }
126 
127         inline SVoxel & operator += ( SVoxel const & vx)
128         {
129      if(cnt==0)
130          {
131           v=vx.v;
132             q=vx.q;
133             n[0]=vx.n[0];
134             n[1]=vx.n[1];
135             n[2]=vx.n[2];
136             cnt=1;
137          }
138      else
139         {
140          const int cnt1=cnt+1;
141          v+=vx.v;
142          q = (q*cnt+vx.q)/(cnt1);
143          n[0]=(vx.n[0]*int(cnt) +vx.n[0])/(cnt1) ;
144          n[1]=(vx.n[1]*int(cnt) +vx.n[1])/(cnt1) ;
145          n[2]=(vx.n[2]*int(cnt) +vx.n[2])/(cnt1) ;
146          if(cnt==255) cnt=1;
147          else ++cnt;
148          }
149          return *this;
150         }
151 
Normalize(int thr)152     inline bool Normalize(int thr)
153     {
154      assert(cnt>0);
155      if(cnt<thr)
156      {
157          (*this) = Zero();
158          return false;
159      }
160    v= v/cnt; // gli altri membri sono gia' normalizzati
161      cnt=255;
162      // b=true; inutile!
163     return true;
164     }
165 
IsZero()166  bool IsZero() const { return v==0; }
167 
Zero()168     static const SVoxel &Zero() {
169         static SVoxel tt(0,false,Point3f(0,0,0),0);
170         return tt;
171     }
172 };
173 
174 #endif
175