From: <and...@us...> - 2011-03-20 22:44:51
|
Revision: 11662 http://plplot.svn.sourceforge.net/plplot/?rev=11662&view=rev Author: andrewross Date: 2011-03-20 22:44:44 +0000 (Sun, 20 Mar 2011) Log Message: ----------- Add support for some callbacks in octave so plslabelfunc, plmap, plmeridians and plstransform now work. Implement example 19 for octave. Modified Paths: -------------- trunk/bindings/octave/plplot_octave.i trunk/bindings/swig-support/plplotcapi.i trunk/examples/octave/x19c.m trunk/plplot_test/test_octave.sh.in Modified: trunk/bindings/octave/plplot_octave.i =================================================================== --- trunk/bindings/octave/plplot_octave.i 2011-03-20 04:45:35 UTC (rev 11661) +++ trunk/bindings/octave/plplot_octave.i 2011-03-20 22:44:44 UTC (rev 11662) @@ -498,6 +498,7 @@ %typemap(freearg) (const PLFLT *ArrayY, PLINT ny, PLFLT *OutMatrixCk) {} + //----------------------------------------------------------------------------- // String returning functions //----------------------------------------------------------------------------- @@ -518,6 +519,7 @@ typedef PLINT (*defined_func)(PLFLT, PLFLT); typedef void (*fill_func)(PLINT, const PLFLT*, const PLFLT*); typedef void (*pltr_func)(PLFLT, PLFLT, PLFLT *, PLFLT*, PLPointer); +typedef void (*ct_func)(PLFLT, PLFLT, PLFLT *, PLFLT*, PLPointer); typedef void (*mapform_func)(PLINT, PLFLT*, PLFLT*); typedef PLFLT (*f2eval_func)(PLINT, PLINT, PLPointer); typedef void (*label_func)(PLINT, PLFLT, char*, PLINT, PLPointer); @@ -526,10 +528,186 @@ typedef PLINT (*defined_func)(PLFLT, PLFLT); typedef void (*fill_func)(PLINT, const PLFLT*, const PLFLT*); typedef void (*pltr_func)(PLFLT, PLFLT, PLFLT *, PLFLT*, PLPointer); +typedef void (*ct_func)(PLFLT, PLFLT, PLFLT *, PLFLT*, PLPointer); typedef void (*mapform_func)(PLINT, PLFLT *, PLFLT*); typedef PLFLT (*f2eval_func)(PLINT, PLINT, PLPointer); typedef void (*label_func)(PLINT, PLFLT, char*, PLINT, PLPointer); %} + +%{ +#include <iostream> + + octave_function *fcnMapForm; + std::string nameMapForm; + + void mapform_octave(PLINT n, PLFLT *x, PLFLT *y) { + octave_idx_type i; + octave_value_list functionArguments; + octave_value_list retval; + + Matrix xin(n,1); + Matrix yin(n,1); + Matrix xout; + Matrix yout; + + for (i=0;i<n;i++) { + xin(i,0) = x[i]; + yin(i,0) = y[i]; + } + + functionArguments(0) = xin; + functionArguments(1) = yin; + + if (fcnMapForm != NULL) + retval = feval(fcnMapForm, functionArguments, 1); + else + retval = feval(nameMapForm, functionArguments, 1); + + + if (retval.length() >= 2) { + xout = retval(0).matrix_value(); + yout = retval(1).matrix_value(); + + for (i=0;i<n;i++) { + x[i] = xout(i,0); + y[i] = yout(i,0); + } + } + + } +%} + +/* Handle function pointers to mapform function */ +%typemap(in) mapform_func mapform { + + octave_value obj = $input; + if (! obj.is_empty() ) { + if ( obj.is_function_handle() || obj.is_inline_function() ) + { + fcnMapForm = obj.function_value(); + } + else if ( obj.is_string() ) + { + nameMapForm = obj.string_value(); + fcnMapForm = NULL; + } + $1 = mapform_octave; + } + else { + $1 = NULL; + } + +} + +%{ + + octave_function *fcnLabelFunc; + std::string nameLabelFunc; + + void labelfunc_octave(PLINT axis, PLFLT value, char *label, PLINT length, PLPointer data) { + int i; + octave_value_list functionArguments; + octave_value_list retval; + + Matrix inAxis(1,1); + Matrix inValue(1,1); + inAxis(0,0) = axis; + inValue(0,0) = value; + + functionArguments(0) = inAxis; + functionArguments(1) = inValue; + + if (fcnLabelFunc != NULL) + retval = feval(fcnLabelFunc, functionArguments, 1); + else + retval = feval(nameLabelFunc, functionArguments, 1); + + strncpy(label,retval(0).string_value().c_str(),length); + } +%} + +/* Handle function pointers to mapform function */ +%typemap(in) label_func lf { + + octave_value obj = $input; + if (! obj.is_empty() ) { + if ( obj.is_function_handle() || obj.is_inline_function() ) + { + fcnLabelFunc = obj.function_value(); + } + else if ( obj.is_string() ) + { + nameLabelFunc = obj.string_value(); + fcnLabelFunc = NULL; + } + $1 = labelfunc_octave; + } + else { + $1 = NULL; + } + +} + +%{ + + octave_function *fcnCoordTrans; + std::string nameCoordTrans; + + void ct_octave(PLFLT x, PLFLT y, PLFLT *xt, PLFLT *yt, PLPointer data) { + octave_idx_type i; + octave_value_list functionArguments; + octave_value_list retval; + + Matrix xin(1,1); + Matrix yin(1,1); + Matrix xout; + Matrix yout; + + xin(0,0) = x; + yin(0,0) = y; + + functionArguments(0) = xin; + functionArguments(1) = yin; + + if (fcnCoordTrans != NULL) + retval = feval(fcnCoordTrans, functionArguments, 1); + else + retval = feval(nameCoordTrans, functionArguments, 1); + + + if (retval.length() >= 2) { + xout = retval(0).matrix_value(); + yout = retval(1).matrix_value(); + + *xt = xout(0,0); + *yt = yout(0,0); + } + + } +%} + +/* Handle function pointers to mapform function */ +%typemap(in) ct_func ctf { + + octave_value obj = $input; + if (! obj.is_empty() ) { + if ( obj.is_function_handle() || obj.is_inline_function() ) + { + fcnCoordTrans = obj.function_value(); + } + else if ( obj.is_string() ) + { + nameCoordTrans = obj.string_value(); + fcnCoordTrans = NULL; + } + $1 = ct_octave; + } + else { + $1 = NULL; + } + +} + // The octave bindings started out as an independent project with a // historical API that does not match up that well with the PLplot API // function names and numbers and types of arguments. So there are a Modified: trunk/bindings/swig-support/plplotcapi.i =================================================================== --- trunk/bindings/swig-support/plplotcapi.i 2011-03-20 04:45:35 UTC (rev 11661) +++ trunk/bindings/swig-support/plplotcapi.i 2011-03-20 22:44:44 UTC (rev 11662) @@ -731,7 +731,7 @@ void plstart( const char *devname, PLINT nx, PLINT ny ); -#if !defined ( SWIG_LUA ) && !defined ( SWIG_OCTAVE ) +#if !defined ( SWIG_LUA ) void plstransform( ct_func ctf, PLPointer data ); #endif Modified: trunk/examples/octave/x19c.m =================================================================== --- trunk/examples/octave/x19c.m 2011-03-20 04:45:35 UTC (rev 11661) +++ trunk/examples/octave/x19c.m 2011-03-20 22:44:44 UTC (rev 11662) @@ -13,8 +13,151 @@ ## This file is part of plplot_octave. ## It is based on the corresponding demo function of PLplot. -printf("\n\n\ -This demo can't run in Octave, as a pointer to an Octave function is necessary,\n\ - and, even if Matwrap did support it, it would be very inefficient anyway.\n\n"); -fflush(stdout); -kbhit; +1; + +## Shows two views of the world map. + +function ix19c + ## Parse and process command line arguments + + ## (void) plparseopts( &argc, argv, PL_PARSE_FULL ); + + ## Longitude (x) and latitude (y) + + miny = -70; + maxy = 80; + + plinit(); + + ## Cartesian plots + ## Most of world + + minx = 190; + maxx = 190 + 360; + + ## Setup a custom latitude and longitude-based scaling function. + plslabelfunc( @geolocation_labeler, [] ); + + plcol0( 1 ); + plenv( minx, maxx, miny, maxy, 1, 70 ); + plmap( [], "usaglobe", minx, maxx, miny, maxy ); + + ## The Americas + + minx = 190; + maxx = 340; + + plcol0( 1 ); + plenv( minx, maxx, miny, maxy, 1, 70 ); + plmap( [], "usaglobe", minx, maxx, miny, maxy ); + + ## Clear the labeling function + plslabelfunc( [], [] ); + + ## Polar, Northern hemisphere + + minx = 0; + maxx = 360; + + plenv( -75., 75., -75., 75., 1, -1 ); + plmap( @mapform19, "globe", minx, maxx, miny, maxy ); + + pllsty( 2 ); + plmeridians( @mapform19, 10.0, 10.0, 0.0, 360.0, -10.0, 80.0 ); + + ## Polar, Northern hemisphere, this time with a PLplot-wide transform + + minx = 0; + maxx = 360; + + plstransform( @map_transform, [] ); + + pllsty( 1 ); + plenv( -75., 75., -75., 75., 1, -1 ); + ## No need to set the map transform here as the global transform will be + ## used. + plmap( [], "globe", minx, maxx, miny, maxy ); + + pllsty( 2 ); + plmeridians( [], 10.0, 10.0, 0.0, 360.0, -10.0, 80.0 ); + + ## Show Baltimore, MD on the map + plcol0( 2 ); + plssym( 0.0, 2.0 ); + x = -76.6125; + y = 39.2902778; + plpoin( x, y, 18 ); + plssym( 0.0, 1.0 ); + plptex( -76.6125, 43.0, 0.0, 0.0, 0.0, "Baltimore, MD" ); + + ## For C, this is how the global transform is cleared + plstransform( [], [] ); + + plend1(); +endfunction + +function [xt, yt] = map_transform( x, y, data ) + radius = 90.0 - y; + xt = radius .* cos( x * pi / 180.0 ); + yt = radius .* sin( x * pi / 180.0 ); +endfunction + +##-------------------------------------------------------------------------- +## mapform19 +## +## Defines specific coordinate transformation for example 19. +## Not to be confused with mapform in src/plmap.c. +## x[], y[] are the coordinates to be plotted. +##-------------------------------------------------------------------------- + +function [xp, yp] = mapform19( x, y ) + [xp, yp] = map_transform( x, y, [] ); +endfunction + +## "Normalize" longitude values so that they always fall between -180.0 and +## 180.0 +function norm = normalize_longitude( lon ) + if ( lon >= -180.0 && lon <= 180.0 ) + norm = lon; + else + times = floor( ( abs( lon ) + 180.0 ) / 360.0 ); + if ( lon < 0.0 ) + norm = lon + 360.0 * times; + else + norm = lon - 360.0 * times; + endif + endif +endfunction + +## A custom axis labeling function for longitudes and latitudes. +function label = geolocation_labeler( axis, value, data ) + + global PL_X_AXIS PL_Y_AXIS + if ( axis == PL_Y_AXIS ) + label_val = value; + if ( label_val > 0.0 ) + direction_label = " N"; + elseif ( label_val < 0.0 ) + direction_label = " S"; + else + direction_label = "Eq"; + endif + elseif ( axis == PL_X_AXIS ) + label_val = normalize_longitude( value ); + if ( label_val > 0.0 ) + direction_label = " E"; + elseif ( label_val < 0.0 ) + direction_label = " W"; + else + direction_label = ""; + endif + endif + if ( axis == PL_Y_AXIS && value == 0.0 ) + ## A special case for the equator + label = sprintf( "%s", direction_label ); + else + label = sprintf( "%.0f%s", abs( label_val ), direction_label ); + endif +endfunction + +ix19c Modified: trunk/plplot_test/test_octave.sh.in =================================================================== --- trunk/plplot_test/test_octave.sh.in 2011-03-20 04:45:35 UTC (rev 11661) +++ trunk/plplot_test/test_octave.sh.in 2011-03-20 22:44:44 UTC (rev 11662) @@ -73,7 +73,7 @@ # Example 32 not implemented because there has been no call for propagation # and it exercises no new API. failed = [] ; -@swig_octave_comment@for i=[1:18 20:31 33] ; +@swig_octave_comment@for i=[1:18 19 20:31 33] ; # Drop 4, 18, 26, and 33 because deprecated matwrap does not include plstring, # plstring3, pllegend, or plcolorbar. @matwrap_octave_comment@for i=[1:3 5:17 20:25 27:31 ] ; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |