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 3 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
29 #include "../ale_pos.h"
30 #include "../config.h"
46 typedef trans_multi transformation
;
47 struct trans_abstract
;
67 gettimeofday(&tv
, NULL
);
77 gettimeofday(&t
, NULL
);
79 t
.tv_sec
-= tv
.tv_sec
;
80 t
.tv_usec
-= tv
.tv_usec
;
82 total
+= t
.tv_sec
+ ((double) 1 / (double) 1000000) * t
.tv_usec
;
84 time_t t
= time(NULL
);
97 * User interface messages.
104 static ui
*singleton
;
117 static int output_performance_data
;
136 * Incremental rendering.
139 LOAD_FILE
, EXPOSURE_PASS_1
,
140 LODCLUSTER_CREATE
, PREMATCH
, ALIGN
, GLOBAL_ALIGN
, POSTMATCH
,
141 EXPOSURE_PASS_2
, RENDERA
, RENDERD
, RENDERO
, WRITED
,
142 WRITEO
, FRAME_DONE
, SET_DONE
, MULTI
,
145 * Irani-Peleg rendering.
148 IP_RENDER
, IP_STEP_DONE
, IP_UPDATE
, IP_WRITE
,
154 D3_CONTROL_POINT_SOLVE
, D3_SUBDIVIDING_SPACE
,
155 D3_UPDATING_OCCUPANCY
, D3_RENDER
157 } code
, orender_current
;
165 double exp_multiplier
[3];
168 unsigned int frame_num
;
169 unsigned int irani_peleg_stage
;
170 unsigned int secondary_frame_num
;
171 unsigned int view_num
;
172 unsigned int x_coordinate
, y_coordinate
;;
173 unsigned int filtering
, focusing
;
174 unsigned int space_num
;
175 unsigned int total_spaces
;
176 double cp_max_perturb
;
177 double cp_min_perturb
;
178 double cp_cur_perturb
;
187 for (int k
= 0; k
< 3; k
++)
188 exp_multiplier
[k
] = 1;
196 ale_timer_t d2_align_sample
;
197 ale_timer_t d2_align_sim
;
198 ale_timer_t d2_incremental
;
199 ale_timer_t d2_irani_peleg
;
200 std::map
<double,ale_timer_t
> perturb_timers
;
214 virtual void printf(const char *format
, ...) = 0;
220 virtual void update() = 0;
223 * Match format strings for textual UIs.
226 const char *format_string_ok() {
227 return " okay (%9.6f%% match)";
229 const char *format_string_no_match() {
230 return " no match (%9.6f%% match)";
232 const char *format_string_working() {
233 return " (%9.6f%% match)";
239 * Handle options and other user input.
242 static void handle_input(int argc
, const char *argv
[], const char *package
,
243 const char *short_version
, const char *version
);
247 static void set_stream() {
248 assert(singleton
== NULL
);
252 static void set_tty() {
253 assert(singleton
== NULL
);
257 static void set_log() {
258 assert (singleton
== NULL
);
262 static void set_quiet() {
263 assert(singleton
== NULL
);
267 static void set_profile() {
268 output_performance_data
= 1;
272 * Messages from the engine
275 virtual void identify_output(const char *name
) {
276 printf("Output file will be '%s'.\n", name
);
279 virtual void d2_align_sim_start() {
280 d2_align_sim
.start();
283 virtual void d2_align_sim_stop() {
287 virtual void d2_align_sample_start() {
288 d2_align_sample
.start();
291 virtual void d2_align_sample_stop() {
292 d2_align_sample
.stop();
295 virtual void d2_incremental_start() {
296 d2_incremental
.start();
299 virtual void d2_incremental_stop() {
300 d2_incremental
.stop();
303 virtual void d2_irani_peleg_start() {
304 d2_irani_peleg
.start();
307 virtual void d2_irani_peleg_stop() {
308 d2_irani_peleg
.stop();
311 virtual void exp_multiplier(double m0
, double m1
, double m2
) {
312 status
.exp_multiplier
[0] = m0
;
313 status
.exp_multiplier
[1] = m1
;
314 status
.exp_multiplier
[2] = m2
;
317 void exp_multiplier(double mult
[3]) {
318 exp_multiplier(mult
[0], mult
[1], mult
[2]);
321 virtual void set_steps(int count
, int type
= 0) {
322 status
.steps
= count
;
323 status
.step_type
= type
;
326 virtual void set_steps_completed(int count
) {
327 status
.steps_completed
= count
;
330 virtual void set_match(double match
) {
331 status
.match_value
= (1 - match
) * 100;
335 virtual void set_offset(d2::trans_single offset
);
336 virtual void set_offset(d2::trans_multi offset
);
338 virtual void gs_mo(ale_pos gs_mo
) {
341 virtual void cache_status(unsigned int c
) {
345 virtual void loading_file() {
346 status
.code
= status
.LOAD_FILE
;
350 virtual void exposure_1() {
351 status
.code
= status
.EXPOSURE_PASS_1
;
355 virtual void exposure_2() {
356 status
.code
= status
.EXPOSURE_PASS_2
;
360 virtual void prematching() {
361 status
.code
= status
.PREMATCH
;
365 virtual void postmatching() {
366 status
.code
= status
.POSTMATCH
;
370 virtual void constructing_lod_clusters(ale_pos lod
) {
371 status
.code
= status
.LODCLUSTER_CREATE
;
372 status
.align_lod
= lod
;
376 virtual void global_alignment(ale_pos perturb
, ale_pos lod
) {
377 status
.perturb_size
= perturb
;
378 status
.align_lod
= lod
;
379 status
.code
= status
.GLOBAL_ALIGN
;
383 virtual void aligning(ale_pos perturb
, ale_pos lod
) {
384 perturb_timers
[perturb
].start();
385 status
.perturb_size
= perturb
;
386 status
.align_lod
= lod
;
387 status
.code
= status
.ALIGN
;
391 virtual void multi() {
392 status
.code
= status
.MULTI
;
396 virtual void following() {
399 virtual void set_orender_current(int num
) {
402 status
.orender_current
= status
.RENDERD
;
404 status
.orender_current
= status
.RENDERO
;
407 virtual void set_arender_current() {
408 status
.arender_current
= 1;
411 virtual void clear_arender_current() {
412 status
.arender_current
= 0;
415 virtual void rendering() {
417 * Current alignment rendering tasks must complete
418 * before any current output rendering tasks can
421 if (status
.arender_current
) {
422 status
.code
= status
.RENDERA
;
423 status
.arender_current
= 0;
425 status
.code
= status
.orender_current
;
430 virtual void writing_output(int num
) {
433 status
.code
= status
.WRITED
;
435 status
.code
= status
.WRITEO
;
439 virtual void d3_control_point_data(double max_perturbation
, double min_perturbation
, double cur_perturbation
,
440 double current_error
) {
441 status
.cp_max_perturb
= max_perturbation
;
442 status
.cp_min_perturb
= min_perturbation
;
443 status
.cp_cur_perturb
= cur_perturbation
;
444 status
.cp_cur_error
= current_error
;
448 virtual void d3_control_point_step() {
453 virtual void d3_subdivision_status(unsigned int primary_frame
, unsigned int secondary_frame
,
454 unsigned int i
, unsigned int j
) {
455 status
.code
= status
.D3_SUBDIVIDING_SPACE
;
456 status
.frame_num
= primary_frame
;
457 status
.secondary_frame_num
= secondary_frame
;
458 status
.y_coordinate
= i
;
459 status
.x_coordinate
= j
;
464 virtual void d3_total_spaces(int total_spaces
) {
465 status
.total_spaces
= total_spaces
;
468 virtual void d3_increment_spaces() {
469 status
.total_spaces
++;
472 virtual void d3_occupancy_status(int frame
) {
473 status
.code
= status
.D3_UPDATING_OCCUPANCY
;
474 status
.frame_num
= frame
;
475 status
.space_num
= 0;
479 virtual void d3_increment_space_num() {
484 virtual void d3_render_status(int filter
, int focus
, int frame
, int view
, int i
, int j
, int space
) {
485 status
.code
= status
.D3_RENDER
;
487 status
.filtering
= filter
;
488 status
.focusing
= focus
;
490 status
.frame_num
= frame
;
491 status
.view_num
= view
;
492 status
.y_coordinate
= i
;
493 status
.x_coordinate
= j
;
495 status
.space_num
= space
;
502 * Informational output
505 virtual void ip_start() {
506 printf("Iterating Irani-Peleg");
509 virtual void refilter_start() {
510 printf("Re-filtering incremental results");
513 virtual void ip_frame_start(unsigned int num
) {
514 status
.code
= status
.IP_RENDER
;
515 status
.frame_num
= num
;
516 status
.irani_peleg_stage
= 0;
520 virtual void ip_frame_simulate_start() {
521 status
.code
= status
.IP_RENDER
;
522 status
.irani_peleg_stage
= 1;
526 virtual void ip_frame_correct_start() {
527 status
.code
= status
.IP_RENDER
;
528 status
.irani_peleg_stage
= 2;
532 virtual void ip_update() {
533 status
.code
= status
.IP_UPDATE
;
537 virtual void ip_write() {
538 status
.code
= status
.IP_WRITE
;
542 virtual void ip_step_done() {
543 status
.code
= status
.IP_STEP_DONE
;
547 virtual void ip_done() {
551 virtual void refilter_done() {
555 virtual void original_frame_start(const char *name
) {
556 status
.code
= status
.UNDEFINED
;
557 printf("Original Frame:\n");
558 printf(" '%s'", name
);
561 virtual void original_frame_done() {
562 status
.code
= status
.FRAME_DONE
;
566 virtual void supplemental_frame_start(const char *name
) {
567 static int section_announced
= 0;
569 if (!section_announced
) {
570 printf("Supplemental Frames:\n");
571 section_announced
= 1;
574 status
.code
= status
.UNDEFINED
;
575 status
.steps_completed
= 0;
576 printf(" '%s'", name
);
579 virtual void supplemental_frame_done() {
580 status
.code
= status
.FRAME_DONE
;
584 virtual void alignment_degree_complete(int degree
) {
585 if (status
.step_type
== 1) {
586 status
.steps_completed
++;
591 virtual void alignment_perturbation_level(ale_pos perturb
, ale_pos lod
) {
592 perturb_timers
[status
.perturb_size
].stop();
593 perturb_timers
[perturb
].start();
594 status
.perturb_size
= perturb
;
595 status
.align_lod
= lod
;
596 if (status
.step_type
== 0) {
597 status
.steps_completed
++;
602 virtual void alignment_dims(unsigned int hr
, unsigned int wr
, unsigned int hi
, unsigned int wi
) {
605 virtual void start_multi_alignment_element(d2::trans_multi
&tm
) {
608 virtual void alignment_match_ok() {
609 status
.code
= status
.UNDEFINED
;
610 printf(format_string_ok(), status
.match_value
);
613 virtual void alignment_no_match() {
614 status
.code
= status
.UNDEFINED
;
615 printf(format_string_no_match(), status
.match_value
);
618 virtual void ale_2d_done(double value
) {
619 status
.code
= status
.UNDEFINED
;
620 printf("Average match: %f%%", value
);
621 status
.code
= status
.SET_DONE
;
623 if (output_performance_data
) {
625 printf("Real time measurements\n");
626 printf("======================\n");
628 printf("Alignment (sampling) : %f s\n", d2_align_sample
.get_total());
629 printf("Alignment (checking) : %f s\n", d2_align_sim
.get_total());
630 printf("Incremental rendering : %f s\n", d2_incremental
.get_total());
631 printf("Irani-Peleg rendering : %f s\n", d2_irani_peleg
.get_total());
634 printf("Details (local alignment)\n");
635 printf("-------------------------\n");
637 int have_details
= 0;
638 for (std::map
<double,ale_timer_t
>::iterator i
= perturb_timers
.begin();
639 i
!= perturb_timers
.end(); i
++) {
640 if (i
->second
.get_total() == 0.0
641 && i
== perturb_timers
.begin())
644 printf("Alignment (perturb %f): %f s\n",
645 i
->first
, i
->second
.get_total());
651 printf("No local alignment performed.\n");
658 virtual void d3_start() {
659 status
.code
= status
.UNDEFINED
;
660 printf("Rendering 3D");
664 virtual void d3_control_point_solve() {
665 status
.code
= status
.D3_CONTROL_POINT_SOLVE
;
669 virtual void d3_init_view_angle(double angle
) {
670 status
.code
= status
.UNDEFINED
;
674 virtual void d3_final_view_angle(double angle
) {
675 status
.code
= status
.UNDEFINED
;
679 virtual void d3_control_point_solve_done() {
680 status
.code
= status
.UNDEFINED
;
684 virtual void d3_subdividing_space() {
685 status
.code
= status
.D3_SUBDIVIDING_SPACE
;
689 virtual void d3_subdividing_space_done() {
690 status
.code
= status
.UNDEFINED
;
694 virtual void d3_updating_occupancy() {
695 status
.code
= status
.D3_UPDATING_OCCUPANCY
;
699 virtual void d3_updating_occupancy_done() {
700 status
.code
= status
.UNDEFINED
;
704 virtual void d3_writing_output(const char *name
) {
705 static int section_announced
= 0;
707 if (!section_announced
) {
709 section_announced
= 1;
712 printf(" '%s'", name
);
717 virtual void d3_writing_output_done() {
718 status
.code
= status
.UNDEFINED
;
727 virtual void warn(const char *string
) {
728 printf("\n\n*** Warning: %s. ***\n\n\n");
735 virtual void exec_failure(const char *exec
, const char *arg1
, const char *arg2
) {
736 printf("\n\n*** An error occurred while running `%s %s %s`. ***\n\n\n", exec
, arg1
, arg2
);
740 virtual void fork_failure(const char *location
) {
741 printf("\n\n*** Could not fork in %s. ***\n\n\n", location
);
745 virtual void memory_error(const char *purpose
) {
746 printf("\n\n*** Unable to allocate memory for %s. ***\n\n\n", purpose
);
750 virtual void memory_error_location(const char *location
) {
751 printf("\n\n*** Unable to allocate memory in %s.\n\n\n", location
);
755 virtual void cli_not_enough(const char *option
) {
756 printf("\n\n*** Not enough arguments for `%s' ***\n\n\n", option
);
760 virtual void cli_bad_arg(const char *option
) {
761 printf("\n\n*** Bad argument to `%s' ***\n\n", option
);
765 virtual void error(const char *string
) {
766 printf("\n\n*** Error: %s. ***\n\n\n", string
);
770 virtual void illegal_option(const char *string
) {
771 printf("\n\n*** Error: illegal option %s ***\n\n", string
);
775 virtual void unknown_device(const char *string
) {
776 printf("\n\n*** Error: unknown device %s ***\n\n", string
);
780 virtual void error_hint(const char *error
, const char *hint
) {
781 printf("\n\n*** Error: %s", error
);
782 printf( "\n*** Hint: %s\n\n\n", hint
);
786 virtual void cache(double usage
, double max
) {
789 virtual void log_message(const char *message
) {