1 // Copyright 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "../ale_pos.h"
29 #include "../config.h"
59 gettimeofday(&tv
, NULL
);
69 gettimeofday(&t
, NULL
);
71 t
.tv_sec
-= tv
.tv_sec
;
72 t
.tv_usec
-= tv
.tv_usec
;
74 total
+= t
.tv_sec
+ ((double) 1 / (double) 1000000) * t
.tv_usec
;
76 time_t t
= time(NULL
);
89 * User interface messages.
107 static int output_performance_data
;
126 * Incremental rendering.
129 LOAD_FILE
, EXPOSURE_PASS_1
,
130 LODCLUSTER_CREATE
, PREMATCH
, ALIGN
, POSTMATCH
,
131 EXPOSURE_PASS_2
, RENDERA
, RENDERD
, RENDERO
, WRITED
,
132 WRITEO
, FRAME_DONE
, SET_DONE
,
135 * Irani-Peleg rendering.
138 IP_RENDER
, IP_STEP_DONE
, IP_UPDATE
, IP_WRITE
,
144 D3_CONTROL_POINT_SOLVE
, D3_SUBDIVIDING_SPACE
,
145 D3_UPDATING_OCCUPANCY
, D3_RENDER
147 } code
, orender_current
;
154 double exp_multiplier
[3];
158 unsigned int frame_num
;
159 unsigned int irani_peleg_stage
;
160 unsigned int secondary_frame_num
;
161 unsigned int view_num
;
162 unsigned int x_coordinate
, y_coordinate
;;
163 unsigned int filtering
, focusing
;
164 unsigned int space_num
;
165 unsigned int total_spaces
;
166 double cp_max_perturb
;
167 double cp_min_perturb
;
168 double cp_cur_perturb
;
175 for (int k
= 0; k
< 3; k
++)
176 exp_multiplier
[k
] = 1;
184 ale_timer_t d2_align_sample
;
185 ale_timer_t d2_align_sim
;
186 ale_timer_t d2_incremental
;
187 ale_timer_t d2_irani_peleg
;
188 std::map
<double,ale_timer_t
> perturb_timers
;
202 virtual void printf(char *format
, ...) = 0;
208 virtual void update() = 0;
211 * Match format strings for textual UIs.
214 char *format_string_ok() {
215 return " okay (%9.6f%% match)";
217 char *format_string_no_match() {
218 return " no match (%9.6f%% match)";
220 char *format_string_working() {
221 return " (%9.6f%% match)";
227 * Handle options and other user input.
230 static void handle_input(int argc
, const char *argv
[], const char *package
,
231 const char *short_version
, const char *version
);
235 static void set_stream() {
236 assert(singleton
== NULL
);
240 static void set_tty() {
241 assert(singleton
== NULL
);
245 static void set_profile() {
246 output_performance_data
= 1;
250 * Messages from the engine
253 void d2_align_sim_start() {
254 d2_align_sim
.start();
257 void d2_align_sim_stop() {
261 void d2_align_sample_start() {
262 d2_align_sample
.start();
265 void d2_align_sample_stop() {
266 d2_align_sample
.stop();
269 void d2_incremental_start() {
270 d2_incremental
.start();
273 void d2_incremental_stop() {
274 d2_incremental
.stop();
277 void d2_irani_peleg_start() {
278 d2_irani_peleg
.start();
281 void d2_irani_peleg_stop() {
282 d2_irani_peleg
.stop();
285 void exp_multiplier(double m0
, double m1
, double m2
) {
286 status
.exp_multiplier
[0] = m0
;
287 status
.exp_multiplier
[1] = m1
;
288 status
.exp_multiplier
[2] = m2
;
291 void exp_multiplier(double mult
[3]) {
292 for (int k
= 0; k
< 3; k
++)
293 status
.exp_multiplier
[k
] = mult
[k
];
296 void set_steps(int count
) {
297 status
.steps
= count
;
300 void set_steps_completed(int count
) {
301 status
.steps_completed
= count
;
304 void set_match(double match
) {
305 status
.match_value
= (1 - match
) * 100;
309 void loading_file() {
310 status
.code
= status
.LOAD_FILE
;
315 status
.code
= status
.EXPOSURE_PASS_1
;
320 status
.code
= status
.EXPOSURE_PASS_2
;
325 status
.code
= status
.PREMATCH
;
329 void postmatching() {
330 status
.code
= status
.POSTMATCH
;
334 void constructing_lod_clusters(ale_pos lod
) {
335 status
.code
= status
.LODCLUSTER_CREATE
;
336 status
.align_lod
= lod
;
340 void aligning(ale_pos perturb
, ale_pos lod
) {
341 perturb_timers
[perturb
].start();
342 status
.perturb_size
= perturb
;
343 status
.align_lod
= lod
;
344 status
.code
= status
.ALIGN
;
348 void set_orender_current(int num
) {
351 status
.orender_current
= status
.RENDERD
;
353 status
.orender_current
= status
.RENDERO
;
356 void set_arender_current() {
357 status
.arender_current
= 1;
360 void clear_arender_current() {
361 status
.arender_current
= 0;
366 * Current alignment rendering tasks must complete
367 * before any current output rendering tasks can
370 if (status
.arender_current
) {
371 status
.code
= status
.RENDERA
;
372 status
.arender_current
= 0;
374 status
.code
= status
.orender_current
;
379 void writing_output(int num
) {
382 status
.code
= status
.WRITED
;
384 status
.code
= status
.WRITEO
;
388 void d3_control_point_data(double max_perturbation
, double min_perturbation
, double cur_perturbation
,
389 double current_error
) {
390 status
.cp_max_perturb
= max_perturbation
;
391 status
.cp_min_perturb
= min_perturbation
;
392 status
.cp_cur_perturb
= cur_perturbation
;
393 status
.cp_cur_error
= current_error
;
397 void d3_control_point_step() {
402 void d3_subdivision_status(unsigned int primary_frame
, unsigned int secondary_frame
,
403 unsigned int i
, unsigned int j
) {
404 status
.code
= status
.D3_SUBDIVIDING_SPACE
;
405 status
.frame_num
= primary_frame
;
406 status
.secondary_frame_num
= secondary_frame
;
407 status
.y_coordinate
= i
;
408 status
.x_coordinate
= j
;
413 void d3_total_spaces(int total_spaces
) {
414 status
.total_spaces
= total_spaces
;
417 void d3_increment_spaces() {
418 status
.total_spaces
++;
421 void d3_occupancy_status(int frame
) {
422 status
.code
= status
.D3_UPDATING_OCCUPANCY
;
423 status
.frame_num
= frame
;
424 status
.space_num
= 0;
428 void d3_increment_space_num() {
433 void d3_render_status(int filter
, int focus
, int frame
, int view
, int i
, int j
, int space
) {
434 status
.code
= status
.D3_RENDER
;
436 status
.filtering
= filter
;
437 status
.focusing
= focus
;
439 status
.frame_num
= frame
;
440 status
.view_num
= view
;
441 status
.y_coordinate
= i
;
442 status
.x_coordinate
= j
;
444 status
.space_num
= space
;
451 * Informational output
455 printf("Iterating Irani-Peleg");
458 void ip_frame_start(unsigned int num
) {
459 status
.code
= status
.IP_RENDER
;
460 status
.frame_num
= num
;
461 status
.irani_peleg_stage
= 0;
464 void ip_frame_simulate_start() {
465 status
.irani_peleg_stage
= 1;
469 void ip_frame_correct_start() {
470 status
.irani_peleg_stage
= 2;
475 status
.code
= status
.IP_UPDATE
;
480 status
.code
= status
.IP_WRITE
;
484 void ip_step_done() {
485 status
.code
= status
.IP_STEP_DONE
;
493 void original_frame_start(const char *name
) {
494 status
.code
= status
.UNDEFINED
;
495 printf("Original Frame:\n");
496 printf(" '%s'", name
);
499 void original_frame_done() {
500 status
.code
= status
.FRAME_DONE
;
504 void supplemental_frame_start(const char *name
) {
505 static int section_announced
= 0;
507 if (!section_announced
) {
508 printf("Supplemental Frames:\n");
509 section_announced
= 1;
512 status
.code
= status
.UNDEFINED
;
513 status
.steps_completed
= 0;
514 printf(" '%s'", name
);
517 void supplemental_frame_done() {
518 status
.code
= status
.FRAME_DONE
;
522 void alignment_monte_carlo_parameter(ale_pos mc
) {
523 status
.mc
= (mc
> 1) ? 1 : mc
;
526 void alignment_perturbation_level(ale_pos perturb
, ale_pos lod
) {
527 perturb_timers
[status
.perturb_size
].stop();
528 perturb_timers
[perturb
].start();
529 status
.perturb_size
= perturb
;
530 status
.align_lod
= lod
;
531 status
.steps_completed
++;
535 void alignment_match_ok() {
536 status
.code
= status
.UNDEFINED
;
537 printf(format_string_ok(), status
.match_value
);
540 void alignment_no_match() {
541 status
.code
= status
.UNDEFINED
;
542 printf(format_string_no_match(), status
.match_value
);
545 void ale_2d_done(double value
) {
546 status
.code
= status
.UNDEFINED
;
547 printf("Average match: %f%%", value
);
548 status
.code
= status
.SET_DONE
;
550 if (output_performance_data
) {
552 printf("Real time measurements\n");
553 printf("======================\n");
555 printf("Alignment (sampling) : %f s\n", d2_align_sample
.get_total());
556 printf("Alignment (checking) : %f s\n", d2_align_sim
.get_total());
557 printf("Incremental rendering : %f s\n", d2_incremental
.get_total());
558 printf("Irani-Peleg rendering : %f s\n", d2_irani_peleg
.get_total());
561 printf("Details (local alignment)\n");
562 printf("-------------------------\n");
564 int have_details
= 0;
565 for (std::map
<double,ale_timer_t
>::iterator i
= perturb_timers
.begin();
566 i
!= perturb_timers
.end(); i
++) {
567 if (i
->second
.get_total() == 0.0
568 && i
== perturb_timers
.begin())
571 printf("Alignment (perturb %f): %f s\n",
572 i
->first
, i
->second
.get_total());
578 printf("No local alignment performed.\n");
586 status
.code
= status
.UNDEFINED
;
587 printf("Rendering 3D");
591 void d3_control_point_solve() {
592 status
.code
= status
.D3_CONTROL_POINT_SOLVE
;
596 void d3_init_view_angle(double angle
) {
597 status
.code
= status
.UNDEFINED
;
601 void d3_final_view_angle(double angle
) {
602 status
.code
= status
.UNDEFINED
;
606 void d3_control_point_solve_done() {
607 status
.code
= status
.UNDEFINED
;
611 void d3_subdividing_space() {
612 status
.code
= status
.D3_SUBDIVIDING_SPACE
;
616 void d3_subdividing_space_done() {
617 status
.code
= status
.UNDEFINED
;
621 void d3_updating_occupancy() {
622 status
.code
= status
.D3_UPDATING_OCCUPANCY
;
626 void d3_updating_occupancy_done() {
627 status
.code
= status
.UNDEFINED
;
631 void d3_writing_output(const char *name
) {
632 static int section_announced
= 0;
634 if (!section_announced
) {
636 section_announced
= 1;
639 printf(" '%s'", name
);
644 void d3_writing_output_done() {
645 status
.code
= status
.UNDEFINED
;
654 void warn(const char *string
) {
655 printf("\n\n*** Warning: %s. ***\n\n\n");
662 void exec_failure(const char *exec
, const char *arg1
, const char *arg2
) {
663 printf("\n\n*** An error occurred while running `%s %s %s`. ***\n\n\n", exec
, arg1
, arg2
);
667 void fork_failure(const char *location
) {
668 printf("\n\n*** Could not fork in %s. ***\n\n\n", location
);
672 void memory_error(const char *purpose
) {
673 printf("Unable to allocate memory for %s.\n", purpose
);
677 void memory_error_location(const char *location
) {
678 printf("Unable to allocate memory in %s.\n", location
);
682 void cli_not_enough(const char *option
) {
683 printf("\n\n*** Not enough arguments for `%s' ***\n\n", option
);
687 void cli_bad_arg(const char *option
) {
688 printf("\n\n*** Bad argument to `%s' ***\n\n", option
);
692 void error(const char *string
) {
693 printf("\n\n*** Error: %s. ***\n\n\n", string
);
697 void illegal_option(const char *string
) {
698 printf("\n\n*** Error: illegal option %s ***\n\n", string
);
702 void unknown_device(const char *string
) {
703 printf("\n\n*** Error: unknown device %s ***\n\n", string
);
707 void error_hint(const char *error
, const char *hint
) {
708 printf("\n\n*** Error: %s", error
);
709 printf( "\n*** Hint: %s\n\n\n", hint
);