stage.cc
Go to the documentation of this file.
1 // Author: Richard Vaughan
2 
3 #include <FL/Fl_Shared_Image.H>
4 
5 #include "config.h" // results of cmake's system configuration tests
6 #include "file_manager.hh"
7 #include "stage.hh"
8 using namespace Stg;
9 
10 static bool init_called = false;
11 
12 const char *Stg::Version()
13 {
14  return VERSION;
15 }
16 
17 void Stg::Init(int *argc, char **argv[])
18 {
19  PRINT_DEBUG("Stg::Init()");
20 
21  // copy the command line args for controllers to inspect
22  World::args.clear();
23  for (int i = 0; i < *argc; i++)
24  World::args.push_back((*argv)[i]);
25 
26  // seed the RNG
27  srand48(time(NULL));
28 
29  if (!setlocale(LC_ALL, "POSIX"))
30  PRINT_WARN("Failed to setlocale(); config file may not be parse correctly\n");
31 
33 
34  // ask FLTK to load support for various image formats
35  fl_register_images();
36 
37  init_called = true;
38 }
39 
41 {
42  return init_called;
43 }
44 
45 const Color Color::blue(0, 0, 1);
46 const Color Color::red(1, 0, 0);
47 const Color Color::green(0, 1, 0);
48 const Color Color::yellow(1, 1, 0);
49 const Color Color::magenta(1, 0, 1);
50 const Color Color::cyan(0, 1, 1);
51 
52 // set all the pixels in a rectangle
53 // static inline void pb_set_rect( Fl_Shared_Image* pb,
54 // const unsigned int x, const unsigned int y,
55 // const unsigned int rwidth, const unsigned int
56 // rheight,
57 // const uint8_t val )
58 // {
59 // const unsigned int bytes_per_sample = 1;
60 // const unsigned int depth = pb->d();
61 // const unsigned int width = pb->w();
62 
63 // for( unsigned int a = y; a < y+rheight; a++ )
64 // {
65 // // zeroing
66 // //uint8_t* pix = pb_get_pixel( pb, x, a );
67 // uint8_t* pix = (uint8_t*)(pb->data()[0] + (a*width*depth) + x*depth);
68 // memset( pix, val, rwidth * depth * bytes_per_sample );
69 // }
70 // }
71 
72 static inline bool pixel_is_set(uint8_t *pixels, const unsigned int width, const unsigned int depth,
73  const unsigned int x, const unsigned int y, uint8_t threshold)
74 {
75  return ((pixels + (y * width * depth) + x * depth)[0] > threshold);
76 }
77 
78 double direction(double a)
79 {
80  if (a == 0.0)
81  return 0;
82  else
83  return sgn(a);
84 }
85 
86 int Stg::polys_from_image_file(const std::string &filename,
87  std::vector<std::vector<point_t> > &polys)
88 {
89  // TODO: make this a parameter
90  const int threshold = 127;
91 
92  Fl_Shared_Image *img = Fl_Shared_Image::get(filename.c_str());
93  if (img == NULL) {
94  std::cerr << "failed to open file: " << filename << std::endl;
95 
96  assert(img); // easy access to this point in debugger
97  exit(-1);
98  }
99 
100  // printf( "loaded image %s w %d h %d d %d count %d ld %d\n",
101  // filename, img->w(), img->h(), img->d(), img->count(), img->ld() );
102 
103  const unsigned int width = img->w();
104  const unsigned height = img->h();
105  const unsigned int depth = img->d();
106  uint8_t *pixels = (uint8_t *)img->data()[0];
107 
108  // a set of previously seen directed edges, The key is a 4-element vector
109  // [x1,y1,x2,y2].
110  std::set<std::vector<uint32_t> > edges;
111 
112  for (unsigned int y = 0; y < height; y++) {
113  for (unsigned int x = 0; x < width; x++) {
114  // skip blank (white) pixels
115  if (pixel_is_set(pixels, width, depth, x, y, threshold))
116  continue;
117 
118  // generate the four directed edges for this pixel
119  std::vector<uint32_t> edge[4];
120 
121  for (int i = 0; i < 4; i++)
122  edge[i].resize(4);
123 
124  edge[0][0] = x + 0;
125  edge[0][1] = y + 0;
126  edge[0][2] = x + 1;
127  edge[0][3] = y + 0;
128 
129  edge[1][0] = x + 1;
130  edge[1][1] = y + 0;
131  edge[1][2] = x + 1;
132  edge[1][3] = y + 1;
133 
134  edge[2][0] = x + 1;
135  edge[2][1] = y + 1;
136  edge[2][2] = x + 0;
137  edge[2][3] = y + 1;
138 
139  edge[3][0] = x + 0;
140  edge[3][1] = y + 1;
141  edge[3][2] = x + 0;
142  edge[3][3] = y + 0;
143 
144  // put them in the set of the inverse edge does not exist
145  for (int i = 0; i < 4; i++) {
146  // the same edge with the opposite direction
147  std::vector<uint32_t> inv(4);
148  inv[0] = edge[i][2];
149  inv[1] = edge[i][3];
150  inv[2] = edge[i][0];
151  inv[3] = edge[i][1];
152 
153  std::set<std::vector<uint32_t> >::iterator it = edges.find(inv);
154 
155  if (it == edges.end()) // inverse not found
156  edges.insert(edge[i]); // add the new edge
157  else // inverse found! delete it
158  edges.erase(it);
159  }
160  }
161  }
162 
163  std::multimap<point_t, point_t> mmap;
164 
165  FOR_EACH (it, edges) {
166  // fill a multimap with start-point / end-point pairs.
167  std::pair<point_t, point_t> p(point_t((*it)[0], (*it)[1]), point_t((*it)[2], (*it)[3]));
168  mmap.insert(p);
169  }
170 
171  for (std::multimap<point_t, point_t>::iterator seedit = mmap.begin(); seedit != mmap.end();
172  seedit = mmap.begin()) {
173  std::vector<point_t> poly;
174 
175  while (seedit != mmap.end()) {
176  // invert y axis and add the new point to the poly
177  point_t pt = seedit->first;
178  pt.y = -pt.y;
179 
180  // can this vector simply extend the previous one?
181  size_t psize = poly.size();
182  if (psize > 2) // need at least two points already
183  {
184  // find the direction of the vector descrived by the two previous points
185  double ldx = direction(poly[psize - 1].x - poly[psize - 2].x);
186  double ldy = direction(poly[psize - 1].y - poly[psize - 2].y);
187 
188  // find the direction of the vector described by the new point and the
189  // previous point
190  double ndx = direction(pt.x - poly[psize - 1].x);
191  double ndy = direction(pt.y - poly[psize - 1].y);
192 
193  // if the direction is the same, we can replace the
194  // previous point with this one, rather than adding a
195  // new point
196  if (ldx == ndx && ldy == ndy)
197  poly[psize - 1] = pt;
198  else
199  poly.push_back(pt);
200  } else
201  poly.push_back(pt);
202 
203  point_t next = seedit->second;
204  mmap.erase(seedit);
205 
206  seedit = mmap.find(next);
207  }
208 
209  polys.push_back(poly);
210  }
211 
212  if (img)
213  img->release(); // frees all resources for this image
214  return 0; // ok
215 }
216 
217 // POINTS -----------------------------------------------------------
218 
220 {
221  point_t *pts = new point_t[4];
222 
223  pts[0].x = 0;
224  pts[0].y = 0;
225  pts[1].x = 1;
226  pts[1].y = 0;
227  pts[2].x = 1;
228  pts[2].y = 1;
229  pts[3].x = 0;
230  pts[3].y = 1;
231 
232  return pts;
233 }
234 
235 // return a value based on val, but limited minval <= val >= maxval
236 double Stg::constrain(double val, const double minval, const double maxval)
237 {
238  if (val < minval)
239  return minval;
240  if (val > maxval)
241  return maxval;
242  return val;
243 }
The Stage library uses its own namespace.
Definition: canvas.hh:8
static const Color red
Definition: stage.hh:233
static std::vector< std::string > args
Definition: stage.hh:775
bool InitDone()
Definition: stage.cc:40
static const Color magenta
Definition: stage.hh:233
void Init(int *argc, char **argv[])
Definition: stage.cc:17
static const Color blue
Definition: stage.hh:233
double direction(double a)
Definition: stage.cc:78
const char * Version()
Definition: stage.cc:12
void RegisterModels()
Definition: typetable.cc:16
static bool pixel_is_set(uint8_t *pixels, const unsigned int width, const unsigned int depth, const unsigned int x, const unsigned int y, uint8_t threshold)
Definition: stage.cc:72
static int argc
meters_t y
Definition: stage.hh:446
meters_t x
Definition: stage.hh:446
static const Color cyan
Definition: stage.hh:233
int polys_from_image_file(const std::string &filename, std::vector< std::vector< point_t > > &polys)
rotated rectangle
Definition: stage.cc:86
#define PRINT_WARN(m)
Definition: stage.hh:603
static char * argv
double constrain(double val, double minval, double maxval)
return val, or minval if val < minval, or maxval if val > maxval
Definition: stage.cc:236
static const Color green
Definition: stage.hh:233
static const Color yellow
Definition: stage.hh:233
#define FOR_EACH(I, C)
Definition: stage.hh:580
#define PRINT_DEBUG(m)
Definition: stage.hh:644
static bool init_called
Definition: stage.cc:10
point_t * unit_square_points_create()
Definition: stage.cc:219
int sgn(int a)
Definition: stage.hh:173


stage
Author(s): Richard Vaughan , Brian Gerkey , Reed Hedges , Andrew Howard , Toby Collett , Pooya Karimian , Jeremy Asher , Alex Couture-Beil , Geoff Biggs , Rich Mattes , Abbas Sadat
autogenerated on Mon Feb 28 2022 23:48:56