~ubuntu-branches/ubuntu/lucid/pdl/lucid

« back to all changes in this revision

Viewing changes to Graphics/Karma/karma.pd

  • Committer: Bazaar Package Importer
  • Author(s): Ben Gertzfield
  • Date: 2002-04-08 18:47:16 UTC
  • Revision ID: james.westby@ubuntu.com-20020408184716-0hf64dc96kin3htp
Tags: upstream-2.3.2
ImportĀ upstreamĀ versionĀ 2.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
pp_addpm({At=>Top},<<'EOD');
 
2
 
 
3
=head1 NAME
 
4
 
 
5
PDL::Graphics::Karma - interface to Karma visualisation applications
 
6
 
 
7
=head1 DESCRIPTION
 
8
 
 
9
Can send PDL 2D/3D data to kview, xray, kslice_3d, etc...
 
10
 
 
11
Data is transferred using shared memory when available on
 
12
the OS (and segments big enough - e.g. Linux but not
 
13
Solaris unless tuned) so ought to be very fast.
 
14
 
 
15
You can say
 
16
 
 
17
  perldl> kim $a, {App=>'xray'}
 
18
 
 
19
to send to a specific viewer and/or
 
20
 
 
21
  perldl> kim $a, {BB=>[0,50,-100,100]}
 
22
 
 
23
to specify the bounding box in world coordinates (here for a 2D image)
 
24
or just
 
25
 
 
26
  perldl> kim $a
 
27
 
 
28
to reuse the last viewer.
 
29
 
 
30
You can start the viewers from PDL.
 
31
 
 
32
For further info about Karma see http://www.atnf.csiro.au/karma.
 
33
The binary distribution can be downloaded from
 
34
http://www.atnf.csiro.au/karma/ftp.html.
 
35
 
 
36
 
 
37
=head1 SYNOPSIS
 
38
 
 
39
 use PDL::Karma;
 
40
 kview;
 
41
 kim $data;
 
42
 
 
43
=head1 FUNCTIONS
 
44
 
 
45
=cut
 
46
 
 
47
EOD
 
48
 
 
49
pp_addhdr(<<'ENDOFHDR');
 
50
#include <karma_iarray.h>
 
51
#include <karma_dsxfr.h>
 
52
#include <karma_conn.h>
 
53
#include <karma_dm.h>
 
54
#include <karma_ds.h>
 
55
#include <karma_r.h>
 
56
#include <karma_m.h>
 
57
#include <karma_st.h>
 
58
#include <karma_overlay.h>
 
59
#include <karma_event.h>
 
60
#include <k_event_codes.h>
 
61
 
 
62
#define K_PDL_Byte      K_UBYTE
 
63
#define K_PDL_Short     K_SHORT
 
64
#define K_PDL_Ushort    K_USHORT
 
65
#define K_PDL_Long      K_INT
 
66
#define K_PDL_Float     K_FLOAT
 
67
#define K_PDL_Double    K_DOUBLE
 
68
 
 
69
static KOverlayList mylist;
 
70
static int first_overlay=1;
 
71
 
 
72
double* packdouble ( SV* sv, int *ndims ) {
 
73
 
 
74
   SV*  bar;
 
75
   AV*  array;
 
76
   int i;
 
77
   double *darr;
 
78
 
 
79
   if (!(SvROK(sv) && SvTYPE(SvRV(sv))==SVt_PVAV))  /* Test */
 
80
       return NULL;
 
81
 
 
82
   array = (AV *) SvRV(sv);   /* dereference */
 
83
 
 
84
   *ndims = (int) av_len(array) + 1;  /* Number of dimensions */
 
85
 
 
86
   darr = (double *) PDL->smalloc( (*ndims) * sizeof(double) );
 
87
   if (darr == NULL)
 
88
      barf("Out of memory");
 
89
 
 
90
   for(i=0; i<(*ndims); i++) {
 
91
      bar = *(av_fetch( array, i, 0 )); /* Fetch */
 
92
      darr[i] = (double) SvNV(bar);
 
93
   }
 
94
   return darr;
 
95
}
 
96
 
 
97
 
 
98
 
 
99
void ensure_initialised() {
 
100
 
 
101
  static int first = 1;
 
102
 
 
103
  if (first) {
 
104
    first = 0;
 
105
    /*  Initialise communications package  */
 
106
    dm_native_setup ();
 
107
    conn_initialise ( ( void (*) () ) NULL );
 
108
    /*  Register multi_array client protocol support  */
 
109
    dsxfr_register_connection_limits (-1, 1);
 
110
  }
 
111
}
 
112
 
 
113
int ensure_connection(char *karma_app)
 
114
{
 
115
 
 
116
  ensure_initialised();
 
117
  /*  Attempt connection to module  */
 
118
 
 
119
  if ( !conn_attempt_connection ("localhost",
 
120
                                   r_get_def_port (karma_app, r_getenv("DISPLAY")),
 
121
                                   "multi_array") )
 
122
      return 0;
 
123
  return 1;
 
124
}
 
125
 
 
126
 
 
127
 
 
128
static void add_cmap (multi_array **multi_desc, packet_desc* pack_desc,
 
129
        char *packet)
 
130
/*  This routine will add a colourmap to a multi_aray data structure.
 
131
    The multi_array header pointer must be pointed to by  multi_desc  .This
 
132
    pointer will be updated with a new pointer.
 
133
    The pointer to the top level packet descriptor of the general data
 
134
    structure which contains the colourmap must be pointed to by  pack_desc  .
 
135
    The pointer to the top level packet of the general data structure which
 
136
    contains the colourmap must be pointed to by  packet  .
 
137
    The routine returns nothing.
 
138
*/
 
139
{
 
140
    multi_array *new_multi_desc;
 
141
    static char function_name[] = "add_cmap";
 
142
 
 
143
    if ( ( new_multi_desc = ds_alloc_multi (2) ) == NULL )
 
144
    {
 
145
        m_abort (function_name, "multi_array");
 
146
    }
 
147
    if ( ( (*new_multi_desc).array_names[0] = st_dup ("Frame") ) == NULL )
 
148
    {
 
149
        m_abort (function_name, "frame name");
 
150
    }
 
151
    if ( ( (*new_multi_desc).array_names[1] = st_dup ("RGBcolourmap") )
 
152
        == NULL )
 
153
    {
 
154
        m_abort (function_name, "colourmap name");
 
155
    }
 
156
    (*new_multi_desc).headers[0] = (**multi_desc).headers[0];
 
157
    (*new_multi_desc).data[0] = (**multi_desc).data[0];
 
158
    (*new_multi_desc).headers[1] = pack_desc;
 
159
    (*new_multi_desc).data[1] = packet;
 
160
    (**multi_desc).headers[0] = NULL;
 
161
    (**multi_desc).data[0] = NULL;
 
162
    ds_dealloc_multi (*multi_desc);
 
163
    *multi_desc = new_multi_desc;
 
164
}   /*  End Function add_cmap  */
 
165
 
 
166
ENDOFHDR
 
167
 
 
168
pp_addpm(<<'ENDOFPM');
 
169
use vars qw($LASTAPP);
 
170
$LASTAPP = 'kview'; # Default application
 
171
ENDOFPM
 
172
 
 
173
pp_add_exported('','kim krgb kstarted kcur');
 
174
 
 
175
pp_addpm(<<'ENDOFPM');
 
176
 
 
177
use PDL::Options;
 
178
 
 
179
# kim - send image data to karma app
 
180
 
 
181
=head2 kim
 
182
 
 
183
=for ref
 
184
 
 
185
Sends piddle data array to an external Karma application for viewing
 
186
 
 
187
=for usage
 
188
 
 
189
 kim($pdl, [$karma-app, $lut])
 
190
 
 
191
Sends $pdl data to Karma application viewer. Remembers the
 
192
last one used [default: kview].
 
193
 
 
194
=cut
 
195
 
 
196
 
 
197
sub kim {
 
198
  barf('Usage: kim $pdl [,{App => $karma-app, LUT => $lut, BB => $bb}]')
 
199
     if $#_==-1;
 
200
  my $pdl = shift;
 
201
  my $hash = shift;
 
202
  my ($app,$inds);
 
203
  $app = $LASTAPP unless ($app = delete($hash->{App}));
 
204
  my ($lut,$haslut) = (PDL->zeroes(PDL::byte,1,1),0);
 
205
  if (defined($hash->{LUT})) {
 
206
        $lut = $hash->{LUT};
 
207
        $haslut = 1;
 
208
  }
 
209
 
 
210
  if ($pdl->getndims == 3) {
 
211
  $inds = [0,$pdl->getdim(0)-1,0,$pdl->getdim(1)-1,0,
 
212
        $pdl->getdim(2)-1] unless $inds=delete($hash->{BB});
 
213
      ksend3D ($pdl, $lut,$haslut,$app,$inds);
 
214
   }
 
215
  else {
 
216
      $inds = [0,$pdl->getdim(0)-1,0,$pdl->getdim(1)-1]
 
217
         unless $inds=delete($hash->{BB});
 
218
      ksend2D ($pdl, $lut, $haslut,$app,$inds);
 
219
  }
 
220
  $LASTAPP = $app;
 
221
}
 
222
 
 
223
=head2 kstarted
 
224
 
 
225
=for usage
 
226
 
 
227
kstarted([$karma-app])
 
228
 
 
229
=for ref
 
230
 
 
231
Tests if a Karma application is running.
 
232
 
 
233
It tries to connect to the karma application, returns 1 on
 
234
success, 0 otherwise
 
235
 
 
236
Can be used to check if a karma application has already been
 
237
started, e.g.
 
238
 
 
239
  xray unless kstarted 'xray';
 
240
 
 
241
=cut
 
242
 
 
243
sub kstarted {
 
244
  barf('Usage: kstarted [$karma-app]')
 
245
     if $#_>0;
 
246
  my $app = $#_ > -1 ? shift : $LASTAPP;
 
247
  $LASTAPP = $app;
 
248
  return kconnect($app);
 
249
}
 
250
 
 
251
 
 
252
=head2 krgb
 
253
 
 
254
=for usage
 
255
 
 
256
krgb($lut, [$karma-app])
 
257
 
 
258
=for ref
 
259
 
 
260
Sends RGB image to an external Karma application for viewing
 
261
 
 
262
 
 
263
Does not change current default viewer.
 
264
 
 
265
=cut
 
266
 
 
267
sub krgb {
 
268
  barf('Usage: krgb($lut, [$karma-app])') if $#_==-1;
 
269
  my @args = @_;
 
270
  push @args, $LASTAPP if $#_==0; 
 
271
  barf "must be [3,..] rgb piddle" unless $args[0]->getdim(0) == 3;
 
272
  if ($args[0]->getndims <= 3) { krgb_private(@args) } else {
 
273
        krgb3d_private(@args)}
 
274
};
 
275
 
 
276
ENDOFPM
 
277
 
 
278
# Add all the karma app startup commands
 
279
 
 
280
for $app (qw(kview koords  kpvslice  krenzo  kshell xray kslice_3d)) {
 
281
 
 
282
   pp_add_exported('',$app);
 
283
 
 
284
   pp_addpm(<<"ENDOFPM");
 
285
 
 
286
=head2 $app()
 
287
 
 
288
=for ref
 
289
 
 
290
Starts external Karma application $app
 
291
 
 
292
=for usage
 
293
 
 
294
$app([OPTIONS])
 
295
 
 
296
=for example
 
297
 
 
298
 perldl> kview (-num_col => 42)
 
299
 perldl> xray
 
300
 
 
301
=cut
 
302
 
 
303
sub $app {  # Start $app
 
304
   if( !(\$pid = fork)) {       # error or child
 
305
      exec("$app", \@_) if defined \$pid;
 
306
      die "Can't start kview: \$!\n";
 
307
   }
 
308
   \$LASTAPP = "$app";
 
309
   return \$pid;
 
310
}
 
311
 
 
312
ENDOFPM
 
313
 
 
314
} # End app loop
 
315
 
 
316
pp_addxs('
 
317
int
 
318
kconnect(app)
 
319
  char * app
 
320
 
 
321
  CODE:
 
322
        RETVAL = ensure_connection(app);
 
323
        if (RETVAL)
 
324
           conn_close(conn_get_client_connection("multi_array",0));
 
325
  OUTPUT:
 
326
        RETVAL
 
327
 
 
328
');
 
329
 
 
330
# currently lut is assumed to be 8bits
 
331
pp_def('ksend2D',
 
332
        Pars => 'im(m,n); byte lut(o,p)', Doc=>undef,
 
333
        OtherPars => 'int haslut; char* karma_app; SV *bb',
 
334
        Code => 'array_desc    *arrayd;
 
335
                 array_pointer arrayp;
 
336
                 multi_array   *arraym;
 
337
                 $GENERIC() *ptr;
 
338
                 int ms, ns, os, ps;
 
339
                 char *tpack;
 
340
                 packet_desc *tpack_desc;
 
341
                 unsigned short *cmap;
 
342
                 double fc[2], lc[2];
 
343
                 uaddr lengths[2];
 
344
                 unsigned int dtype;
 
345
                 static char *elem_names[1] = { "intensity" };
 
346
                 int bblen;
 
347
                 double *dbb = packdouble($COMP(bb),&bblen);
 
348
 
 
349
                 if (bblen != 4)
 
350
                    barf("need 4 coodinates for 2D boundary box");
 
351
                 fc[0] = dbb[2]; lc[0] = dbb[3];
 
352
                 fc[1] = dbb[0]; lc[1] = dbb[1];
 
353
                 lengths[0] = $SIZE(n);
 
354
                 lengths[1] = $SIZE(m);
 
355
                 ms = $SIZE(m); ns = $SIZE(n); os = $SIZE(o); ps = $SIZE(p);
 
356
                 printf("Sending to %s...\n",$COMP(karma_app));
 
357
                 if (!ensure_connection($COMP(karma_app)))
 
358
                      barf("Error connecting to %s via karma communications",
 
359
                                $COMP(karma_app));
 
360
 
 
361
                 dtype = $TBSULFD(K_PDL_Byte,K_PDL_Short,K_PDL_Ushort,
 
362
                                K_PDL_Long,K_PDL_Float,K_PDL_Double);
 
363
 
 
364
                 /* First create array descriptor */
 
365
 
 
366
                 if ( ( arrayd = ds_easy_alloc_array_desc
 
367
                        (2, lengths,
 
368
                        (CONST double *) fc, (CONST double *) lc,
 
369
                        (CONST double **) NULL, (CONST char **) NULL, 1, &dtype,
 
370
                        (CONST char **) elem_names) ) == NULL )
 
371
                 {
 
372
                        barf("couldn\'t allocate mem for multi array descriptor");
 
373
                 }
 
374
 
 
375
                 /* Now try and create the karma array in various kinds of memory */
 
376
 
 
377
                 if ( !ds_alloc_shm_array (&arrayp, arrayd, FALSE, FALSE) &&
 
378
                      !ds_alloc_mmap_array (-1, 0, 0, TRUE, &arrayp, arrayd, FALSE, FALSE) &&
 
379
                      !ds_alloc_vm_array (&arrayp, arrayd, FALSE, FALSE) )
 
380
                    barf("Unable to create space for karma array (tried shm/mmap/vm)\n");
 
381
 
 
382
                 if ((arraym=ds_easy_alloc_array_from_array_desc(arrayd,&arrayp,FALSE)) == NULL)
 
383
                        barf("couldn\'t allocate mem for multi array");
 
384
 
 
385
                 ptr = ($GENERIC()*) (*(char **) arraym->data[0]);
 
386
 
 
387
                 if ($COMP(haslut)) {
 
388
                        if (os != 3)
 
389
                           barf("first dim must be 3 for rgb");
 
390
                        if ( ( cmap = ds_cmap_alloc_colourmap (ps,
 
391
                             (multi_array **) NULL,
 
392
                                           &tpack_desc, &tpack) ) == NULL )
 
393
                           barf("couldn\'t allocate mem for cmap");
 
394
                        add_cmap(&arraym, tpack_desc, tpack);
 
395
                 }
 
396
 
 
397
                 /* Copy piddle into karma array */
 
398
 
 
399
                 threadloop %{
 
400
                        unsigned short *cm = cmap;
 
401
                        loop(n) %{
 
402
                          loop(m) %{
 
403
                                *ptr++ = $im();
 
404
                          %}
 
405
                        %}
 
406
                        if ($COMP(haslut)) {
 
407
                          loop(p) %{
 
408
                            loop(o) %{
 
409
                                *cm++ = $lut() * 256;
 
410
                            %}
 
411
                          %}
 
412
                        }
 
413
                        /*  Send  a  to module  */
 
414
                        dsxfr_put_multi("connections",arraym);
 
415
                 %}
 
416
 
 
417
                 conn_close(conn_get_client_connection("multi_array",0));
 
418
                 ds_dealloc_multi(arraym);
 
419
');
 
420
 
 
421
# Note reason for seperate 3D function is kview gives error:
 
422
# right_x: 0.000000e+00 must not equal left_x: 0.000000e+00
 
423
# if given a MxNx1 image
 
424
 
 
425
# currently lut is assumed to be 8bits
 
426
pp_def('ksend3D',
 
427
        Pars => 'im(m,n,z); byte lut(o,p)', Doc=>undef,
 
428
        OtherPars => 'int haslut; char* karma_app; SV* bb',
 
429
        Code => 'array_desc    *arrayd;
 
430
                 array_pointer arrayp;
 
431
                 multi_array   *arraym;
 
432
                 $GENERIC() *ptr;
 
433
                 int ms, ns, os, ps, zs;
 
434
                 char *tpack;
 
435
                 packet_desc *tpack_desc;
 
436
                 unsigned short *cmap;
 
437
                 double fc[3], lc[3];
 
438
                 uaddr lengths[3];
 
439
                 unsigned int dtype;
 
440
                 static char *elem_names[1] = { "intensity" };
 
441
                 int bblen;
 
442
                 double *dbb = packdouble($COMP(bb),&bblen);
 
443
 
 
444
                 if (bblen != 6)
 
445
                    barf("need 6 coodinates for 3D boundary box");
 
446
                 fc[0] = dbb[4]; lc[0] = dbb[5];
 
447
                 fc[1] = dbb[2]; lc[1] = dbb[3];
 
448
                 fc[2] = dbb[0]; lc[2] = dbb[1];
 
449
                 lengths[0] = $SIZE(z);
 
450
                 lengths[1] = $SIZE(n);
 
451
                 lengths[2] = $SIZE(m);
 
452
                 zs = $SIZE(z); ms = $SIZE(m); ns = $SIZE(n);
 
453
                 os = $SIZE(o); ps = $SIZE(p);
 
454
                 printf("Sending to %s...\n",$COMP(karma_app));
 
455
                 if (!ensure_connection($COMP(karma_app)))
 
456
                      barf("Error connecting to %s via karma communications",
 
457
                                $COMP(karma_app));
 
458
 
 
459
                 dtype = $TBSULFD(K_PDL_Byte,K_PDL_Short,K_PDL_Ushort,
 
460
                                K_PDL_Long,K_PDL_Float,K_PDL_Double);
 
461
 
 
462
                 /* First create array descriptor */
 
463
 
 
464
                 if ( ( arrayd = ds_easy_alloc_array_desc
 
465
                        (3, lengths,
 
466
                        (CONST double *) fc, (CONST double *) lc,
 
467
                        (CONST double **) NULL, (CONST char **) NULL, 1, &dtype,
 
468
                        (CONST char **) elem_names) ) == NULL )
 
469
                 {
 
470
                        barf("couldn\'t allocate mem for multi array descriptor");
 
471
                 }
 
472
 
 
473
 
 
474
                 /* Now try and create the karma array in various kinds of memory */
 
475
 
 
476
                 if ( !ds_alloc_shm_array (&arrayp, arrayd, FALSE, FALSE) &&
 
477
                      !ds_alloc_mmap_array (-1, 0, 0, TRUE, &arrayp, arrayd, FALSE, FALSE) &&
 
478
                      !ds_alloc_vm_array (&arrayp, arrayd, FALSE, FALSE) )
 
479
                    barf("Unable to create space for karma array (tried shm/mmap/vm)\n");
 
480
 
 
481
                 if ((arraym=ds_easy_alloc_array_from_array_desc(arrayd,&arrayp,FALSE)) == NULL)
 
482
                        barf("couldn\'t allocate mem for multi array");
 
483
 
 
484
                 ptr = ($GENERIC()*) (*(char **) arraym->data[0]);
 
485
 
 
486
                 if ($COMP(haslut)) {
 
487
                        if (os != 3)
 
488
                           barf("first dim must be 3 for rgb");
 
489
                        if ( ( cmap = ds_cmap_alloc_colourmap (ps,
 
490
                             (multi_array **) NULL,
 
491
                                           &tpack_desc, &tpack) ) == NULL )
 
492
                           barf("couldn\'t allocate mem for cmap");
 
493
                        add_cmap(&arraym, tpack_desc, tpack);
 
494
                 }
 
495
                 threadloop %{
 
496
                        unsigned short *cm = cmap;
 
497
                        loop(z) %{
 
498
                         loop(n) %{
 
499
                          loop(m) %{
 
500
                                *ptr++ = $im();
 
501
                          %}
 
502
                         %}
 
503
                        %}
 
504
                        if ($COMP(haslut)) {
 
505
                          loop(p) %{
 
506
                            loop(o) %{
 
507
                                *cm++ = $lut() * 256;
 
508
                            %}
 
509
                          %}
 
510
                        }
 
511
                        /*  Send  a  to module  */
 
512
                        dsxfr_put_multi("connections",arraym);
 
513
                 %}
 
514
 
 
515
                 conn_close(conn_get_client_connection("multi_array",0));
 
516
                 ds_dealloc_multi(arraym);'
 
517
 
 
518
);
 
519
 
 
520
 
 
521
pp_def( 'krgb_private',
 
522
        Pars => 'im(m,n,o)', Doc=>undef,
 
523
        OtherPars => 'char* karma_app;',
 
524
        Code => q@int ms=$SIZE(m);
 
525
                 multi_array *multi_desc;
 
526
                 char *array;
 
527
                 uaddr lengths[2];
 
528
                 static unsigned int elem_types[3] =
 
529
                     {K_UBYTE, K_UBYTE, K_UBYTE};
 
530
                 static char *elem_names[3] =
 
531
                   {"Red Intensity", "Green Intensity", "Blue Intensity"};
 
532
 
 
533
                 if (ms != 3)
 
534
                     barf("first dim must be 3 for rgb");
 
535
                 lengths[0] = $SIZE(o);
 
536
                 lengths[1] = $SIZE(n);
 
537
 
 
538
                 /* check if we can use the 'preallocated' equivalent */
 
539
                 if ( ( array = ds_easy_alloc_n_element_array
 
540
                        (&multi_desc, 2, lengths,
 
541
                        (CONST double *) NULL, (CONST double *) NULL,
 
542
                        (CONST char **) NULL, 3, elem_types,
 
543
                        (CONST char **) elem_names) ) == NULL )
 
544
                 {
 
545
                        barf("couldn\'t allocate mem for multi array");
 
546
                 }
 
547
 
 
548
                 if (!ensure_connection($COMP(karma_app)))
 
549
                      barf("Error connecting to %s via karma communications",
 
550
                                $COMP(karma_app));
 
551
 
 
552
                threadloop %{
 
553
                  loop(o) %{
 
554
                    loop(n) %{
 
555
                      loop(m) %{
 
556
                        *array++ = $im();
 
557
                      %}
 
558
                    %}
 
559
                  %}
 
560
                  dsxfr_put_multi("connections",multi_desc);
 
561
                %}
 
562
 
 
563
                ds_dealloc_multi(multi_desc);
 
564
                conn_close(conn_get_client_connection("multi_array",0));@
 
565
);
 
566
 
 
567
pp_def( 'krgb3d_private',
 
568
        Pars => 'im(m,n,o,p)', Doc=>undef,
 
569
        OtherPars => 'char* karma_app;',
 
570
        Code => q@int ms=$SIZE(m);
 
571
                 multi_array *multi_desc;
 
572
                 char *array;
 
573
                 uaddr lengths[3];
 
574
                 static unsigned int elem_types[3] =
 
575
                     {K_UBYTE, K_UBYTE, K_UBYTE};
 
576
                 static char *elem_names[3] =
 
577
                   {"Red Intensity", "Green Intensity", "Blue Intensity"};
 
578
 
 
579
                 if (ms != 3)
 
580
                     barf("first dim must be 3 for rgb");
 
581
                 lengths[0] = $SIZE(p);
 
582
                 lengths[1] = $SIZE(o);
 
583
                 lengths[2] = $SIZE(n);
 
584
 
 
585
                 /* check if we can use the 'preallocated' equivalent */
 
586
                 if ( ( array = ds_easy_alloc_n_element_array
 
587
                        (&multi_desc, 3, lengths,
 
588
                        (CONST double *) NULL, (CONST double *) NULL,
 
589
                        (CONST char **) NULL, 3, elem_types,
 
590
                        (CONST char **) elem_names) ) == NULL )
 
591
                 {
 
592
                        barf("couldn\'t allocate mem for multi array");
 
593
                 }
 
594
 
 
595
                 if (!ensure_connection($COMP(karma_app)))
 
596
                      barf("Error connecting to %s via karma communications",
 
597
                                $COMP(karma_app));
 
598
 
 
599
                threadloop %{
 
600
                  loop(p) %{
 
601
                    loop(o) %{
 
602
                      loop(n) %{
 
603
                        loop(m) %{
 
604
                          *array++ = $im();
 
605
                        %}
 
606
                      %}
 
607
                    %}
 
608
                %}
 
609
                  dsxfr_put_multi("connections",multi_desc);
 
610
                %}
 
611
 
 
612
                ds_dealloc_multi(multi_desc);
 
613
                conn_close(conn_get_client_connection("multi_array",0));@
 
614
);
 
615
 
 
616
pp_def('koverlay',
 
617
        Pars => 'x(); y(); r(); ell(); PA(); fill(); int id();',
 
618
        OtherPars => 'char* karma_app; char* colour; int coordtype; int dotext;',Doc=><<'EOD',
 
619
 
 
620
=head2 koverlay
 
621
 
 
622
=for ref
 
623
 
 
624
Overlay graphics markers on a Karma application (e.g. kview)
 
625
 
 
626
=for usage
 
627
 
 
628
koverlay $x, $y, {Options...}
 
629
 
 
630
Currently the only markers supported are ellipses. The default
 
631
is a circle of radius 10 units,
 
632
 
 
633
=for example
 
634
 
 
635
$x = 10*xvals(10);
 
636
koverlay $x, sqrt($x), {Radius=>$x/3, Colour=>'green', App=>'kpolar'}
 
637
 
 
638
=for options
 
639
 
 
640
  Radius - [piddle] specify radius of ellipses (major axis if ellipse). Default = 10 units.
 
641
  Ellip  - [piddle] specify ellipticity of ellipses. Default = 0 i.e. circle.
 
642
  PA     - [piddle] specify principle axis (degrees rotation anticlockwise
 
643
                    from the Y axis). Default.
 
644
  ID     - [piddle] Numeric integer id labels to apply.
 
645
  Colour - [string] Colour name for overlay (e.g.  'red'). Default = 'blue'
 
646
  App    - [string] name of Karma app to send too
 
647
  Fill   - [piddle] whether outlines are filled (0 or 1). (Note filled,
 
648
                    ellipses are not yet available in Karma).
 
649
  Coords - [string] "World" or "Pixel" - type of coordinates for x/y/r.
 
650
                    Note pixel implementation rounds to nearest pixel due
 
651
                    to Karma overlays not supporting proper IMAGE_PIXEL
 
652
                    coordinates.
 
653
 
 
654
=cut
 
655
EOD
 
656
        Signature => 'x(); y(); {r(); ell(); PA(); fill(); int id();}',
 
657
        Code => '
 
658
          double ell;
 
659
          int bad=0;
 
660
          int coordtype = $COMP(coordtype) == 1 ? OVERLAY_COORD_WORLD : OVERLAY_COORD_LINEAR;
 
661
          int dotext = $COMP(dotext);
 
662
          char string[81];
 
663
 
 
664
          printf("Sending to %s...\n",$COMP(karma_app));
 
665
 
 
666
          if (first_overlay) {
 
667
             ensure_initialised ();
 
668
             if ((mylist=overlay_va_create_list(NULL, NULL,
 
669
                  OVERLAY_ATT_END))==NULL)
 
670
                  printf("Error initialising overlay list");
 
671
             first_overlay=0;
 
672
          }
 
673
          if (!conn_attempt_connection ("localhost",
 
674
              r_get_def_port ($COMP(karma_app), r_getenv("DISPLAY")),"2D_overlay"))
 
675
                barf("Error connecting to %s via karma communications",$COMP(karma_app));
 
676
 
 
677
          threadloop %{
 
678
             ell = $ell();
 
679
             if (ell == 1.0) {
 
680
                ell = 0.9999999999999999;
 
681
                bad = 1;
 
682
              }
 
683
              overlay_arc(mylist, coordtype, (double)$x(), (double)$y(),
 
684
                         coordtype, (double)$r(), (double)($r()*1.0/(1.0-ell)),
 
685
                         (double)$PA(), $COMP(colour),
 
686
                         (int)($fill() ? 1:0) );
 
687
             if (dotext) {
 
688
                sprintf(string,"%-80d\0", $id());
 
689
                overlay_text(mylist, string, coordtype, (double)($x()+0.8*$r()), (double)($y()+0.8*$r()*1.0/(1.0-ell)),
 
690
                             $COMP(colour), "fixed", 0);
 
691
             }
 
692
          %}
 
693
          while ( !overlay_have_token (mylist) ) dm_native_poll (-1);
 
694
          overlay_release_token (mylist);
 
695
          conn_close(conn_get_client_connection("2D_overlay",0));
 
696
          overlay_remove_objects(mylist,0);
 
697
          if (bad)
 
698
             barf("Infinite ellipticity was specified!\n");
 
699
', PMCode=><<'EOD');
 
700
 
 
701
sub PDL::koverlay {
 
702
   my $hash = ref($_[-1]) eq "HASH" ? pop @_ : {};
 
703
   barf("Usage: koverlay: \$x, \$y, {Options...} \n") if @_ != 2;
 
704
   my($x,$y) = @_;
 
705
   $hash = {iparse({App => $LASTAPP,
 
706
                    Colour => "blue",
 
707
                    Radius => 10,
 
708
                    Ellipse => 0,
 
709
                    PA => 0,
 
710
                    Fill => 0,
 
711
                    ID => undef,
 
712
                    Coords => "WORLD"},$hash)};
 
713
   my ($app,$col,$rad,$ell,$PA,$fill,$id,$dotext);
 
714
   $app = $hash->{App};
 
715
   $col = $hash->{Colour};
 
716
   $rad = $hash->{Radius};
 
717
   $ell = $hash->{Ellipse};
 
718
   $PA  = $hash->{PA};
 
719
   $fill = $hash->{Fill};
 
720
   $dotext = 1;
 
721
   unless (defined ($id = $hash->{ID})) {
 
722
     $id = pdl(0); $dotext = 0;
 
723
   }
 
724
 
 
725
   my $supported = {"WORLD"=>1, "PIXEL"=>2};
 
726
   my $type=1;
 
727
   $type = $supported->{uc($hash->{Coords})} if defined $hash->{Coords};
 
728
   barf "koverlay: Unsupported coordinate type" unless $type;
 
729
 
 
730
   &PDL::_koverlay_int($x,$y,$rad,$ell,$PA,$fill,$id,$app,$col,$type,$dotext);
 
731
   $LASTAPP = $app;
 
732
 
 
733
}
 
734
EOD
 
735
 
 
736
pp_addpm(<<'EOD');
 
737
=head2 kcur
 
738
 
 
739
=for ref
 
740
 
 
741
Return cursor position from a Karma application (e.g. kview/xray)
 
742
 
 
743
=for usage
 
744
 
 
745
 ($x,$y) = kcur($ch, {App=>'karma-app',Coords=>"World|Pixel"})
 
746
 
 
747
This function connects to a Karma application and returns
 
748
the ($x,$y) position and the character typed ($ch)
 
749
by the user. By default world coordinates are returned.
 
750
 
 
751
=for example
 
752
 
 
753
  print kcur {App=>"kview", Coords=>"World"}
 
754
 
 
755
=cut
 
756
 
 
757
sub kcur {
 
758
    my $hash = pop if ref($_[$#_]) eq "HASH";
 
759
    my $supported = {"WORLD"=>1, "PIXEL"=>2};
 
760
    my $type=1;
 
761
    $type = $supported->{uc($hash->{Coords})} if defined $hash->{Coords};
 
762
    barf "kcur: Unsupported coordinate type" unless $type;
 
763
    my $app;
 
764
    $app = $LASTAPP unless ($app = delete($hash->{App}));
 
765
    my ($x,$y,$ch) = &_kcur_int($app,$type);
 
766
    $_[0] = $ch; # Pass this back in args
 
767
    $LASTAPP = $app;
 
768
    return ($x,$y);
 
769
}
 
770
 
 
771
EOD
 
772
 
 
773
pp_addxs('',<<'EOD');
 
774
 
 
775
MODULE = PDL::Graphics::Karma PACKAGE = PDL::Graphics::Karma
 
776
 
 
777
void
 
778
_kcur_int(app,type)
 
779
   PPCODE:
 
780
    char* app = SvPV(ST(0),PL_na);
 
781
    int type = SvIV(ST(1));
 
782
    double x,y;
 
783
    KEvent coord;
 
784
    Connection myconn;
 
785
 
 
786
    ensure_initialised();
 
787
    event_initialise();
 
788
    if (!conn_attempt_connection ("localhost",
 
789
       r_get_def_port (app, r_getenv("DISPLAY")),"generic_event"))
 
790
          barf("Error connecting to %s via karma communications",app);
 
791
 
 
792
    myconn = conn_get_client_connection("generic_event",0);
 
793
 
 
794
    event_wait( K_EVENT_MASK_KEYPRESS , myconn, &coord );
 
795
 
 
796
    if (type==1) {
 
797
       x = coord.data.keypress.position.world.x;
 
798
       y = coord.data.keypress.position.world.y;
 
799
    }
 
800
    else if (type==2) {
 
801
       x = coord.data.keypress.position.image_pixel.x;
 
802
       y = coord.data.keypress.position.image_pixel.y;
 
803
    }
 
804
    conn_close(conn_get_client_connection("generic_event",0));
 
805
    EXTEND(sp,3);
 
806
    PUSHs(sv_2mortal(newSVnv( x )));
 
807
    PUSHs(sv_2mortal(newSVnv( y )));
 
808
    PUSHs(sv_2mortal(newSVpv( coord.data.keypress.string ,1)));
 
809
 
 
810
 
 
811
EOD
 
812
 
 
813
pp_addpm({At=>Bot},<<'EOD');
 
814
 
 
815
 
 
816
=head1 AUTHORS
 
817
 
 
818
Copyright (C)  1997-2001 Christian Soeller, Karl Glazebrook. Reproducing
 
819
documentation from the pdl distribution in any way that does not include a
 
820
statement telling who the original authors are is forbidden.  Reproducing
 
821
and/or distributing the documentation  in any  form that  alters the text is
 
822
forbidden. This module is free software and can be distributed under the
 
823
same terms as PDL itself.
 
824
 
 
825
=cut
 
826
 
 
827
EOD
 
828
 
 
829
pp_done();