ALMaSS Rabbit ODdox  1.1
The rabbit model description following ODdox protocol
hedgebanks.cpp
Go to the documentation of this file.
1 //
2 // hedgebanks.cpp
3 //
4 // This file implements the methods in the Landscape class needed for
5 // adding artificial hedgebanks.
6 
7 /*
8 *******************************************************************************************************
9 Copyright (c) 2011, Christopher John Topping, University of Aarhus
10 All rights reserved.
11 
12 Redistribution and use in source and binary forms, with or without modification, are permitted provided
13 that the following conditions are met:
14 
15 Redistributions of source code must retain the above copyright notice, this list of conditions and the
16 following disclaimer.
17 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
18 the following disclaimer in the documentation and/or other materials provided with the distribution.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
23 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 ********************************************************************************************************
29 */
30 
31 #define _CRT_SECURE_NO_DEPRECATE
32 
33 #include "ls.h"
34 #include "map_cfg.h"
35 #include <math.h>
36 
37 
38 #define HB_MAGIC 1000
39 #define HB_MAGIC_COLOR 999
40 #define HB_MAGIC_PAINTER_BIT 0x40000000
41 
42 // As a fraction.
43 static CfgFloat l_map_art_hb_width( "MAP_ART_HB_WIDTH",
44  CFG_CUSTOM, 0.3 );
45 static CfgFloat l_map_art_hb_seg_len("MAP_ART_HB_SEG_LEN",
46  CFG_CUSTOM, 100.0 );
47 static CfgInt l_map_art_hb_nums( "MAP_ART_HB_NUMS",
48  CFG_CUSTOM, 3 );
49 static CfgInt l_map_art_hb_tran_prob( "MAP_ART_HB_TRAN_PROB",
50  CFG_CUSTOM, 30 );
51 // As a fraction.
52 static CfgFloat l_map_art_hb_core_thres("MAP_ART_HB_STRIPE_THRES",
53  CFG_CUSTOM, 0.4 );
54 
55 
56 void Landscape::hb_Add( void )
57 {
58  // Make a local copy of the actual map parameters for speed
59  // purposes. We are going to use these *a lot*.
60  hb_map = m_land->GetMagicP( 0, 0 );
64 
65  //#ifdef HB_TESTING
66  //m_elems[m_polymapping
67  //[hb_map[750 + 600*hb_width]]]->SetElementType( tole_Hedges );
68  //#endif
69 
70  // Generate a list of polygon numbers + HB_MAGIC for all hedge elements
71  // in our current map.
72  hb_FindHedges();
73 
74  // As one lemming at the cliff edge said to the other: "Let's Go!"
75 
76  // For every hedge polygon:
77  printf("Hedges: %d\n", int(hb_hedges.size()));
78  fflush(stdout);
79 
80  double l_inc = 50.0/((double)hb_hedges.size());
81  double l_count = 0.001;
82 
83  for ( unsigned int i=0; i<hb_hedges.size(); i++ ) {
84  l_count += l_inc;
85  if ( l_count > 1.0 ) {
86  l_count = 0.001;
87  printf(".");
88  fflush(stdout);
89  }
90  // Find the enclosing bounding box for our current polygon.
91  if ( ! hb_FindBoundingBox( hb_hedges[i] )) {
92  // Might want to raise a runtime error upon ending here.
93  // The test for hb_FindBoundingBox() fails if we have a polygon
94  // without any pixels in the main map!
95  continue;
96  }
97 
98  // Move all polygon numbers in our bounding box up! by HB_MAGIC
99  // to make room for our 'paint' values in the space below.
101 
103 
104  hb_PaintBorder( 0 );
105 
106  int l_color = 0;
107  while ( hb_PaintWhoHasNeighbourColor( l_color,
108  l_color + 1 )) {
109  l_color++;
110  }
111 
112  double l_percent = (double)hb_core_pixels/
113  ((double)hb_core_pixels+(double)hb_border_pixels);
114 
115  if ( l_percent > l_map_art_hb_core_thres.value()) {
116  // We ought to have at least *some* visible core area
117  // within the polygon, so do a simple scan.
118 
119  // l_color now happens to contain the maximum contour/color value
120  // within our current polygon.
121  int l_min = (int)((double)l_color * l_map_art_hb_width.value());
122  while ( l_color > l_min ) {
123  hb_MarkTopFromLocalMax( l_color );
125  l_color--;
126  }
127  } else {
128  // Very thin hedge (1->2 meters),
129  // use special border case scan when adding hedge banks.
131  }
132 
134 
135  // All the previous steps were just preparations.
136  // Now do the serious stuff.
138 
139 #ifdef HB_TESTING
140  // Sanity check.
141  for ( int j=0; j<hb_size; j++ ) {
142  if ( m_polymapping[ hb_map[ j ] - HB_MAGIC ] == -1 ) {
143  printf("Oh dear!\n");
144  exit(1);
145  }
146  }
147 
148  char ffname[24];
149  sprintf( ffname, "test%02d.ppm", i);
150 #endif
151 
152  // Restore order to the map before continuing.
154 
155 #ifdef HB_TESTING
156  hb_dump_map( 0, hb_width, 0, hb_height, ffname, false );
157 #endif
158  }
159 
160  printf("\n");
161 #ifdef HB_TESTING
162  // Quick reminder.
163  for ( unsigned int i=0; i<m_elems.size(); i++ ) {
164  if ( m_elems[i]->GetArea() < 0.9 &&
165  m_elems[i]->GetElementType() != tole_FieldBoundary ) {
166  // Note: Field boundaries have not been scanned yet at this point,
167  // so they will have a zero area right here and now.
168  printf("Warning: Polygon %6d of type %s came up with area %3.2f!\n",
169  m_elems[i]->GetPoly(),
170  PolytypeToString( m_elems[i]->GetElementType() ),
171  m_elems[i]->GetArea() );
172  }
173  }
174  exit(0);
175 #endif
176 }
177 
178 
179 
181 {
182  hb_new_hbs.resize( l_map_art_hb_nums.value() );
183 
184  for ( int i =0; i<l_map_art_hb_nums.value(); i++ ) {
186  hb_new_hbs[ i ]->SetArea( 0.0 );
187  hb_new_hbs[ i ]->SetSubType( i );
188  m_elems.resize( m_elems.size() + 1 );
189  m_elems[ m_elems.size() - 1 ] = hb_new_hbs[ i ];
191  (int) m_elems.size() - 1;
192  hb_new_hbs[ i ]->SetPoly( hb_first_free_poly_num++ );
193  }
194 }
195 
196 
197 
198 void Landscape::hb_AddNewHedgebanks( int /* a_orig_poly_num */ )
199 {
201 
202  for ( int l_y=hb_min_y; l_y<=hb_max_y; l_y++ ) {
203  for ( int l_x=hb_min_x; l_x<=hb_max_x; l_x++ ) {
204  int i = l_y*hb_width + l_x;
205  int l_val = hb_map[ i ];
206  if ( l_val >= 0 && l_val < HB_MAGIC ) {
207  hb_map[ i ] = hb_StripingDist() + HB_MAGIC;
208  /*
209  m_elems[m_polymapping[hb_map[ i ]-HB_MAGIC]]->AddArea( 1.0 );
210  m_elems[m_polymapping[hb_map[ i ]-HB_MAGIC]]->m_squares_in_map++;
211  m_elems[m_polymapping[a_orig_poly_num]]->AddArea( -1.0 );
212  if ( m_elems[m_polymapping[a_orig_poly_num]]->GetArea() < 0.0 ) {
213  printf("%d %d !!!\n", l_x, l_y );
214  exit(1);
215  }
216  */
217  //m_elems[m_polymapping[a_orig_poly_num]]->m_squares_in_map--;
218  }
219  }
220  }
221 }
222 
223 
224 
226 {
227  // Striping distribution function for the new hedgebanks.
228  static LE* l_curr_ele = NULL;
229 
230  if ( !l_curr_ele ) {
231  l_curr_ele = hb_new_hbs[ random( l_map_art_hb_nums.value()) ];
232  return l_curr_ele->GetPoly();
233  }
234 
235  if ( random(100) < l_map_art_hb_tran_prob.value() )
236  l_curr_ele = hb_new_hbs[ random( l_map_art_hb_nums.value()) ];
237 
238  return l_curr_ele->GetPoly();
239 }
240 
241 
242 
243 bool Landscape::hb_FindBoundingBox( int a_poly_num )
244 {
245  hb_min_x = hb_width + 1;
246  hb_max_x = -1;
247 
248  hb_min_y = hb_height + 1;
249  hb_max_y = -1;
250 
251  bool l_found = false;
252 
253  // Search for every pixel which belongs to the current polygon, and
254  // min and max values for x and y. Values are inclusive.
255  for ( int l_y=0; l_y<hb_height; l_y++ ) {
256  for ( int l_x=0; l_x<hb_width; l_x++ ) {
257  if ( hb_map[ l_y*hb_width + l_x ] == a_poly_num ) {
258  l_found = true;
259  if ( l_x < hb_min_x)
260  hb_min_x = l_x;
261  else if ( l_x > hb_max_x)
262  hb_max_x = l_x;
263  if ( l_y < hb_min_y)
264  hb_min_y = l_y;
265  else if ( l_y > hb_max_y)
266  hb_max_y = l_y;
267  }
268  }
269  }
270 
271  return l_found;
272 }
273 
274 
275 
277 {
278  for ( unsigned int i=0; i<m_elems.size(); i++ ) {
279  if ( tole_Hedges == m_elems[i]->GetElementType() ) {
280  hb_hedges.resize( hb_hedges.size() + 1 );
281  hb_hedges[ hb_hedges.size() - 1 ] =
282  m_elems[i]->GetPoly();
283  }
284  }
285 }
286 
287 
288 
290 {
291  for ( int i=0; i<hb_size; i++ ) {
292  hb_map[ i ] += HB_MAGIC;
293  }
294 }
295 
296 
297 
299 {
300  for ( int l_y=hb_min_y; l_y<=hb_max_y; l_y++ ) {
301  for ( int l_x=hb_min_x; l_x<=hb_max_x; l_x++ ) {
302  int l_coord = l_y*hb_width + l_x;
303  if ( hb_map[l_coord] < 0 )
304  hb_map[l_coord] |= HB_MAGIC_PAINTER_BIT;
305  }
306  }
307 }
308 
309 
310 
311 void Landscape::hb_RestoreHedgeCore( int a_orig_poly_number )
312 {
313  for ( int l_y=hb_min_y; l_y<=hb_max_y; l_y++ ) {
314  for ( int l_x=hb_min_x; l_x<=hb_max_x; l_x++ ) {
315  int l_coord = l_y*hb_width + l_x;
316  if ( hb_map[l_coord] < 0 ) {
317  hb_map[l_coord] = a_orig_poly_number;
318  }
319  }
320  }
321 }
322 
323 
324 
325 inline bool Landscape::hb_MapBorder(int a_x, int a_y )
326 {
327  if ( a_x < 0 ||
328  a_y < 0 ||
329  a_x >= hb_width ||
330  a_y >= hb_height ) {
331  return true;
332  }
333 
334  return false;
335 }
336 
337 
338 
339 inline bool Landscape::hb_HasOtherNeighbour( int a_x, int a_y )
340 {
341  bool l_has_neighbour = false;
342  bool loop=false;
343 
344  // Who said C++ needs the goto statement? ;-)
345  do {
346  a_x -= 1;
347  a_y -= 1;
348 
349  if ( hb_MapBorder( a_x, a_y ) ||
350  hb_map[ a_x + a_y*hb_width ] >= HB_MAGIC ) {
351  l_has_neighbour = true;
352  break;
353  }
354 
355  a_x++;
356  if ( hb_MapBorder( a_x, a_y ) ||
357  hb_map[ a_x + a_y*hb_width ] >= HB_MAGIC ) {
358  l_has_neighbour = true;
359  break;
360  }
361 
362  a_x++;
363  if ( hb_MapBorder( a_x, a_y ) ||
364  hb_map[ a_x + a_y*hb_width ] >= HB_MAGIC ) {
365  l_has_neighbour = true;
366  break;
367  }
368 
369  a_x -= 2;
370  a_y += 1;
371  if ( hb_MapBorder( a_x, a_y ) ||
372  hb_map[ a_x + a_y*hb_width ] >= HB_MAGIC ) {
373  l_has_neighbour = true;
374  break;
375  }
376 
377  a_x += 2;
378  if ( hb_MapBorder( a_x, a_y ) ||
379  hb_map[ a_x + a_y*hb_width ] >= HB_MAGIC ) {
380  l_has_neighbour = true;
381  break;
382  }
383 
384  a_x -= 2;
385  a_y += 1;
386 
387  if ( hb_MapBorder( a_x, a_y ) ||
388  hb_map[ a_x + a_y*hb_width ] >= HB_MAGIC ) {
389  l_has_neighbour = true;
390  break;
391  }
392 
393  a_x++;
394  if ( hb_MapBorder( a_x, a_y ) ||
395  hb_map[ a_x + a_y*hb_width ] >= HB_MAGIC ) {
396  l_has_neighbour = true;
397  break;
398  }
399 
400  a_x++;
401  if ( hb_MapBorder( a_x, a_y ) ||
402  hb_map[ a_x + a_y*hb_width ] >= HB_MAGIC ) {
403  l_has_neighbour = true;
404  break;
405  }
406  } while ( loop ); // was while (false) CJT 16-05-06
407 
408  return l_has_neighbour;
409 }
410 
411 
412 
413 void Landscape::hb_ClearPolygon( int a_poly_num )
414 {
415  // 'Paint' every pixel which belongs to the current polygon with the
416  // value HB_MAGIC_COLOR.
417  for ( int l_y=hb_min_y; l_y<=hb_max_y; l_y++ ) {
418  for ( int l_x=hb_min_x; l_x<=hb_max_x; l_x++ ) {
419  int l_coord = l_y*hb_width + l_x;
420  if ( hb_map[ l_coord ] == a_poly_num ) {
421  hb_map[ l_coord ] = HB_MAGIC_COLOR;
422  }
423  }
424  }
425 }
426 
427 
428 
429 void Landscape::hb_PaintBorder( int a_color )
430 {
431  hb_border_pixels = 0;
432  hb_core_pixels = 0;
433  // Paint every pixel which belongs to the current polygon, and which
434  // does have a neighbour *not* equal to HB_MAGIC_COLOR (our marker value).
435  for ( int l_y=hb_min_y; l_y<=hb_max_y; l_y++ ) {
436  for ( int l_x=hb_min_x; l_x<=hb_max_x; l_x++ ) {
437  int l_coord = l_y*hb_width + l_x;
438  if ( hb_map[ l_coord ] == HB_MAGIC_COLOR ) {
439  if ( hb_HasOtherNeighbour( l_x, l_y )) {
440  hb_map[ l_coord ] = a_color;
442  } else {
443  hb_core_pixels++;
444  }
445  }
446  }
447  }
448 }
449 
450 
451 
452 inline bool Landscape::hb_HasNeighbourColor( int a_x, int a_y,
453  int a_neighbour_color )
454 {
455  bool l_neighbour_has_color = false;
456  bool loop=false;
457 
458  do {
459  a_x -= 1;
460  a_y -= 1;
461  if ( a_x >= 0 && a_y >= 0 &&
462  hb_map[ a_x + a_y*hb_width ] == a_neighbour_color ) {
463  l_neighbour_has_color = true;
464  break;
465  }
466 
467  a_x++;
468  if ( hb_map[ a_x + a_y*hb_width ] == a_neighbour_color ) {
469  l_neighbour_has_color = true;
470  break;
471  }
472 
473  a_x++;
474  if ( a_x < hb_width &&
475  hb_map[ a_x + a_y*hb_width ] == a_neighbour_color ) {
476  l_neighbour_has_color = true;
477  break;
478  }
479 
480  a_x -= 2;
481  a_y += 1;
482  if ( a_x >= 0 &&
483  hb_map[ a_x + a_y*hb_width ] == a_neighbour_color ) {
484  l_neighbour_has_color = true;
485  break;
486  }
487 
488  a_x += 2;
489  if ( a_x < hb_width &&
490  hb_map[ a_x + a_y*hb_width ] == a_neighbour_color ) {
491  l_neighbour_has_color = true;
492  break;
493  }
494 
495  a_x -= 2;
496  a_y += 1;
497 
498  if ( a_y >= hb_height )
499  break;
500 
501  if ( a_x >= 0 &&
502  hb_map[ a_x + a_y*hb_width ] == a_neighbour_color ) {
503  l_neighbour_has_color = true;
504  break;
505  }
506 
507  a_x++;
508  if ( hb_map[ a_x + a_y*hb_width ] == a_neighbour_color ) {
509  l_neighbour_has_color = true;
510  break;
511  }
512 
513  a_x++;
514  if ( a_x < hb_width &&
515  hb_map[ a_x + a_y*hb_width ] == a_neighbour_color ) {
516  l_neighbour_has_color = true;
517  break;
518  }
519  } while ( loop ); // was while (false) CJT 16-05-06
520 
521  return l_neighbour_has_color;
522 }
523 
524 
525 
526 bool Landscape::hb_PaintWhoHasNeighbourColor( int a_neighbour_color,
527  int a_new_color )
528 {
529  // Paint every pixel which belongs to the current polygon, and which
530  // has a neighbour with a color equal to a_neighbour_color.
531 
532  bool l_at_least_one = false;
533  for ( int l_y=hb_min_y; l_y<=hb_max_y; l_y++ ) {
534  for ( int l_x=hb_min_x; l_x<=hb_max_x; l_x++ ) {
535  if ( hb_map[l_y*hb_width + l_x] == HB_MAGIC_COLOR &&
536  hb_HasNeighbourColor( l_x, l_y, a_neighbour_color )) {
537  hb_map[l_y*hb_width + l_x] = a_new_color;
538  l_at_least_one = true;
539  }
540  }
541  }
542 
543  return l_at_least_one;
544 }
545 
546 
547 
549  int a_y )
550 {
551  int l_max_neg = 0;
552  int l_val;
553  bool loop=false; // This is just to avoid the warning about constant expression if we use: do {...} while (false)
554 
555  do {
556  a_x -= 1;
557  a_y -= 1;
558  if ( a_x >= 0 && a_y >= 0 ) {
559  l_val = hb_map[ a_x + a_y*hb_width ];
560  if ( l_val < l_max_neg && (l_val & HB_MAGIC_PAINTER_BIT)) {
561  l_max_neg = l_val;
562  }
563  }
564 
565  a_x++;
566  l_val = hb_map[ a_x + a_y*hb_width ];
567  if ( l_val < l_max_neg && (l_val & HB_MAGIC_PAINTER_BIT)) {
568  l_max_neg = l_val;
569  }
570 
571  a_x++;
572  if ( a_x < hb_width ) {
573  l_val = hb_map[ a_x + a_y*hb_width ];
574  if ( l_val < l_max_neg && (l_val & HB_MAGIC_PAINTER_BIT)) {
575  l_max_neg = l_val;
576  }
577  }
578 
579  a_x -= 2;
580  a_y += 1;
581  if ( a_x >= 0 ) {
582  l_val = hb_map[ a_x + a_y*hb_width ];
583  if ( l_val < l_max_neg && (l_val & HB_MAGIC_PAINTER_BIT)) {
584  l_max_neg = l_val;
585  }
586  }
587 
588  a_x += 2;
589  if ( a_x < hb_width ) {
590  l_val = hb_map[ a_x + a_y*hb_width ];
591  if ( l_val < l_max_neg && (l_val & HB_MAGIC_PAINTER_BIT)) {
592  l_max_neg = l_val;
593  }
594  }
595 
596  a_x -= 2;
597  a_y += 1;
598 
599  if ( a_y >= hb_height )
600  break;
601 
602  if ( a_x >= 0 ) {
603  l_val = hb_map[ a_x + a_y*hb_width ];
604  if ( l_val < l_max_neg && (l_val & HB_MAGIC_PAINTER_BIT)) {
605  l_max_neg = l_val;
606  }
607  }
608 
609  a_x++;
610  l_val = hb_map[ a_x + a_y*hb_width ];
611  if ( l_val < l_max_neg && (l_val & HB_MAGIC_PAINTER_BIT)) {
612  l_max_neg = l_val;
613  }
614 
615  a_x++;
616  if ( a_x < hb_width ) {
617  l_val = hb_map[ a_x + a_y*hb_width ];
618  if ( l_val < l_max_neg && (l_val & HB_MAGIC_PAINTER_BIT)) {
619  l_max_neg = l_val;
620  }
621  }
622  } while ( loop );
623 
624  return l_max_neg;
625 }
626 
627 
628 
630 {
631  double l_hb = l_map_art_hb_width.value()*10000.0;
632  double l_up = 10000.0 - l_hb;
633  bool l_is_hb = true;
634  double l_length = (double)(random( (int)l_hb )) * 0.0001 *
636  double l_hb_remain = 0.0;
637  double l_up_remain = 0.0;
638 
639  for ( int l_y=hb_min_y; l_y<=hb_max_y; l_y++) {
640  // Note: The missing update of l_x below is intentional.
641  for ( int l_x=hb_min_x; l_x<=hb_max_x; ) {
642  int l_coord = l_y*hb_width + l_x;
643  if ( hb_map[ l_coord ] < HB_MAGIC ) {
644  // 'Painting' with a negative value turns a pixel into
645  // hedgebank 'core', ie. hedge!
646 
647  // Paint segment length with appropriate type.
648  if ( l_length >= 1.0 ) {
649  if ( l_is_hb ) {
650  hb_map[ l_coord ] = 0;
651  } else {
652  hb_map[ l_coord ] = -1;
653  }
654  l_length -= 1.0;
655  l_x++;
656  } else {
657  // Change state.
658  if ( l_is_hb ) {
659  l_is_hb = false;
660  l_hb_remain = l_length;
661  l_length = (double)(random( (int)l_up )) * 0.0001 *
662  l_map_art_hb_seg_len.value() + l_up_remain;
663  } else {
664  l_is_hb = true;
665  l_up_remain = l_length;
666  l_length = (double)(random( (int)l_hb )) * 0.0001 *
667  l_map_art_hb_seg_len.value() + l_hb_remain;
668  }
669  }
670  } else {
671  // Pixel not part of the hedge, just update the coordinate.
672  l_x++;
673  }
674  }
675  }
676 }
677 
678 
680 {
681  // Sweep through the map. If we find a pixel, which has a value
682  // equal to a_color and *not* a negative neighbour, then mark it as
683  // negative with an absolute value equal to the number of steps from
684  // here and out to the center/perimeter polygons border, calculated
685  // as the given percentage.
686 
687  // If one or more negative numbers are found among the neighbours,
688  // some that were not marked during this round, then assign a
689  // negative value equal to the minimum found plus one.
690 
691  for ( int l_y=hb_min_y; l_y<=hb_max_y; l_y++ ) {
692  for ( int l_x=hb_min_x; l_x<=hb_max_x; l_x++ ) {
693  int l_coord = l_y*hb_width + l_x;
694  int l_max;
695  if ( hb_map[ l_coord ] == a_color ) {
696  l_max = hb_MaxUnpaintedNegNeighbour( l_x, l_y );
697  if ( l_max < 0 ) {
698  if ( ++l_max < 0 ) {
699  hb_map[ l_coord ] = l_max;
700  } else {
701  // l_max was precisely -1
702  hb_map[ l_coord ] = -1;
703  }
704  } else {
705  // We are a local maxima.
706  hb_map[ l_coord ] = -a_color;
707  }
708  hb_map[ l_coord ] ^= HB_MAGIC_PAINTER_BIT;
709  }
710  }
711  }
712 }
713 
714 
716 {
717  for ( int i=0; i<hb_size; i++ ) {
718  if ( hb_map[ i ] >= HB_MAGIC ) {
719  hb_map[ i ] -= HB_MAGIC;
720  }
721  }
722 }
723 
724 
725 #ifdef HB_TESTING
726 
727 #define SV_UINT32 unsigned int
728 #define SV_INT32 int
729 #define SV_UINT8 unsigned char
730 #define SV_INT8 char
731 
732 
733 const unsigned int hb_dump_colors [tole_Foobar] = {
734  0x00AAFFAA, // tole_Hedges
735  0x0011BBCC, // tole_RoadsideVerge, // 13
736  0x0011AAAA, // tole_Railway, // 118
737  0x00339933, // tole_FieldBoundary, // 160
738  0x00AA6666, // tole_Marsh, // 95
739  0x0022AA22, // tole_Scrub, // 70
740  0x00CCCCCC, // tole_Field, //grey
741  0x0099aa99, // tole_PermPastureTussocky, // 26
742  0x00FF3311, // tole_UnsprayedFieldMargin,
743  0x00BBCCBB, // tole_PermanentSetaside, // 33
744  0x00BBFFBB, // tole_PermPasture, // 35
745  0x0099FF99, // tole_NaturalGrassDry, // 110
746  0x0044AA55, // tole_RiversidePlants, // 98
747  0x00558855, // tole_PitDisused, // 75
748  0x0022CC22, // tole_RiversideTrees, // 97
749  0x0022AA22, // tole_DeciduousForest, // 40
750  0x00227722, // tole_MixedForest, // 60
751  0x00225522, // tole_ConiferousForest, // 50
752  0x00223322, // tole_YoungForest, // 55
753  0x00EEEEEE, // tole_StoneWall, // 15
754  0x0088AA88, // tole_Garden, //11
755  0x00448888, // tole_Track, // 123
756  0x00777777, // tole_SmallRoad, // 122
757  0x00444444, // tole_LargeRoad, // 121
758  0x00666666, // tole_Building, // 5
759  0x00888888, // tole_Urban, // 10
760  0x00222222, // tole_ActivePit, // 115
761  0x00DD3333, // tole_Freshwater, // 90
762  0x00FF8888, // tole_River, // 96
763  0x00FF1111, // tole_Saltwater, // 80
764  0x00DD1111, // tole_Coast, // 100
765  0x005555FF, // tole_HedgeBank, // No official number. 140. FN.
766  0x0088FFFF, // tole_Heath,
767  0x000000FF // tole_BareRock
768 };
769 
770 
771 
772 void Landscape::hb_dump_map( int a_beginx, int a_width,
773  int a_beginy, int a_height,
774  char* a_filename,
775  bool a_high_numbers )
776 {
777  SV_UINT32 linesize = a_width*3;
778  SV_UINT8* linebuffer = (SV_UINT8*)malloc(sizeof(SV_UINT8)* linesize);
779 
780  if ( linebuffer == NULL ) {
781  printf("hb_dump_color_map(): Out of memory!\n",
782  "" );
783  exit(1);
784  }
785 
786  FILE* l_file = fopen( a_filename, "w" );
787  if ( ! l_file ) {
788  printf("hb_dump_color_map(): Unable to open file for writing: %s\n",
789  a_filename );
790  exit(1);
791  }
792 
793  fprintf( l_file, "P6\n%d %d %d\n",
794  a_width,
795  a_height,
796  255 );
797 
798  for ( int line=a_beginy; line< a_beginy + a_height; line++ ) {
799  int i = 0;
800  for ( int column=a_beginx; column < a_beginx + a_width; column++ ) {
801  int localcolor = hb_dump_color( column, line, a_high_numbers );
802  linebuffer [ i++ ] = localcolor & 0xff;
803  linebuffer [ i++ ] = (localcolor >> 8) & 0xff;
804  linebuffer [ i++ ] = (localcolor >> 16) & 0xff;
805  }
806  fwrite( linebuffer, sizeof(SV_UINT8), linesize, l_file );
807  }
808 
809  fclose( l_file );
810  free( linebuffer );
811 }
812 
813 
814 inline int Landscape::hb_dump_color( int a_x, int a_y,
815  bool a_high_numbers )
816 {
817  int l_map_val = hb_map[ a_x + a_y*hb_width ];
818 
819  if ( l_map_val < 0 )
820  return 0x000000ff;
821 
822  if ( a_high_numbers && m_polymapping[l_map_val] != -1 )
823  l_map_val -= HB_MAGIC;
824 
825  if ( m_polymapping[l_map_val] != -1 ) {
826  return hb_dump_colors[ m_elems[m_polymapping
827  [l_map_val]]->GetElementType() ];
828  }
829 
830  return 0x00ffffff - 32*l_map_val;
831 }
832 
833 #endif // HB_TESTING
834 
835 
tole_HedgeBank
Definition: tole_declaration.h:68
Landscape::hb_max_x
int hb_max_x
Definition: landscape.h:272
Landscape::hb_width
int hb_width
Definition: landscape.h:269
Landscape::hb_MarkTopFromLocalMax
void hb_MarkTopFromLocalMax(int a_color)
Definition: hedgebanks.cpp:679
l_map_art_hb_tran_prob
static CfgInt l_map_art_hb_tran_prob("MAP_ART_HB_TRAN_PROB", CFG_CUSTOM, 30)
HB_MAGIC_COLOR
#define HB_MAGIC_COLOR
Definition: hedgebanks.cpp:39
Landscape::hb_new_hbs
vector< LE * > hb_new_hbs
Definition: landscape.h:264
Landscape::hb_MapBorder
bool hb_MapBorder(int a_x, int a_y)
Definition: hedgebanks.cpp:325
SV_UINT32
#define SV_UINT32
Definition: pesticide.cpp:668
Landscape::hb_PaintBorder
void hb_PaintBorder(int a_color)
Definition: hedgebanks.cpp:429
RasterMap::MapHeight
int MapHeight(void)
Definition: rastermap.h:53
Landscape::hb_FindBoundingBox
bool hb_FindBoundingBox(int a_poly_num)
Definition: hedgebanks.cpp:243
Landscape::hb_AddNewHedgebanks
void hb_AddNewHedgebanks(int a_orig_poly_num)
Definition: hedgebanks.cpp:198
Landscape::hb_MaxUnpaintedNegNeighbour
int hb_MaxUnpaintedNegNeighbour(int a_x, int a_y)
Definition: hedgebanks.cpp:548
LE::GetPoly
int GetPoly(void)
Returns the polyref number for this polygon.
Definition: elements.h:189
Landscape::hb_core_pixels
int hb_core_pixels
Definition: landscape.h:275
Landscape::hb_DownPolyNumbers
void hb_DownPolyNumbers(void)
Definition: hedgebanks.cpp:715
ls.h
Landscape::m_polymapping
vector< int > m_polymapping
Definition: landscape.h:130
Landscape::hb_FindHedges
void hb_FindHedges(void)
Definition: hedgebanks.cpp:276
Landscape::PolytypeToString
std::string PolytypeToString(TTypesOfLandscapeElement a_le_type)
Definition: Landscape.cpp:4087
SV_UINT8
#define SV_UINT8
Definition: pesticide.cpp:670
RasterMap::GetMagicP
int * GetMagicP(int a_x, int a_y)
Definition: rastermap.h:74
tole_Foobar
Definition: tole_declaration.h:111
HB_MAGIC
#define HB_MAGIC
Definition: hedgebanks.cpp:38
map_cfg.h
l_map_art_hb_width
static CfgFloat l_map_art_hb_width("MAP_ART_HB_WIDTH", CFG_CUSTOM, 0.3)
Landscape::hb_first_free_poly_num
int hb_first_free_poly_num
Definition: landscape.h:274
l_map_art_hb_seg_len
static CfgFloat l_map_art_hb_seg_len("MAP_ART_HB_SEG_LEN", CFG_CUSTOM, 100.0)
Landscape::hb_StripingDist
int hb_StripingDist(void)
Definition: hedgebanks.cpp:225
HB_MAGIC_PAINTER_BIT
#define HB_MAGIC_PAINTER_BIT
Definition: hedgebanks.cpp:40
Landscape::hb_RestoreHedgeCore
void hb_RestoreHedgeCore(int a_orig_poly_number)
Definition: hedgebanks.cpp:311
Landscape::hb_HasNeighbourColor
bool hb_HasNeighbourColor(int a_x, int a_y, int a_neighbour_color)
Definition: hedgebanks.cpp:452
Landscape::hb_PaintWhoHasNeighbourColor
bool hb_PaintWhoHasNeighbourColor(int a_neighbour_color, int a_new_color)
Definition: hedgebanks.cpp:526
Landscape::hb_height
int hb_height
Definition: landscape.h:270
Landscape::hb_UpPolyNumbers
void hb_UpPolyNumbers(void)
Definition: hedgebanks.cpp:289
Landscape::hb_MarkTheBresenhamWay
void hb_MarkTheBresenhamWay(void)
Definition: hedgebanks.cpp:629
Landscape::hb_max_y
int hb_max_y
Definition: landscape.h:273
Landscape::hb_GenerateHBPolys
void hb_GenerateHBPolys(void)
Definition: hedgebanks.cpp:180
Landscape::hb_hedges
vector< int > hb_hedges
Definition: landscape.h:263
CfgFloat::value
double value(void)
Definition: configurator.h:118
Landscape::hb_ClearPolygon
void hb_ClearPolygon(int a_poly_num)
Definition: hedgebanks.cpp:413
Landscape::m_land
RasterMap * m_land
The big map.
Definition: landscape.h:125
Landscape::hb_min_x
int hb_min_x
Definition: landscape.h:272
l_map_art_hb_core_thres
static CfgFloat l_map_art_hb_core_thres("MAP_ART_HB_STRIPE_THRES", CFG_CUSTOM, 0.4)
CFG_CUSTOM
Definition: configurator.h:60
Landscape::hb_size
int hb_size
Definition: landscape.h:271
LE
Definition: elements.h:81
tole_FieldBoundary
Definition: tole_declaration.h:40
Landscape::hb_ResetColorBits
void hb_ResetColorBits(void)
Definition: hedgebanks.cpp:298
CfgInt
Integer configurator entry class.
Definition: configurator.h:87
CfgFloat
Double configurator entry class.
Definition: configurator.h:106
Landscape::hb_border_pixels
int hb_border_pixels
Definition: landscape.h:276
Landscape::NewElement
LE * NewElement(TTypesOfLandscapeElement a_type)
Definition: Landscape.cpp:3688
CfgInt::value
int value(void)
Definition: configurator.h:98
Landscape::hb_map
int * hb_map
Definition: landscape.h:268
tole_Hedges
Definition: tole_declaration.h:37
Landscape::hb_Add
void hb_Add(void)
Definition: hedgebanks.cpp:56
Landscape::hb_min_y
int hb_min_y
Definition: landscape.h:273
l_map_art_hb_nums
static CfgInt l_map_art_hb_nums("MAP_ART_HB_NUMS", CFG_CUSTOM, 3)
RasterMap::MapWidth
int MapWidth(void)
Definition: rastermap.h:52
Landscape::m_elems
vector< LE * > m_elems
List of all landscape elements. The index is a sequential number, to get the polynum look this number...
Definition: landscape.h:122
Landscape::hb_HasOtherNeighbour
bool hb_HasOtherNeighbour(int a_x, int a_y)
Definition: hedgebanks.cpp:339