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
30 #include "../ale_pos.h"
31 #include "../config.h"
47 typedef trans_multi transformation
;
48 struct trans_abstract
;
68 gettimeofday(&tv
, NULL
);
78 gettimeofday(&t
, NULL
);
80 t
.tv_sec
-= tv
.tv_sec
;
81 t
.tv_usec
-= tv
.tv_usec
;
83 total
+= t
.tv_sec
+ ((double) 1 / (double) 1000000) * t
.tv_usec
;
85 time_t t
= time(NULL
);
98 * User interface messages.
105 static ui
*singleton
;
120 static int output_performance_data
;
139 * Incremental rendering.
142 LOAD_FILE
, EXPOSURE_PASS_1
,
143 LODCLUSTER_CREATE
, PREMATCH
, ALIGN
, GLOBAL_ALIGN
, POSTMATCH
,
144 EXPOSURE_PASS_2
, RENDERA
, RENDERD
, RENDERO
, WRITED
,
145 WRITEO
, FRAME_DONE
, SET_DONE
, MULTI
,
148 * Irani-Peleg rendering.
151 IP_RENDER
, IP_STEP_DONE
, IP_UPDATE
, IP_WRITE
,
157 D3_CONTROL_POINT_SOLVE
, D3_SUBDIVIDING_SPACE
,
158 D3_UPDATING_OCCUPANCY
, D3_RENDER
160 } code
, orender_current
;
168 double exp_multiplier
[3];
171 unsigned int element_degree
;
172 unsigned int total_degree
;
173 unsigned int element_index
;
174 unsigned int num_elements
;
175 unsigned int frame_num
;
176 unsigned int irani_peleg_stage
;
177 unsigned int irani_peleg_step
;
178 unsigned int irani_peleg_steps
;
179 unsigned int secondary_frame_num
;
180 unsigned int view_num
;
181 unsigned int x_coordinate
, y_coordinate
;;
182 unsigned int filtering
, focusing
;
183 unsigned int space_num
;
184 unsigned int total_spaces
;
185 double cp_max_perturb
;
186 double cp_min_perturb
;
187 double cp_cur_perturb
;
196 for (int k
= 0; k
< 3; k
++)
197 exp_multiplier
[k
] = 1;
213 ale_timer_t d2_align_sample
;
214 ale_timer_t d2_align_sim
;
215 ale_timer_t d2_incremental
;
216 ale_timer_t d2_irani_peleg
;
217 std::map
<double,ale_timer_t
> perturb_timers
;
231 virtual void printf(const char *format
, ...) = 0;
237 virtual void update() = 0;
240 * Match format strings for textual UIs.
243 const char *format_string_ok() {
244 return " okay (%9.6f%% match)";
246 const char *format_string_no_match() {
247 return " no match (%9.6f%% match)";
249 const char *format_string_working() {
250 return " (%9.6f%% match)";
256 * Handle options and other user input.
259 static void handle_input(int argc
, const char *argv
[], const char *package
,
260 const char *short_version
, const char *version
);
264 static void set_stream() {
265 assert(singleton
== NULL
);
269 static void set_tty() {
270 assert(singleton
== NULL
);
274 static void set_log() {
275 assert (singleton
== NULL
);
279 static void set_quiet() {
280 assert(singleton
== NULL
);
284 static void set_profile() {
285 output_performance_data
= 1;
289 * Messages from the engine
292 virtual void identify_output(const char *name
) {
293 printf("Output file will be '%s'.\n", name
);
296 virtual void d2_align_sim_start() {
297 d2_align_sim
.start();
300 virtual void d2_align_sim_stop() {
304 virtual void d2_align_sample_start() {
305 d2_align_sample
.start();
308 virtual void d2_align_sample_stop() {
309 d2_align_sample
.stop();
312 virtual void d2_incremental_start() {
313 d2_incremental
.start();
316 virtual void d2_incremental_stop() {
317 d2_incremental
.stop();
320 virtual void d2_irani_peleg_start() {
321 d2_irani_peleg
.start();
324 virtual void d2_irani_peleg_stop() {
325 d2_irani_peleg
.stop();
328 virtual void exp_multiplier(double m0
, double m1
, double m2
) {
329 status
.exp_multiplier
[0] = m0
;
330 status
.exp_multiplier
[1] = m1
;
331 status
.exp_multiplier
[2] = m2
;
334 void exp_multiplier(double mult
[3]) {
335 exp_multiplier(mult
[0], mult
[1], mult
[2]);
338 virtual void set_steps(int count
, int type
= 0) {
339 status
.steps
= count
;
340 status
.step_type
= type
;
343 virtual void set_steps_completed(int count
) {
344 status
.steps_completed
= count
;
347 virtual void set_match(double match
) {
348 status
.match_value
= (1 - match
) * 100;
352 virtual void set_offset(d2::trans_single offset
);
353 virtual void set_offset(d2::trans_multi offset
);
355 virtual void gs_mo(ale_pos gs_mo
) {
358 virtual void cache_status(unsigned int c
) {
362 virtual void loading_file() {
363 status
.code
= status
.LOAD_FILE
;
367 virtual void exposure_1() {
368 status
.code
= status
.EXPOSURE_PASS_1
;
372 virtual void exposure_2() {
373 status
.code
= status
.EXPOSURE_PASS_2
;
377 virtual void prematching() {
378 status
.code
= status
.PREMATCH
;
382 virtual void postmatching() {
383 status
.code
= status
.POSTMATCH
;
387 virtual void constructing_lod_clusters(ale_pos lod
) {
388 status
.code
= status
.LODCLUSTER_CREATE
;
389 status
.align_lod
= lod
;
393 virtual void global_alignment(ale_pos perturb
, ale_pos lod
) {
394 status
.perturb_size
= perturb
;
395 status
.align_lod
= lod
;
396 status
.code
= status
.GLOBAL_ALIGN
;
400 virtual void aligning(ale_pos perturb
, ale_pos lod
) {
401 perturb_timers
[perturb
].start();
402 status
.perturb_size
= perturb
;
403 status
.align_lod
= lod
;
404 status
.code
= status
.ALIGN
;
408 virtual void multi() {
409 status
.code
= status
.MULTI
;
413 virtual void following() {
416 virtual void set_orender_current(int num
) {
419 status
.orender_current
= status
.RENDERD
;
421 status
.orender_current
= status
.RENDERO
;
424 virtual void set_arender_current() {
425 status
.arender_current
= 1;
428 virtual void clear_arender_current() {
429 status
.arender_current
= 0;
432 virtual void rendering() {
434 * Current alignment rendering tasks must complete
435 * before any current output rendering tasks can
438 if (status
.arender_current
) {
439 status
.code
= status
.RENDERA
;
440 status
.arender_current
= 0;
442 status
.code
= status
.orender_current
;
447 virtual void writing_output(int num
) {
450 status
.code
= status
.WRITED
;
452 status
.code
= status
.WRITEO
;
456 virtual void d3_control_point_data(double max_perturbation
, double min_perturbation
, double cur_perturbation
,
457 double current_error
) {
458 status
.cp_max_perturb
= max_perturbation
;
459 status
.cp_min_perturb
= min_perturbation
;
460 status
.cp_cur_perturb
= cur_perturbation
;
461 status
.cp_cur_error
= current_error
;
465 virtual void d3_control_point_step() {
470 void set_frame_num(unsigned int num
) {
471 status
.frame_num
= num
;
474 virtual void d3_subdivision_status(unsigned int primary_frame
, unsigned int secondary_frame
,
475 unsigned int i
, unsigned int j
) {
476 status
.code
= status
.D3_SUBDIVIDING_SPACE
;
477 status
.frame_num
= primary_frame
;
478 status
.secondary_frame_num
= secondary_frame
;
479 status
.y_coordinate
= i
;
480 status
.x_coordinate
= j
;
485 virtual void d3_total_spaces(int total_spaces
) {
486 status
.total_spaces
= total_spaces
;
489 virtual void d3_increment_spaces() {
490 status
.total_spaces
++;
493 virtual void d3_occupancy_status(int frame
) {
494 status
.code
= status
.D3_UPDATING_OCCUPANCY
;
495 status
.frame_num
= frame
;
496 status
.space_num
= 0;
500 virtual void d3_increment_space_num() {
505 virtual void d3_render_status(int filter
, int focus
, int frame
, int view
, int i
, int j
, int space
) {
506 status
.code
= status
.D3_RENDER
;
508 status
.filtering
= filter
;
509 status
.focusing
= focus
;
511 status
.frame_num
= frame
;
512 status
.view_num
= view
;
513 status
.y_coordinate
= i
;
514 status
.x_coordinate
= j
;
516 status
.space_num
= space
;
523 * Informational output
526 virtual void ip_start() {
527 printf("Iterating Irani-Peleg");
530 virtual void refilter_start() {
531 printf("Re-filtering incremental results");
534 virtual void ip_frame_start(unsigned int num
) {
535 status
.code
= status
.IP_RENDER
;
536 status
.frame_num
= num
;
537 status
.irani_peleg_stage
= 0;
541 virtual void ip_frame_simulate_start() {
542 status
.code
= status
.IP_RENDER
;
543 status
.irani_peleg_stage
= 1;
547 virtual void ip_frame_correct_start() {
548 status
.code
= status
.IP_RENDER
;
549 status
.irani_peleg_stage
= 2;
553 virtual void ip_update() {
554 status
.code
= status
.IP_UPDATE
;
558 virtual void ip_write() {
559 status
.code
= status
.IP_WRITE
;
563 void ip_step_start(int num
, int total
) {
564 status
.irani_peleg_step
= num
;
565 status
.irani_peleg_steps
= total
;
568 virtual void ip_step_done() {
569 status
.code
= status
.IP_STEP_DONE
;
573 virtual void ip_done() {
577 virtual void refilter_done() {
581 virtual void original_frame_start(const char *name
) {
582 status
.code
= status
.UNDEFINED
;
583 printf("Original Frame:\n");
584 printf(" '%s'", name
);
587 virtual void original_frame_done() {
588 status
.code
= status
.FRAME_DONE
;
592 virtual void supplemental_frame_start(const char *name
) {
593 static int section_announced
= 0;
595 if (!section_announced
) {
596 printf("Supplemental Frames:\n");
597 section_announced
= 1;
600 status
.code
= status
.UNDEFINED
;
601 status
.steps_completed
= 0;
602 printf(" '%s'", name
);
605 virtual void supplemental_frame_done() {
606 status
.code
= status
.FRAME_DONE
;
610 void alignment_degree_max(int degree_total
) {
611 status
.total_degree
= degree_total
;
612 status
.element_degree
= 0;
615 virtual void alignment_degree_complete(int degree
) {
616 if (status
.step_type
== 1) {
617 status
.steps_completed
++;
620 status
.element_degree
= degree
;
624 void aligning_element(unsigned int index
, unsigned int num
) {
625 status
.element_index
= index
;
626 status
.num_elements
= num
;
631 virtual void alignment_perturbation_level(ale_pos perturb
, ale_pos lod
) {
632 perturb_timers
[status
.perturb_size
].stop();
633 perturb_timers
[perturb
].start();
634 status
.perturb_size
= perturb
;
635 status
.align_lod
= lod
;
636 if (status
.step_type
== 0) {
637 status
.steps_completed
++;
642 virtual void alignment_dims(unsigned int hr
, unsigned int wr
, unsigned int hi
, unsigned int wi
) {
645 virtual void start_multi_alignment_element(d2::trans_multi
&tm
) {
648 virtual void alignment_match_ok() {
649 status
.code
= status
.UNDEFINED
;
650 printf(format_string_ok(), status
.match_value
);
653 virtual void alignment_no_match() {
654 status
.code
= status
.UNDEFINED
;
655 printf(format_string_no_match(), status
.match_value
);
658 virtual void ale_2d_done(double value
) {
659 status
.code
= status
.UNDEFINED
;
660 printf("Average match: %f%%", value
);
661 status
.code
= status
.SET_DONE
;
663 if (output_performance_data
) {
665 printf("Real time measurements\n");
666 printf("======================\n");
668 printf("Alignment (sampling) : %f s\n", d2_align_sample
.get_total());
669 printf("Alignment (checking) : %f s\n", d2_align_sim
.get_total());
670 printf("Incremental rendering : %f s\n", d2_incremental
.get_total());
671 printf("Irani-Peleg rendering : %f s\n", d2_irani_peleg
.get_total());
674 printf("Details (local alignment)\n");
675 printf("-------------------------\n");
677 int have_details
= 0;
678 for (std::map
<double,ale_timer_t
>::iterator i
= perturb_timers
.begin();
679 i
!= perturb_timers
.end(); i
++) {
680 if (i
->second
.get_total() == 0.0
681 && i
== perturb_timers
.begin())
684 printf("Alignment (perturb %f): %f s\n",
685 i
->first
, i
->second
.get_total());
691 printf("No local alignment performed.\n");
698 virtual void d3_start() {
699 status
.code
= status
.UNDEFINED
;
700 printf("Rendering 3D");
704 virtual void d3_control_point_solve() {
705 status
.code
= status
.D3_CONTROL_POINT_SOLVE
;
709 virtual void d3_init_view_angle(double angle
) {
710 status
.code
= status
.UNDEFINED
;
714 virtual void d3_final_view_angle(double angle
) {
715 status
.code
= status
.UNDEFINED
;
719 virtual void d3_control_point_solve_done() {
720 status
.code
= status
.UNDEFINED
;
724 virtual void d3_subdividing_space() {
725 status
.code
= status
.D3_SUBDIVIDING_SPACE
;
729 virtual void d3_subdividing_space_done() {
730 status
.code
= status
.UNDEFINED
;
734 virtual void d3_updating_occupancy() {
735 status
.code
= status
.D3_UPDATING_OCCUPANCY
;
739 virtual void d3_updating_occupancy_done() {
740 status
.code
= status
.UNDEFINED
;
744 virtual void d3_writing_output(const char *name
) {
745 static int section_announced
= 0;
747 if (!section_announced
) {
749 section_announced
= 1;
752 printf(" '%s'", name
);
757 virtual void d3_writing_output_done() {
758 status
.code
= status
.UNDEFINED
;
767 virtual void warn(const char *string
) {
768 printf("\n\n*** Warning: %s. ***\n\n\n");
775 virtual void exec_failure(const char *exec
, const char *arg1
, const char *arg2
) {
776 printf("\n\n*** An error occurred while running `%s %s %s`. ***\n\n\n", exec
, arg1
, arg2
);
780 virtual void fork_failure(const char *location
) {
781 printf("\n\n*** Could not fork in %s. ***\n\n\n", location
);
785 virtual void memory_error(const char *purpose
) {
786 printf("\n\n*** Unable to allocate memory for %s. ***\n\n\n", purpose
);
790 virtual void memory_error_location(const char *location
) {
791 printf("\n\n*** Unable to allocate memory in %s.\n\n\n", location
);
795 virtual void cli_not_enough(const char *option
) {
796 printf("\n\n*** Not enough arguments for `%s' ***\n\n\n", option
);
800 virtual void cli_bad_arg(const char *option
) {
801 printf("\n\n*** Bad argument to `%s' ***\n\n", option
);
805 virtual void error(const char *string
) {
806 printf("\n\n*** Error: %s. ***\n\n\n", string
);
810 virtual void illegal_option(const char *string
) {
811 printf("\n\n*** Error: illegal option %s ***\n\n", string
);
815 virtual void unknown_device(const char *string
) {
816 printf("\n\n*** Error: unknown device %s ***\n\n", string
);
820 virtual void error_hint(const char *error
, const char *hint
) {
821 printf("\n\n*** Error: %s", error
);
822 printf( "\n*** Hint: %s\n\n\n", hint
);
826 virtual void cache(double usage
, double max
) {
829 virtual void log_message(const char *message
) {