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"
38 * User interface messages.
56 static int output_performance_data
;
75 * Incremental rendering.
78 LOAD_FILE
, EXPOSURE_PASS_1
,
79 LODCLUSTER_CREATE
, PREMATCH
, ALIGN
, POSTMATCH
,
80 EXPOSURE_PASS_2
, RENDERA
, RENDERD
, RENDERO
, WRITED
,
81 WRITEO
, FRAME_DONE
, SET_DONE
,
84 * Irani-Peleg rendering.
87 IP_RENDER
, IP_STEP_DONE
, IP_UPDATE
, IP_WRITE
,
93 D3_CONTROL_POINT_SOLVE
, D3_SUBDIVIDING_SPACE
,
94 D3_UPDATING_OCCUPANCY
, D3_RENDER
96 } code
, orender_current
;
103 double exp_multiplier
[3];
107 unsigned int frame_num
;
108 unsigned int irani_peleg_stage
;
109 unsigned int secondary_frame_num
;
110 unsigned int view_num
;
111 unsigned int x_coordinate
, y_coordinate
;;
112 unsigned int filtering
, focusing
;
113 unsigned int space_num
;
114 unsigned int total_spaces
;
115 double cp_max_perturb
;
116 double cp_min_perturb
;
117 double cp_cur_perturb
;
124 for (int k
= 0; k
< 3; k
++)
125 exp_multiplier
[k
] = 1;
133 #if HAVE_GETTIMEOFDAY
134 typedef struct timeval ale_timer_t
;
136 typedef time_t ale_timer_t
;
139 ale_timer_t d2_align_sample_start_time
;
140 ale_timer_t d2_align_sim_start_time
;
141 ale_timer_t d2_incremental_start_time
;
142 ale_timer_t d2_irani_peleg_start_time
;
143 ale_timer_t d2_align_sample_total_time
;
144 ale_timer_t d2_align_sim_total_time
;
145 ale_timer_t d2_incremental_total_time
;
146 ale_timer_t d2_irani_peleg_total_time
;
154 #if HAVE_GETTIMEOFDAY
155 d2_irani_peleg_total_time
.tv_usec
= 0;
156 d2_irani_peleg_total_time
.tv_sec
= 0;
157 d2_incremental_total_time
.tv_usec
= 0;
158 d2_incremental_total_time
.tv_sec
= 0;
159 d2_align_sample_total_time
.tv_usec
= 0;
160 d2_align_sample_total_time
.tv_sec
= 0;
161 d2_align_sim_total_time
.tv_usec
= 0;
162 d2_align_sim_total_time
.tv_sec
= 0;
164 d2_incremental_total_time
= 0;
165 d2_irani_peleg_total_time
= 0;
166 d2_align_sample_total_time
= 0;
167 d2_align_sim_total_time
= 0;
175 virtual void printf(char *format
, ...) = 0;
181 virtual void update() = 0;
184 * Match format strings for textual UIs.
187 char *format_string_ok() {
188 return " okay (%f%% match)";
190 char *format_string_no_match() {
191 return " no match (%f%% match)";
193 char *format_string_working() {
194 return " (%f%% match)";
197 void timer_start(void *t
) {
198 #if HAVE_GETTIMEOFDAY
199 gettimeofday((timeval
*) t
, NULL
);
201 *((time_t *) t
) = time(NULL
);
205 void timer_stop(void *start_v
, void *total_v
) {
206 #if HAVE_GETTIMEOFDAY
208 timeval
*start
= (timeval
*) start_v
;
209 timeval
*total
= (timeval
*) total_v
;
211 gettimeofday(&t
, NULL
);
213 t
.tv_sec
-= start
->tv_sec
;
214 t
.tv_usec
-= start
->tv_usec
;
216 total
->tv_sec
+= t
.tv_sec
;
217 total
->tv_usec
+= t
.tv_usec
;
219 while (total
->tv_usec
>= 1000000) {
221 total
->tv_usec
-= 1000000;
224 while (total
->tv_usec
< 0) {
226 total
->tv_usec
+= 1000000;
229 time_t t
= time(NULL
);
230 t
-= *((time_t *) start_v
);
231 *((time_t *) total_v
) += t
;
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_profile() {
258 output_performance_data
= 1;
262 * Messages from the engine
265 void d2_align_sim_start() {
266 timer_start((void *) &d2_align_sim_start_time
);
269 void d2_align_sim_stop() {
270 timer_stop((void *) &d2_align_sim_start_time
, (void *) &d2_align_sim_total_time
);
273 void d2_align_sample_start() {
274 timer_start((void *) &d2_align_sample_start_time
);
277 void d2_align_sample_stop() {
278 timer_stop((void *) &d2_align_sample_start_time
, (void *) &d2_align_sample_total_time
);
281 void d2_incremental_start() {
282 timer_start((void *) &d2_incremental_start_time
);
285 void d2_incremental_stop() {
286 timer_stop((void *) &d2_incremental_start_time
, (void *) &d2_incremental_total_time
);
289 void d2_irani_peleg_start() {
290 timer_start((void *) &d2_irani_peleg_start_time
);
293 void d2_irani_peleg_stop() {
294 timer_stop((void *) &d2_irani_peleg_start_time
, (void *) &d2_irani_peleg_total_time
);
297 void exp_multiplier(double m0
, double m1
, double m2
) {
298 status
.exp_multiplier
[0] = m0
;
299 status
.exp_multiplier
[1] = m1
;
300 status
.exp_multiplier
[2] = m2
;
303 void exp_multiplier(double mult
[3]) {
304 for (int k
= 0; k
< 3; k
++)
305 status
.exp_multiplier
[k
] = mult
[k
];
308 void set_steps(int count
) {
309 status
.steps
= count
;
312 void set_steps_completed(int count
) {
313 status
.steps_completed
= count
;
316 void set_match(double match
) {
317 status
.match_value
= (1 - match
) * 100;
321 void loading_file() {
322 status
.code
= status
.LOAD_FILE
;
327 status
.code
= status
.EXPOSURE_PASS_1
;
332 status
.code
= status
.EXPOSURE_PASS_2
;
337 status
.code
= status
.PREMATCH
;
341 void postmatching() {
342 status
.code
= status
.POSTMATCH
;
346 void constructing_lod_clusters(ale_pos lod
) {
347 status
.code
= status
.LODCLUSTER_CREATE
;
348 status
.align_lod
= lod
;
352 void aligning(ale_pos perturb
, ale_pos lod
) {
353 status
.perturb_size
= perturb
;
354 status
.align_lod
= lod
;
355 status
.code
= status
.ALIGN
;
359 void set_orender_current(int num
) {
362 status
.orender_current
= status
.RENDERD
;
364 status
.orender_current
= status
.RENDERO
;
367 void set_arender_current() {
368 status
.arender_current
= 1;
371 void clear_arender_current() {
372 status
.arender_current
= 0;
377 * Current alignment rendering tasks must complete
378 * before any current output rendering tasks can
381 if (status
.arender_current
) {
382 status
.code
= status
.RENDERA
;
383 status
.arender_current
= 0;
385 status
.code
= status
.orender_current
;
390 void writing_output(int num
) {
393 status
.code
= status
.WRITED
;
395 status
.code
= status
.WRITEO
;
399 void d3_control_point_data(double max_perturbation
, double min_perturbation
, double cur_perturbation
,
400 double current_error
) {
401 status
.cp_max_perturb
= max_perturbation
;
402 status
.cp_min_perturb
= min_perturbation
;
403 status
.cp_cur_perturb
= cur_perturbation
;
404 status
.cp_cur_error
= current_error
;
408 void d3_control_point_step() {
413 void d3_subdivision_status(unsigned int primary_frame
, unsigned int secondary_frame
,
414 unsigned int i
, unsigned int j
) {
415 status
.code
= status
.D3_SUBDIVIDING_SPACE
;
416 status
.frame_num
= primary_frame
;
417 status
.secondary_frame_num
= secondary_frame
;
418 status
.y_coordinate
= i
;
419 status
.x_coordinate
= j
;
424 void d3_total_spaces(int total_spaces
) {
425 status
.total_spaces
= total_spaces
;
428 void d3_increment_spaces() {
429 status
.total_spaces
++;
432 void d3_occupancy_status(int frame
) {
433 status
.code
= status
.D3_UPDATING_OCCUPANCY
;
434 status
.frame_num
= frame
;
435 status
.space_num
= 0;
439 void d3_increment_space_num() {
444 void d3_render_status(int filter
, int focus
, int frame
, int view
, int i
, int j
, int space
) {
445 status
.code
= status
.D3_RENDER
;
447 status
.filtering
= filter
;
448 status
.focusing
= focus
;
450 status
.frame_num
= frame
;
451 status
.view_num
= view
;
452 status
.y_coordinate
= i
;
453 status
.x_coordinate
= j
;
455 status
.space_num
= space
;
462 * Informational output
466 printf("Iterating Irani-Peleg");
469 void ip_frame_start(unsigned int num
) {
470 status
.code
= status
.IP_RENDER
;
471 status
.frame_num
= num
;
472 status
.irani_peleg_stage
= 0;
475 void ip_frame_simulate_start() {
476 status
.irani_peleg_stage
= 1;
480 void ip_frame_correct_start() {
481 status
.irani_peleg_stage
= 2;
486 status
.code
= status
.IP_UPDATE
;
491 status
.code
= status
.IP_WRITE
;
495 void ip_step_done() {
496 status
.code
= status
.IP_STEP_DONE
;
504 void original_frame_start(const char *name
) {
505 status
.code
= status
.UNDEFINED
;
506 printf("Original Frame:\n");
507 printf(" '%s'", name
);
510 void original_frame_done() {
511 status
.code
= status
.FRAME_DONE
;
515 void supplemental_frame_start(const char *name
) {
516 static int section_announced
= 0;
518 if (!section_announced
) {
519 printf("Supplemental Frames:\n");
520 section_announced
= 1;
523 status
.code
= status
.UNDEFINED
;
524 status
.steps_completed
= 0;
525 printf(" '%s'", name
);
528 void supplemental_frame_done() {
529 status
.code
= status
.FRAME_DONE
;
533 void alignment_monte_carlo_parameter(ale_pos mc
) {
534 status
.mc
= (mc
> 1) ? 1 : mc
;
537 void alignment_perturbation_level(ale_pos perturb
, ale_pos lod
) {
538 status
.perturb_size
= perturb
;
539 status
.align_lod
= lod
;
540 status
.steps_completed
++;
544 void alignment_match_ok() {
545 status
.code
= status
.UNDEFINED
;
546 printf(format_string_ok(), status
.match_value
);
549 void alignment_no_match() {
550 status
.code
= status
.UNDEFINED
;
551 printf(format_string_no_match(), status
.match_value
);
554 void ale_2d_done(double value
) {
555 status
.code
= status
.UNDEFINED
;
556 printf("Average match: %f%%", value
);
557 status
.code
= status
.SET_DONE
;
559 if (output_performance_data
) {
561 printf("Real time measurements\n");
562 printf("======================\n");
564 #if HAVE_GETTIMEOFDAY
565 printf("Alignment (sampling) : %f s\n", (double) d2_align_sample_total_time
.tv_sec
566 + (double) d2_align_sample_total_time
.tv_usec
/ (double) 1000000);
567 printf("Alignment (checking) : %f s\n", (double) d2_align_sim_total_time
.tv_sec
568 + (double) d2_align_sim_total_time
.tv_usec
/ (double) 1000000);
569 printf("Incremental rendering : %f s\n", (double) d2_incremental_total_time
.tv_sec
570 + (double) d2_incremental_total_time
.tv_usec
/ (double) 1000000);
571 printf("Irani-Peleg rendering : %f s\n", (double) d2_irani_peleg_total_time
.tv_sec
572 + (double) d2_irani_peleg_total_time
.tv_usec
/ (double) 1000000);
574 printf("Alignment (sampling) : %f s\n", (double) d2_align_sample_total_time
);
575 printf("Alignment (checking) : %f s\n", (double) d2_align_sim_total_time
);
576 printf("Incremental rendering : %f s\n", (double) d2_incremental_total_time
);
577 printf("Irani-Peleg rendering : %f s\n", (double) d2_irani_peleg_total_time
);
584 status
.code
= status
.UNDEFINED
;
585 printf("Rendering 3D");
589 void d3_control_point_solve() {
590 status
.code
= status
.D3_CONTROL_POINT_SOLVE
;
594 void d3_init_view_angle(double angle
) {
595 status
.code
= status
.UNDEFINED
;
599 void d3_final_view_angle(double angle
) {
600 status
.code
= status
.UNDEFINED
;
604 void d3_control_point_solve_done() {
605 status
.code
= status
.UNDEFINED
;
609 void d3_subdividing_space() {
610 status
.code
= status
.D3_SUBDIVIDING_SPACE
;
614 void d3_subdividing_space_done() {
615 status
.code
= status
.UNDEFINED
;
619 void d3_updating_occupancy() {
620 status
.code
= status
.D3_UPDATING_OCCUPANCY
;
624 void d3_updating_occupancy_done() {
625 status
.code
= status
.UNDEFINED
;
629 void d3_writing_output(const char *name
) {
630 static int section_announced
= 0;
632 if (!section_announced
) {
634 section_announced
= 1;
637 printf(" '%s'", name
);
642 void d3_writing_output_done() {
643 status
.code
= status
.UNDEFINED
;
652 void warn(const char *string
) {
653 printf("\n\n*** Warning: %s. ***\n\n\n");
660 void exec_failure(const char *exec
, const char *arg1
, const char *arg2
) {
661 printf("\n\n*** An error occurred while running `%s %s %s`. ***\n\n\n", exec
, arg1
, arg2
);
665 void fork_failure(const char *location
) {
666 printf("\n\n*** Could not fork in %s. ***\n\n\n", location
);
670 void memory_error(const char *purpose
) {
671 printf("Unable to allocate memory for %s.\n", purpose
);
675 void memory_error_location(const char *location
) {
676 printf("Unable to allocate memory in %s.\n", location
);
680 void cli_not_enough(const char *option
) {
681 printf("\n\n*** Not enough arguments for `%s' ***\n\n", option
);
685 void cli_bad_arg(const char *option
) {
686 printf("\n\n*** Bad argument to `%s' ***\n\n", option
);
690 void error(const char *string
) {
691 printf("\n\n*** Error: %s. ***\n\n\n", string
);
695 void illegal_option(const char *string
) {
696 printf("\n\n*** Error: illegal option %s ***\n\n", string
);
700 void unknown_device(const char *string
) {
701 printf("\n\n*** Error: unknown device %s ***\n\n", string
);
705 void error_hint(const char *error
, const char *hint
) {
706 printf("\n\n*** Error: %s", error
);
707 printf( "\n*** Hint: %s\n\n\n", hint
);