~ubuntu-branches/debian/sid/3depict/sid

« back to all changes in this revision

Viewing changes to src/common.h

  • Committer: Bazaar Package Importer
  • Author(s): D Haley
  • Date: 2010-08-09 21:23:50 UTC
  • Revision ID: james.westby@ubuntu.com-20100809212350-cg6yumndhwi3bqws
Tags: upstream-0.0.1
ImportĀ upstreamĀ versionĀ 0.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      common.h - Common functionality header 
 
3
 *      Copyright (C) 2010, D Haley 
 
4
 
 
5
 *      This program is free software: you can redistribute it and/or modify
 
6
 *      it under the terms of the GNU General Public License as published by
 
7
 *      the Free Software Foundation, either version 3 of the License, or
 
8
 *      (at your option) any later version.
 
9
 
 
10
 *      This program is distributed in the hope that it will be useful,
 
11
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *      GNU General Public License for more details.
 
14
 
 
15
 *      You should have received a copy of the GNU General Public License
 
16
 *      along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
*/
 
18
#ifndef COMMON_H
 
19
#define COMMON_H
 
20
 
 
21
#include "wxPreprec.h"
 
22
#include <wx/treectrl.h>
 
23
 
 
24
//TODO: split this between wx and non-wx stuff
 
25
 
 
26
#include <string>
 
27
#include <vector>
 
28
#include <fstream>
 
29
#include <list>
 
30
#include <algorithm>
 
31
#include <utility>
 
32
 
 
33
#include "basics.h"
 
34
#include "mathfuncs.h"
 
35
 
 
36
#define wxCStr(a) wxString(a,*wxConvCurrent)
 
37
#define wxStr(a) wxString(a.c_str(),*wxConvCurrent)
 
38
 
 
39
#define stlStr(a) (const char *)a.mb_str()
 
40
 
 
41
 
 
42
extern const char *DTD_NAME;
 
43
extern const char *PROGRAM_NAME;
 
44
extern const char *PROGRAM_VERSION;
 
45
extern const char *FONT_FILE;
 
46
 
 
47
 
 
48
//OK, this is a bit tricky. We override the operators to call
 
49
//a callback, so the UI updates keep happening, even inside the STL function
 
50
//----
 
51
template<class T>
 
52
class GreaterWithCallback 
 
53
{
 
54
        private:
 
55
                bool (*callback)(void);
 
56
                //!Reduction frequency (use callback every k its)
 
57
                unsigned int redMax;
 
58
                //!Current reduction counter
 
59
                unsigned int reduction;
 
60
                //!pointer to progress value
 
61
                unsigned int *prgPtr;
 
62
        public:
 
63
                //!Second argument is a "reduction" value to set the number of calls
 
64
                //to the random functor before initiating a callback
 
65
                GreaterWithCallback( bool (*ptr)(void),unsigned int red)
 
66
                        { callback=ptr; reduction=redMax=red;};
 
67
 
 
68
                bool operator()(const T &a, const T &b) 
 
69
                {
 
70
                        if(!reduction--)
 
71
                        {
 
72
                                reduction=redMax;
 
73
                                //Execute callback
 
74
                                (*callback)();
 
75
                        }
 
76
 
 
77
                        return a < b;
 
78
                }
 
79
};
 
80
 
 
81
 
 
82
template<class T>
 
83
class EqualWithCallback 
 
84
{
 
85
        private:
 
86
                bool (*callback)(void);
 
87
                //!Reduction frequency (use callback every k its)
 
88
                unsigned int redMax;
 
89
                //!Current reduction counter
 
90
                unsigned int reduction;
 
91
                //!pointer to progress value
 
92
                unsigned int *prgPtr;
 
93
        public:
 
94
                //!Second argument is a "reduction" value to set the number of calls
 
95
                //to the random functor before initiating a callback
 
96
                EqualWithCallback( bool (*ptr)(void),unsigned int red)
 
97
                        { callback=ptr; reduction=redMax=red;};
 
98
 
 
99
                bool operator()(const T &a, const T &b) 
 
100
                {
 
101
                        if(!reduction--)
 
102
                        {
 
103
                                reduction=redMax;
 
104
                                //Execute callback
 
105
                                (*callback)();
 
106
                        }
 
107
 
 
108
                        return a ==b;
 
109
                }
 
110
};
 
111
//----
 
112
 
 
113
 
 
114
//!Property types for wxPropertyGrid
 
115
enum
 
116
{
 
117
        PROPERTY_TYPE_BOOL=1,
 
118
        PROPERTY_TYPE_INTEGER,
 
119
        PROPERTY_TYPE_REAL,
 
120
        PROPERTY_TYPE_COLOUR,
 
121
        PROPERTY_TYPE_STRING,
 
122
        PROPERTY_TYPE_POINT3D,
 
123
        PROPERTY_TYPE_CHOICE,
 
124
};
 
125
 
 
126
//!Allowable export ion formats
 
127
enum
 
128
{
 
129
        IONFORMAT_POS=1,
 
130
};
 
131
 
 
132
//Randomly select subset. Subset will be (somewhat) sorted on output
 
133
template<class T> size_t randomSelect(std::vector<T> &result, const std::vector<T> &source, 
 
134
                                                        RandNumGen &rng, size_t num,unsigned int &progress,bool (*callback)())
 
135
{
 
136
        //If there are not enough points, just copy it across in whole
 
137
        if(source.size() < num)
 
138
        {
 
139
                num=source.size();
 
140
                result.resize(source.size());
 
141
                for(size_t ui=0; ui<num; ui++)
 
142
                        result[ui] = source[ui]; 
 
143
        
 
144
                return num;
 
145
        }
 
146
 
 
147
        result.resize(num);
 
148
 
 
149
 
 
150
        size_t numTicksNeeded;
 
151
        //If the number of items is larger than half the source size,
 
152
        //switch to tracking vacancies, rather than data
 
153
        if(num < source.size()/2)
 
154
                numTicksNeeded=num;
 
155
        else
 
156
                numTicksNeeded=source.size()-num;
 
157
 
 
158
        //Randomly selected items 
 
159
        //---------
 
160
        std::vector<size_t> ticks;
 
161
        ticks.resize(numTicksNeeded);
 
162
 
 
163
        //Create an array of numTicksNeededbers and fill 
 
164
        for(size_t ui=0; ui<numTicksNeeded; ui++)
 
165
                ticks[ui]=(size_t)(rng.genUniformDev()*(source.size()-1));
 
166
 
 
167
        //Remove duplicates. Intersperse some callbacks to be nice
 
168
        GreaterWithCallback<size_t> gFunctor(callback,50000);
 
169
        std::sort(ticks.begin(),ticks.end(),gFunctor);
 
170
        EqualWithCallback<size_t> eqFunctor(callback,50000);
 
171
        std::unique(ticks.begin(),ticks.end(),eqFunctor);       
 
172
 
 
173
        std::vector<size_t> moreTicks;
 
174
        //Top up with unique entries
 
175
        while(ticks.size() +moreTicks.size() < numTicksNeeded)
 
176
        {
 
177
                size_t index;
 
178
 
 
179
                //This is actually not too bad. the collision probability is at most 50%
 
180
                //due the switching behaviour above, for any large number of items 
 
181
                //So this is at worst case nlog(n) (I think)
 
182
                index =rng.genUniformDev()*(source.size()-1);
 
183
                if(!binary_search(ticks.begin(),ticks.end(),index) &&
 
184
                        std::find(moreTicks.begin(),moreTicks.end(),index) ==moreTicks.end())
 
185
                        moreTicks.push_back(index);
 
186
 
 
187
        }
 
188
 
 
189
        ticks.reserve(numTicksNeeded);
 
190
        for(size_t ui=0;ui<moreTicks.size();ui++)
 
191
                ticks.push_back(moreTicks[ui]);
 
192
 
 
193
        moreTicks.clear();
 
194
 
 
195
        ASSERT(ticks.size() == numTicksNeeded);
 
196
        //---------
 
197
        
 
198
        size_t pos=0;
 
199
        //Transfer the output
 
200
        unsigned int curProg=70000;
 
201
 
 
202
        if(num < source.size()/2)
 
203
        {
 
204
                for(std::vector<size_t>::iterator it=ticks.begin();it!=ticks.end();it++)
 
205
                {
 
206
 
 
207
                        result[pos]=source[*it];
 
208
                        pos++;
 
209
                        if(!curProg--)
 
210
                        {
 
211
                                progress= (unsigned int)((float)(curProg)/((float)num)*100.0f);
 
212
                                (*callback)();
 
213
                                curProg=70000;
 
214
                        }
 
215
                }
 
216
        }
 
217
        else
 
218
        {
 
219
                //Sort the ticks properly (mostly sorted anyway..)
 
220
                std::sort(ticks.begin(),ticks.end(),gFunctor);
 
221
                
 
222
                unsigned int curTick=0;
 
223
                for(size_t ui=0;ui<num; ui++)
 
224
                {
 
225
                        //Don't copy if this is marked
 
226
                        if(ui == ticks[curTick])
 
227
                                curTick++;
 
228
                        else
 
229
                                result[ui-curTick]=source[ui];
 
230
                        
 
231
                        if(!curProg--)
 
232
                        {
 
233
                                progress= (unsigned int)((float)(curProg)/((float)num)*100.0f);
 
234
                                (*callback)();
 
235
                                curProg=70000;
 
236
                        }
 
237
                }
 
238
        }
 
239
 
 
240
        ticks.clear();
 
241
        
 
242
        return num;
 
243
}
 
244
 
 
245
//Randomly select subset. Subset will be (somewhat) sorted on output
 
246
template<class T> size_t randomDigitSelection(std::vector<T> &result, const size_t max,
 
247
                        RandNumGen &rng, size_t num,unsigned int &progress,bool (*callback)())
 
248
{
 
249
        //If there are not enough points, just copy it across in whole
 
250
        if(max < num)
 
251
        {
 
252
                num=max;
 
253
                result.resize(max);
 
254
                for(size_t ui=0; ui<num; ui++)
 
255
                        result[ui] = ui; 
 
256
        
 
257
                return num;
 
258
        }
 
259
 
 
260
        result.resize(num);
 
261
 
 
262
 
 
263
        size_t numTicksNeeded;
 
264
        //If the number of items is larger than half the source size,
 
265
        //switch to tracking vacancies, rather than data
 
266
        if(num < max/2)
 
267
                numTicksNeeded=num;
 
268
        else
 
269
                numTicksNeeded=max-num;
 
270
 
 
271
        //Randomly selected items 
 
272
        //---------
 
273
        std::vector<size_t> ticks;
 
274
        ticks.resize(numTicksNeeded);
 
275
 
 
276
        //Create an array of numTicksNeededbers and fill 
 
277
        for(size_t ui=0; ui<numTicksNeeded; ui++)
 
278
                ticks[ui]=(size_t)(rng.genUniformDev()*(max-1));
 
279
 
 
280
        //Remove duplicates. Intersperse some callbacks to be nice
 
281
        GreaterWithCallback<size_t> gFunctor(callback,50000);
 
282
        std::sort(ticks.begin(),ticks.end(),gFunctor);
 
283
        EqualWithCallback<size_t> eqFunctor(callback,50000);
 
284
        std::unique(ticks.begin(),ticks.end(),eqFunctor);       
 
285
 
 
286
        std::vector<size_t> moreTicks;
 
287
        //Top up with unique entries
 
288
        while(ticks.size() +moreTicks.size() < numTicksNeeded)
 
289
        {
 
290
                size_t index;
 
291
 
 
292
                //This is actually not too bad. the collision probability is at most 50%
 
293
                //due the switching behaviour above, for any large number of items 
 
294
                //So this is at worst case nlog(n) (I think)
 
295
                index =rng.genUniformDev()*(max-1);
 
296
                if(!binary_search(ticks.begin(),ticks.end(),index) &&
 
297
                        std::find(moreTicks.begin(),moreTicks.end(),index) ==moreTicks.end())
 
298
                        moreTicks.push_back(index);
 
299
 
 
300
        }
 
301
 
 
302
        ticks.reserve(numTicksNeeded);
 
303
        for(size_t ui=0;ui<moreTicks.size();ui++)
 
304
                ticks.push_back(moreTicks[ui]);
 
305
 
 
306
        moreTicks.clear();
 
307
 
 
308
        ASSERT(ticks.size() == numTicksNeeded);
 
309
        //---------
 
310
        
 
311
        size_t pos=0;
 
312
        //Transfer the output
 
313
        unsigned int curProg=70000;
 
314
 
 
315
        if(num < max/2)
 
316
        {
 
317
                for(std::vector<size_t>::iterator it=ticks.begin();it!=ticks.end();it++)
 
318
                {
 
319
 
 
320
                        result[pos]=*it;
 
321
                        pos++;
 
322
                        if(!curProg--)
 
323
                        {
 
324
                                progress= (unsigned int)((float)(curProg)/((float)num)*100.0f);
 
325
                                (*callback)();
 
326
                                curProg=70000;
 
327
                        }
 
328
                }
 
329
        }
 
330
        else
 
331
        {
 
332
                //Sort the ticks properly (mostly sorted anyway..)
 
333
                std::sort(ticks.begin(),ticks.end(),gFunctor);
 
334
                
 
335
                unsigned int curTick=0;
 
336
                for(size_t ui=0;ui<num; ui++)
 
337
                {
 
338
                        //Don't copy if this is marked
 
339
                        if(ui == ticks[curTick])
 
340
                                curTick++;
 
341
                        else
 
342
                                result[ui-curTick]=ui;
 
343
                        
 
344
                        if(!curProg--)
 
345
                        {
 
346
                                progress= (unsigned int)((float)(curProg)/((float)num)*100.0f);
 
347
                                (*callback)();
 
348
                                curProg=70000;
 
349
                        }
 
350
                }
 
351
        }
 
352
 
 
353
        ticks.clear();
 
354
        
 
355
        return num;
 
356
}
 
357
 
 
358
 
 
359
#endif