/* Copyright (c) 1996, 1997, The Regents of the University of California. * All rights reserved. See Legal.htm for full text and disclaimer. */ #include "Python.h" #include "narcisse.h" #include "arrayobject.h" #include #include static PyObject *ErrorObject; /* ----------------------------------------------------- */ #define NNARCISSE 10000 /* Size of array for setting attributes */ #define NARTABLE 200 /* Size of table of keyword pairs */ #define MOTSIZE 24 /* Longest keyword */ /* (ZCM 3/27/97) Revised to use the macros below and to make narcissemodule a bit more type-tolerant. */ static char * errstr = NULL ; #define Py_Try(BOOLEAN) {if (!(BOOLEAN)) return NULL;} #define Py_Assert(BOOLEAN,ERROBJ,MESS) {if (!(BOOLEAN)) { \ PyErr_SetString((ERROBJ), (MESS)); \ return NULL;} \ } #define A_DATA(a) (((PyArrayObject *)a)->data) #define A_SIZE(a) PyArray_Size((PyObject *) a) #define A_TYPE(a) (int)(((PyArrayObject *)a)->descr->type_num) #define isARRAY(a) ((a) && PyArray_Check((PyArrayObject *)a)) #define A_NDIM(a) (((PyArrayObject *)a)->nd) #define A_DIM(a,i) (((PyArrayObject *)a)->dimensions[i]) #define GET_ARR(ap,op,type,dim) \ Py_Try(ap=(PyArrayObject *)PyArray_ContiguousFromObject(op,type,dim,dim)) #define ERRSS(s) ((PyObject *)(PyErr_SetString(ErrorObject,s),0)) #define SETERR(s) if(!PyErr_Occurred()) ERRSS(errstr ? errstr : s) #define DECREF_AND_ZERO(p) do{Py_XDECREF(p);p=0;}while(0) static char nartable[165][2][MOTSIZE] = { /* English, French equivalent pairs */ {"display_clip_height","afficheur_clip_hauteur"}, {"display_clip_width","afficheur_clip_largeur"}, {"display_height","afficheur_hauteur"}, {"display_width","afficheur_largeur"}, {"animation_number","animation_nombre"}, {"animation_azimuth","animation_pas_azimuth"}, {"animation_elevation","animation_pas_site"}, {"c_axis_max","axe_c_max"}, {"c_axis_min","axe_c_min"}, {"axes_title_color","axe_couleur_titre"}, {"c_axis_log","axe_log_c"}, {"x_axis_log","axe_log_x"}, {"y_axis_log","axe_log_y"}, {"yr_axis_log","axe_log_yd"}, {"z_axis_log","axe_log_z"}, {"axes_scale_size","axe_taille_echelle"}, {"axes_title_size","axe_taille_titre"}, {"x_axis_title","axe_valeur_x"}, {"y_axis_title","axe_valeur_y"}, {"yr_axis_title","axe_valeur_yd"}, {"z_axis_title","axe_valeur_z"}, {"x_axis_max","axe_x_max"}, {"x_axis_min","axe_x_min"}, {"y_axis_max","axe_y_max"}, {"y_axis_min","axe_y_min"}, {"yr_axis_max","axe_yd_max"}, {"yr_axis_min","axe_yd_min"}, {"z_axis_max","axe_z_max"}, {"z_axis_min","axe_z_min"}, {"3d_box_x_max","boite_cur_x_max"}, {"3d_box_x_min","boite_cur_x_min"}, {"3d_box_y_max","boite_cur_y_max"}, {"3d_box_y_min","boite_cur_y_min"}, {"2d_box_x_max","boite_gri_x_max"}, {"2d_box_x_min","boite_gri_x_min"}, {"2d_box_y_max","boite_gri_y_max"}, {"2d_box_y_min","boite_gri_y_min"}, {"box_width_cm","boite_tai_abs_x"}, {"box_height_cm","boite_tai_abs_y"}, /*{"calcul_action","calcul_action"},*/ {"hide_panel","calcul_ok_cache"}, {"plot_now","calcul_socket"}, /*{"calcul_socket_numero","calcul_socket_numero"},*/ {"config_save","config_sauvegarde"}, /*{"clip_hyperplan","coupe_hyperplan"},*/ /*{"clip_plan_a","coupe_plan_a"},*/ /*{"clip_plan_b","coupe_plan_b"},*/ /*{"clip_plan_c","coupe_plan_c"},*/ /*{"clip_plan_d","coupe_plan_d"},*/ /*{"clip_plan_e","coupe_plan_e"},*/ {"clip_type","coupe_type"}, {"clip_val_i","coupe_val_coup_i"}, {"clip_val_j","coupe_val_coup_j"}, {"clip_val_avg_beg_i","coupe_val_moy_deb_i"}, {"clip_val_avg_beg_j","coupe_val_moy_deb_j"}, {"clip_val_avg_end_i","coupe_val_moy_fin_i"}, {"clip_val_avg_end_j","coupe_val_moy_fin_j"}, {"clip_val_proj_beg_i","coupe_val_proj_deb_i"}, {"clip_val_proj_beg_j","coupe_val_proj_deb_j"}, {"clip_val_proj_end_i","coupe_val_proj_fin_i"}, {"clip_val_proj_end_j","coupe_val_proj_fin_j"}, {"clip_val_proj_pitch_i","coupe_val_proj_pas_i"}, {"clip_val_proj_pitch_j","coupe_val_proj_pas_j"}, {"curve_y_axis","courbe_cote"}, {"curve_color","courbe_couleur"}, {"curve_label","courbe_label"}, {"curve_label_type","courbe_label_type"}, {"curve_label_x_max","courbe_label_x_max"}, {"curve_label_x_min","courbe_label_x_min"}, {"curve_label_y_max","courbe_label_y_max"}, {"curve_label_y_min","courbe_label_y_min"}, {"curve_type","courbe_type"}, {"data_node_number","donnee_noeud_numero"}, {"driver_type","driver_type"}, {"file_save","fichier_sauvegarde"}, {"grid_color","grille_couleur"}, {"grid_x_dist","grille_ecart_x"}, {"grid_y_dist","grille_ecart_y"}, {"grid_z_dist","grille_ecart_z"}, /*{"grid_grad_inter","grille_grad_inter"},*/ {"grid_no_x_ticks","grille_grad_x_nb"}, {"grid_no_y_ticks","grille_grad_y_nb"}, {"grid_no_z_ticks","grille_grad_z_nb"}, {"grid_type","grille_type"}, {"height_c","hauteur_c"}, {"height_c_h_max","hauteur_c_h_max"}, {"height_c_h_min","hauteur_c_h_min"}, {"height_c_log","hauteur_c_log"}, {"height_c_type","hauteur_c_type"}, {"height_c_x_max","hauteur_c_x_max"}, {"height_c_x_min","hauteur_c_x_min"}, {"height_c_y_max","hauteur_c_y_max"}, {"height_c_y_min","hauteur_c_y_min"}, {"height_label","hauteur_label"}, {"height_label_type","hauteur_label_type"}, {"height_label_x_max","hauteur_label_x_max"}, {"height_label_type","hauteur_label_type"}, {"height_label_x_max","hauteur_label_x_max"}, {"height_label_x_min","hauteur_label_x_min"}, {"height_label_y_max","hauteur_label_y_max"}, {"height_label_y_min","hauteur_label_y_min"}, {"height_z","hauteur_z"}, {"height_z_h_max","hauteur_z_h_max"}, {"height_z_h_min","hauteur_z_h_min"}, {"height_z_log","hauteur_z_log"}, {"height_z_type","hauteur_z_type"}, {"height_z_x_max","hauteur_z_x_max"}, {"height_z_x_min","hauteur_z_x_min"}, {"height_z_y_max","hauteur_z_y_max"}, {"height_z_y_min","hauteur_z_y_min"}, {"language","langage"}, {"cell_point","maille_pique"}, {"option_2d","option_2d"}, {"option_2d_concatenate","option_2d_concatene"}, {"option_3d","option_3d"}, {"option_3d_concatenate","option_3d_concatene"}, {"option_3d_conv_mode","option_3d_conv_mu_mo"}, {"option_3d_color_down","option_3d_couleur_down"}, {"option_3d_color_up","option_3d_couleur_up"}, {"option_3d_mask_type","option_3d_masque"}, {"option_3d_grid_type","option_3d_trace_fil"}, {"option_3d_z_or_c","option_3d_z_eq_c"}, {"output","output"}, {"parameter_color_bg","parametre_couleur_fond"}, {"parameter_bg","parametre_fond"}, {"parameter_map","parametre_map"}, {"parameter_map_fg","parametre_map_afond"}, {"parameter_map_col","parametre_map_col"}, {"parameter_map_bg","parametre_map_fond"}, {"parameter_map_pal","parametre_map_pal"}, {"parameter_scene","parametre_scene"}, {"theta","ptvue_azimuth"}, {"distance","ptvue_distance"}, {"ptvue_redress_hori","ptvue_redress_hori"}, {"ptvue_redress_vert","ptvue_redress_vert"}, {"roll","ptvue_roulis"}, {"height","ptvue_site"}, {"text_display","texte_affiche"}, {"text_angle","texte_angle"}, {"text_color","texte_couleur"}, {"text_generator","texte_generateur"}, {"text_number","texte_numero"}, {"text_pos_x","texte_pos_x"}, {"text_pos_y","texte_pos_y"}, {"text_size","texte_taille"}, {"text_value","texte_valeur"}, {"title_display_bottom","titre_affiche_bas"}, {"title_display_right","titre_affiche_droit"}, {"title_display_left","titre_affiche_gauche"}, {"title_display_top","titre_affiche_haut"}, {"title_color_bottom","titre_couleur_bas"}, {"title_color_right","titre_couleur_droit"}, {"title_color_left","titre_couleur_gauche"}, {"title_color_top","titre_couleur_haut"}, {"title_number","titre_numero"}, {"title_size_bottom","titre_taille_bas"}, {"title_size_right","titre_taille_droit"}, {"title_size_left","titre_taille_gauche"}, {"title_size_top","titre_taille_haut"}, {"title_value_bottom","titre_valeur_bas"}, {"title_value_right","titre_valeur_droit"}, {"title_value_left","titre_valeur_gauche"}, {"title_value_top","titre_valeur_haut"}, {"zoom_active","zoom_actif"}, {"zoom_cur_x_max","zoom_cur_x_max"}, {"zoom_cur_x_min","zoom_cur_x_min"}, {"zoom_cur_y_max","zoom_cur_y_max"}, {"zoom_cur_y_min","zoom_cur_y_min"}, {"zoom_gra_coef_size","zoom_gra_coef_taille"}, {"zoom_gra_x_max","zoom_gra_x_max"}, {"zoom_gra_x_min","zoom_gra_x_min"}, {"zoom_gra_y_max","zoom_gra_y_max"}, {"zoom_gra_y_min","zoom_gra_y_min"}, {"",""} /*sentinel */ } ; static SpxArg spxarg[NNARCISSE] ; /* Workspace used by configuration routines. */ static int nspxarg = 0 ; /* Number of entries in spxarg so far. */ static int mspxarg = NNARCISSE;/* Maximum number of entries allowed. */ static char spxmots[NNARCISSE][32] ; /* Keywords in spxarg */ static char nar_naropen__doc__[] = "Opens a connection to Narcisse, if one is not already open." ; static PyObject * nar_naropen(self, args) /* really a wrapper for SpxOpen */ PyObject *self; /* Not used */ PyObject *args; { char * filename ; SPXFILE * spxfile ; Py_Try(PyArg_ParseTuple(args, "s", &filename)); Py_Try( spxfile = SpxOpen ( filename ) ); return PyInt_FromLong ( (long) spxfile ) ; } static char nar_narclose__doc__[] = "Closes the connection, if any, opened by naropen." ; static PyObject * nar_narclose(self, args) /* really a wrapper for SpxClose */ PyObject *self; /* Not used */ PyObject *args; { long spxfile ; Py_Try(PyArg_ParseTuple(args, "l", &spxfile)); SpxClose ( (SPXFILE *)spxfile ) ; Py_INCREF(Py_None); return Py_None; } static char nar_narsync__doc__[] = "Wait until Narcisse has finished requests in progress." ; static PyObject * nar_narsync(self, args) /* Really a wrapper for SpxSync. */ PyObject *self; /* Not used */ PyObject *args; { long spxfile ; Py_Try(PyArg_ParseTuple(args, "l", &spxfile)); SpxSync ( (SPXFILE *)spxfile ) ; Py_INCREF(Py_None); return Py_None; } static char nar_narquery__doc__[] = "Returns 1 if Narcisse exists, -1 if not, and 0 if unsure." ; static PyObject * nar_narquery(self, args) /* really a wrapper for SpxQuery */ PyObject *self; /* Not used */ PyObject *args; { char * filename ; PyObject * retval ; Py_Try(PyArg_ParseTuple(args, "s", &filename)); return PyInt_FromLong ( ( long ) SpxQuery ( filename ) ) ; } static char nar_narinit__doc__[] = "Initializes argument table and translation table." ; static PyObject * nar_narinit(self, args) /* Really a wrapper for SpxInitArg */ /* Since the table is local to this module, no arguments */ /* are needed. */ PyObject *self; /* Not used */ PyObject *args; /* Not used */ { SpxInitArg ( spxarg , NNARCISSE ) ; Py_INCREF(Py_None); return Py_None; } char * nartrans ( keyword ) /* Internal routine that translates keyword to French if need be. */ char * keyword ; { int i , j ; for ( j = 0 ; j < 2 ; j ++ ) for ( i = 0 ; strlen ( nartable[i][j] ) != 0 ; i++ ) if ( ! strcmp ( keyword , nartable[i][j] ) ) return ( nartable[i][1] ) ; return ( NULL ) ; } int narkey ( keyword ) /* Internal routine to Find a spot in the keyword table for keyword motcle */ char * keyword ; { char * motcle ; int i ; if ( ! ( motcle = nartrans ( keyword ) ) ) /* Translate to French */ return -1 ; for ( i = 0 ; i < nspxarg ; i ++ ) if ( ! strcmp ( spxmots[i] , keyword ) ) return i ; if ( nspxarg >= mspxarg - 1 ) return -1 ; i = nspxarg++ ; strcpy ( spxmots[i] , motcle ) ; return i ; } static char nar_narsetai__doc__[] = "Writes a pair (keyword, integer) into the array spxarg." ; static PyObject * nar_narsetai(self, args) /* Really a wrapper for SpxSetArgInt */ PyObject *self; /* Not used */ PyObject *args; { char * name ; int value , index ; Py_Try(PyArg_ParseTuple(args, "si",&name,&value)); if ( ( index = narkey ( name ) ) < 0 ) { return ERRSS (strcat ( "Incorrect keyword name: " , name ) ) ; } SpxSetArgInt ( &(spxarg[index]) , spxmots[index] , value ) ; Py_INCREF(Py_None); return Py_None; } static char nar_narsetar__doc__[] = "Writes a pair (keyword, float) into the array spxarg." ; static PyObject * nar_narsetar(self, args) /* really a wrapper for SpxSetArgReel */ PyObject *self; /* Not used */ PyObject *args; { char * name ; float value ; int index ; Py_Try(PyArg_ParseTuple(args, "sf",&name,&value)); if ( ( index = narkey ( name ) ) < 0 ) { return ERRSS (strcat ( "Incorrect keyword name: " , name ) ) ; } SpxSetArgReel ( &(spxarg[index]) , spxmots[index] , value ) ; Py_INCREF(Py_None); return Py_None; } static char nar_narsetac__doc__[] = "Writes a pair (keyword, char) into the array spxarg." ; static PyObject * nar_narsetac(self, args) /* really a wrapper for SpxSetArgChar */ PyObject *self; /* Not used */ PyObject *args; { char * name ; char * value ; int index ; Py_Try(PyArg_ParseTuple(args, "ss",&name,&value)); if ( ( index = narkey ( name ) ) < 0 ) { return ERRSS (strcat ( "Incorrect keyword name: " , name ) ) ; } SpxSetArgChar ( &(spxarg[index]) , spxmots[index] , value ) ; Py_INCREF(Py_None); return Py_None; } static char nar_narsetaii__doc__[] = "keyword is associated with an array of ints; this writes the ith one of these." ; static PyObject * nar_narsetaii(self, args) /* really a wrapper for SpxSetArgTabInt */ PyObject *self; /* Not used */ PyObject *args; { char * name ; int value ; int index ; int i ; Py_Try(PyArg_ParseTuple(args, "sii",&name,&value,&i)); if ( ( index = narkey ( name ) ) < 0 ) { return ERRSS (strcat ( "Incorrect keyword name: " , name ) ) ; } SpxSetArgTabInt ( &(spxarg[index]) , spxmots[index] , value , i ) ; Py_INCREF(Py_None); return Py_None; } static char nar_narsetari__doc__[] = "keyword is associated with an array of floats; this writes the ith one of these." ; static PyObject * nar_narsetari(self, args) /* really a wrapper for SpxSetArgTabReel. */ PyObject *self; /* Not used */ PyObject *args; { char * name ; float value ; int index ; int i ; Py_Try(PyArg_ParseTuple(args, "sfi",&name,&value,&i)); if ( ( index = narkey ( name ) ) < 0 ) { return ERRSS (strcat ( "Incorrect keyword name: " , name ) ) ; } SpxSetArgTabReel ( &(spxarg[index]) , spxmots[index] , value , i ) ; Py_INCREF(Py_None); return Py_None; } static char nar_narsetaci__doc__[] = "keyword is associated with an array of chars; this writes the ith one of these." ; static PyObject * nar_narsetaci(self, args) /* really a wrapper for SpxSetArgTabChar. */ PyObject *self; /* Not used */ PyObject *args; { char * name ; char * value ; int index ; int i ; Py_Try(PyArg_ParseTuple(args, "ssi",&name,&value,&i)); if ( ( index = narkey ( name ) ) < 0 ) { return ERRSS (strcat ( "Incorrect keyword name: " , name ) ) ; } SpxSetArgTabChar ( &(spxarg[index]) , spxmots[index] , value , i ) ; Py_INCREF(Py_None); return Py_None; } static char nar_narsetvals__doc__[] = "Sends Narcisse the array of pairs initialized previously. */" ; static PyObject * nar_narsetvals(self, args) /* really a wrapper for SpxSetValues. */ PyObject *self; /* Not used */ PyObject *args; { long spxfile ; Py_Try(PyArg_ParseTuple(args, "l", &spxfile)); SpxSetValues ( (SPXFILE *)spxfile , spxarg , nspxarg ) ; nspxarg = 0 ; Py_INCREF(Py_None); return Py_None; } static char nar_nar1curve__doc__[] = "Graph one two-dimensional curve. Arguments y (ordinates), optional x (abscissa). If x is missing, just use iota(x)." ; static PyObject * nar_nar1curve(self, args) /* really a wrapper for SpxMonoCourbe */ /* I am going to assume two arguments which are float */ /* matrices of the same size. The first argument is y */ /* and the second (optional one) is x. If x is not */ /* present, then this acts like basis and generates a */ /* float iota vector of the same size as y. */ /* The Python module interface to this routine will do */ /* everything in its power to coerce what it is sent */ /* into float matrices. */ PyObject *self; /* Not used */ PyObject *args; { PyObject * ox = NULL , * oy ; PyArrayObject * mx = NULL , * my ; int nx ; /*size of object */ int ny ; float * x , * y ; int i ; long spxfile ; Py_Try(PyArg_ParseTuple(args, "lO|O",&spxfile,&oy,&ox)); if (ox) GET_ARR(mx, ox, PyArray_FLOAT, 1); if (!(my=(PyArrayObject *) PyArray_ContiguousFromObject(oy,PyArray_FLOAT,1,1))) { if (mx) Py_DECREF (mx); return ERRSS ("Can't get a float array from the y argument."); } ny = A_SIZE(my); nx = mx ? A_SIZE(mx) : ny ; if ( nx != ny ) { if (mx) Py_DECREF (mx); return (PyObject *) ERRSS ("nar1curve expects x and y to be the same size.");} if ( mx ) x = ( float *)A_DATA (mx); else { /* create an iota array */ x = ( float * ) malloc ( nx * sizeof ( float ) ) ; for ( i = 0 ; i < nx ; i++ ) x[i] = ( float ) i ; } y = ( float *)A_DATA (my); SpxMonoCourbe ( x , y , nx , (SPXFILE *)spxfile ) ; if ( ! mx ) free ( x ) ; else Py_DECREF (mx) ; Py_DECREF (my) ; Py_INCREF(Py_None); return Py_None; } static char nar_narncurves__doc__[] = "Graph several n-dimensional curves." ; static PyObject * nar_narncurves(self, args) /* Really a wrapper for the spx curve-drawing routines. */ /* Must be called with three arguments, the y array, the */ /* x array, and either an integer scalar or array. The */ /* cases are: */ /* scalar = 1 : SpxMonoCourbe, number of points being */ /* min ( sizex , size y ) */ /* scalar > 1 : SpxMulYMonoX, using min(sizex,sizey/n) */ /* points of x and assuming n blocks of */ /* y laid end to end */ /* array ncoords : sizex and sizey must be >= the sum */ /* of ncoords; then we draw size(nccords) */ /* graphs, the length of the ith being */ /* ncoords(i), using SpxMulCourbe. */ PyObject *self; /* Not used */ PyObject *args; { PyObject * ox = NULL, * oy = NULL, * onc = NULL; PyArrayObject * mx , * my ; PyArrayObject * mnc ; PyObject * ocoords ; int nx ; /*size of object */ int ny ; int ndx, ndy ; /* number of dimensions */ float * x , * y ; int * curve_sizes ; int nc = 0 ; /* number of curves */ int total ; int i ; long spxfile ; mx = NULL ; Py_Try(PyArg_ParseTuple(args, "lOOO",&spxfile,&my,&mx,&ocoords)); GET_ARR(mx, ox, PyArray_FLOAT, 1); if (!(my=(PyArrayObject *) PyArray_ContiguousFromObject(oy,PyArray_FLOAT,1,1))) { Py_DECREF (mx); return ERRSS ("Can't get a float array from the y argument."); } nx = A_SIZE (mx); ny = A_SIZE (nx); x = ( float * ) A_DATA (mx); y = ( float * ) A_DATA (my); /* OK , now check the third argument. */ if ( PyInt_Check ( ocoords ) ) { nc = (int)PyInt_AsLong(ocoords) ; if ( nc <= 0 ) { Py_DECREF (mx); Py_DECREF (my); return ERRSS ( "narncurves: Can't graph <= 0 curves." ); } else if ( nc == 1 ) SpxMonoCourbe ( x , y , nx < ny ? nx : ny , (SPXFILE *)spxfile ) ; else SpxMulYMonoX ( x , y , nx < ny/nc ? nx : ny/nc , nc , (SPXFILE *)spxfile ) ; } else { GET_ARR(mnc,ocoords,PyArray_INT,1); if (!(mnc=(PyArrayObject *) PyArray_ContiguousFromObject(ocoords,PyArray_INT,1,1))) { Py_DECREF (mx); Py_DECREF (my); return (PyObject *) ERRSS ("Can't get a float array from the ncoords argument."); } nc = A_DIM(mnc, 0); curve_sizes = ( int * ) A_DATA(mnc); for ( i = 0 , total = 0 ; i < nc ; i++ ) total += curve_sizes[i] ; if ( total > nx || total > ny ) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mnc); return (PyObject *) ERRSS ("narncurves: coordinate string(s) too short." ); } SpxMulCourbe ( x , y , curve_sizes , nc , (SPXFILE *)spxfile ) ; Py_DECREF (mnc); } Py_DECREF (mx); Py_DECREF (my); Py_INCREF(Py_None); return Py_None; } static char nar_narsurf__doc__[] = "Graph a surface given only the z coordinate." ; static PyObject * nar_narsurf(self, args) /* Really a wrapper for SpxPrintSurf */ PyObject *self; /* Not used */ PyObject *args; { PyArrayObject * mz ; PyObject * oz ; float * z ; int sizex , sizey ; long spxfile ; Py_Try(PyArg_ParseTuple(args, "lO", &spxfile , &oz)); GET_ARR(mz,oz,PyArray_FLOAT,2); z = (float *) A_DATA (mz) ; sizex = A_DIM(mz,0); sizey = A_DIM(mz,1); SpxPrintSurf ( sizey , sizex , z , sizey , (SPXFILE *)spxfile ) ; Py_DECREF(mz); Py_INCREF(Py_None); return Py_None; } static char nar_nar3drect__doc__[] = "Given vector x and vector y, and array z, draw the resulting surface." ; static PyObject * nar_nar3drect(self, args) /* This is really a wrapper for SpxRect3d */ PyObject *self; /* Not used */ PyObject *args; { PyObject * oz = NULL, * ox = NULL, * oy = NULL ; PyArrayObject * mz , * mx , * my ; int sizex , sizey ; float * x , * y , * z ; long spxfile ; Py_Try(PyArg_ParseTuple(args, "lOOO", &spxfile , &ox , &oy, &oz)); GET_ARR(mx,ox,PyArray_FLOAT,1); if (!(my=(PyArrayObject *) PyArray_ContiguousFromObject(oy,PyArray_FLOAT,1,1))) { Py_DECREF (mx); return (PyObject *) ERRSS ("Can't get a 1d float array from the y argument.");; } if (!(mz=(PyArrayObject *) PyArray_ContiguousFromObject(oz,PyArray_FLOAT,2,2))) { Py_DECREF (mx); Py_DECREF (my); return (PyObject *) ERRSS ("Can't get a 2d float array from the z argument."); } sizex = A_DIM(mx,0); sizey = A_DIM(my,0); if ( A_DIM(mz,0)!=sizey || A_DIM(mz,1)!=sizex ) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); return ERRSS ("nar3drect: z, x, and y dimensions do not match." ); } x = ( float *)A_DATA (mx); y = ( float *)A_DATA (my); z = ( float *)A_DATA (mz); SpxRect3d(sizex,sizey,x,y,z,sizex,(SPXFILE *)spxfile) ; Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_INCREF(Py_None); return Py_None; } static char nar_nar3dtetra__doc__[] = "Given matrices z, y, and x of the same shape, draw the surface." ; static PyObject * nar_nar3dtetra(self, args) /* Really a wrapper for SpxTetra3d. */ /* It took me a long time to work this out. The dimensions */ /* in Narcisse are like those in FORTRAN, i. e., the roles */ /* of dimensions 0 and 1 are reversed from what you might */ /* think. */ PyObject *self; /* Not used */ PyObject *args; { PyObject * oz = NULL, * ox = NULL, *oy = NULL; PyArrayObject * mz , * mx , * my ; int sizex , sizey ; float * x , * y , * z ; long spxfile ; Py_Try(PyArg_ParseTuple(args, "lOOO", &spxfile , &ox , &oy, &oz)); GET_ARR(mx,ox,PyArray_FLOAT,2); if (!(my=(PyArrayObject *) PyArray_ContiguousFromObject(oy,PyArray_FLOAT,2,2))) { Py_DECREF (mx); return (PyObject *) ERRSS ("Can't get a 2d float array from the y argument."); } if (!(mz=(PyArrayObject *) PyArray_ContiguousFromObject(oz,PyArray_FLOAT,2,2))) { Py_DECREF (mx); Py_DECREF (my); return (PyObject *) ERRSS ("Can't get a 2d float array from the z argument.");; } sizex = A_DIM(mx, 0); sizey = A_DIM(mx, 1); if ( sizex != A_DIM (my, 0) || sizey != A_DIM (my, 1) || sizex != A_DIM (mz, 0) || sizey != A_DIM (mz, 1) ) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); return (PyObject *) ERRSS ("nar3dtetra: x, y, and z must have the same shape." ); } x = (float *)A_DATA (mx); y = (float *)A_DATA (my); z = (float *)A_DATA (mz); SpxTetra3d(sizey,sizex,x,sizey,y,sizey,z,sizey,(SPXFILE *)spxfile) ; Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_INCREF(Py_None); return Py_None; } static char nar_nar4drect__doc__[] = "Given vectors x and y, and matrices z and c, draw the resulting surface." ; static PyObject * nar_nar4drect(self, args) /* This is really a wrapper for SpxRect4d. */ PyObject *self; /* Not used */ PyObject *args; { PyObject * oz = NULL, * oc = NULL, * ox = NULL, * oy = NULL; PyArrayObject * mz , *mc , * mx , * my ; int sizex , sizey ; float * x , * y , * z , * c ; long spxfile ; Py_Try( PyArg_ParseTuple(args, "lOOOO", &spxfile , &ox , &oy , &oz, &oc)); GET_ARR(mx,ox,PyArray_FLOAT,1); if (!(my=(PyArrayObject *) PyArray_ContiguousFromObject(oy,PyArray_FLOAT,1,1))) { Py_DECREF (mx); return ERRSS ("Can't get a 1d float array from the y argument."); } if (!(mz=(PyArrayObject *) PyArray_ContiguousFromObject(oz,PyArray_FLOAT,2,2))) { Py_DECREF (mx); Py_DECREF (my); return ERRSS ("Can't get a 2d float array from the z argument."); } if (!(mc=(PyArrayObject *) PyArray_ContiguousFromObject(oc,PyArray_FLOAT,2,2))) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); return ERRSS ("Can't get a 2d float array from the c argument."); } sizex = A_DIM (mx, 0); sizey = A_DIM (my, 0); if ( A_DIM (mz, 0)!=sizey || A_DIM (mz, 1)!=sizex ) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); return ERRSS( "nar4drect: z, x, and y dimensions do not match." ) ;} if ( A_DIM (mc, 0)!=sizey || A_DIM (mc, 1)!=sizex ) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); return ERRSS( "nar4drect: c, x, and y dimensions do not match." ) ; } x = ( float *)A_DATA (mx); y = ( float *)A_DATA (my); z = ( float *)A_DATA (mz); c = ( float *)A_DATA (mc); SpxRect4d(sizey, sizex, x, y, z, sizey, c, sizey, (SPXFILE *)spxfile) ; Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); Py_INCREF(Py_None); return Py_None; } static char nar_nar4dtetra__doc__[] = "Given matrices z, c, y, and x of the same shape, draw the surface." ; static PyObject * nar_nar4dtetra(self, args) /* Really a wrapper for SpxTetra4d. */ PyObject *self; /* Not used */ PyObject *args; { PyObject * oz = NULL, * oc = NULL, * ox = NULL, * oy = NULL; PyArrayObject * mz , *mc , * mx , * my ; int sizex , sizey ; float * x , * y , * z , * c ; long spxfile ; Py_Try( PyArg_ParseTuple(args, "lOOOO", &spxfile , &ox , &oy , &oz, &oc)); GET_ARR(mx,ox,PyArray_FLOAT,2); if (!(my=(PyArrayObject *) PyArray_ContiguousFromObject(oy,PyArray_FLOAT,2,2))) { Py_DECREF (mx); return ERRSS ("Can't get a 2d float array from the y argument.");; } if (!(mz=(PyArrayObject *) PyArray_ContiguousFromObject(oz,PyArray_FLOAT,2,2))) { Py_DECREF (mx); Py_DECREF (my); return ERRSS ("Can't get a 2d float array from the z argument."); } if (!(mc=(PyArrayObject *) PyArray_ContiguousFromObject(oc,PyArray_FLOAT,2,2))) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); return ERRSS ("Can't get a 2d float array from the c argument."); } sizex = A_DIM (mx, 0); sizey = A_DIM (mx, 1); if ( sizex != A_DIM (my, 0) || sizey != A_DIM (my, 1) || sizex != A_DIM (mc, 0) || sizey != A_DIM (mc, 1) || sizex != A_DIM (mz, 0) || sizey != A_DIM (mz, 1) ) {Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); return ERRSS ("nar4dtetra: x, y, and z must have the same shape." ); } x = (float *) A_DATA (mx); y = (float *) A_DATA (my); z = (float *) A_DATA (mz); c = (float *) A_DATA (mc); SpxTetra4d(sizey,sizex,x,sizey,y,sizey,z,sizey,c,sizey,(SPXFILE *)spxfile) ; Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); Py_INCREF(Py_None); return Py_None; } static char nar_narnonstructmesh__doc__[] = "Given vectors x, y, z (nodal coordinates) and c (a physical quantity defined at each node), draw a nonstructured mesh." ; static PyObject * nar_narnonstructmesh(self, args) /* Really a wrapper for SpxNonStruc4d. */ PyObject *self; /* Not used */ PyObject *args; { PyObject * oz = NULL, * ox = NULL, * oy = NULL, * oc = NULL, * ocelldescr = NULL; PyArrayObject * mz , * mx , * my , *mc , *mcelldescr ; int sizex , nocells , nodescr ; float * z , * x , * y , * c ; int * celldescr ; char msg[1000] ; long spxfile ; mz=mx=my=mc=mcelldescr=NULL; nocells=-1; Py_Try(PyArg_ParseTuple(args, "lOOOOOi", &spxfile , &ox, &oy, &oz, &oc, &ocelldescr, &nocells)); GET_ARR (mx, ox, PyArray_FLOAT, 1); if (!(my=(PyArrayObject *) PyArray_ContiguousFromObject(oy,PyArray_FLOAT,1,1))) { Py_DECREF (mx); return ERRSS ("Can't get a 1d float array from the y argument."); } if (!(mz=(PyArrayObject *) PyArray_ContiguousFromObject(oz,PyArray_FLOAT,1,1))) { Py_DECREF (mx); Py_DECREF (my); return ERRSS ("Can't get a 1d float array from the z argument."); } if (!(mc=(PyArrayObject *) PyArray_ContiguousFromObject(oc,PyArray_FLOAT,1,1))) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); return ERRSS ("Can't get a 1d float array from the c argument."); } if (!(mcelldescr=(PyArrayObject *) PyArray_ContiguousFromObject(ocelldescr,PyArray_INT,1,1))) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); return ERRSS ("Can't get a 1d int array from the mcelldescr argument."); } sizex = A_DIM (mx, 0); if ( sizex != A_DIM (my, 0) || sizex != A_DIM (mz, 0) || sizex != A_DIM (mc, 0) ) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); Py_DECREF (mcelldescr); return ERRSS( "narnonstructmesh: x, y, z, and c must be the same size." ); } nodescr = A_DIM (mcelldescr, 0); x = ( float * ) A_DATA (mx); y = ( float * ) A_DATA (my); z = ( float * ) A_DATA (mz); c = ( float * ) A_DATA (mc); celldescr = ( int * ) A_DATA (mcelldescr) ; if ( nodescr < nocells + celldescr[nocells] ) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); Py_DECREF (mcelldescr); return ERRSS ("narnonstructmesh: cell descriptor array too small." ); } SpxNonStruc4d ( sizex, x, y, z, c, nocells, nodescr, celldescr, (SPXFILE *)spxfile ) ; Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); Py_DECREF (mcelldescr); Py_INCREF(Py_None); return Py_None; } static char nar_narstructmesh__doc__[] = "Given vectors x, y, z (nodal coordinates) and c (a physical quantity defined at each node), draw a structured mesh." ; static PyObject * nar_narstructmesh(self, args) /* Really a wrapper for SpxParRect4d. */ PyObject *self; /* Not used */ PyObject *args; { PyObject * oz, * ox, *oy, *oc ; PyArrayObject * mz , * mx , * my , *mc ; int sizex , sizey , sizez ; float * z , * x , * y , * c ; int trans ; /* whether to transpose c array */ long spxfile ; Py_Try( PyArg_ParseTuple(args, "lOOOO", &spxfile , &ox , &oy , &oz , &oc )); GET_ARR (mx, ox, PyArray_FLOAT, 1); if (!(my=(PyArrayObject *) PyArray_ContiguousFromObject(oy,PyArray_FLOAT,1,1))) { Py_DECREF (mx); return ERRSS ("Can't get a 1d float array from the y argument."); } if (!(mz=(PyArrayObject *) PyArray_ContiguousFromObject(oz,PyArray_FLOAT,1,1))) { Py_DECREF (mx); Py_DECREF (my); return ERRSS ("Can't get a 1d float array from the z argument."); } if (!(mc=(PyArrayObject *) PyArray_ContiguousFromObject(oc,PyArray_FLOAT,3,3))) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); return ERRSS ("Can't get a 3d float array from the c argument."); } sizex = A_DIM (mx, 0); sizey = A_DIM (my, 0); sizez = A_DIM (mz, 0); if ( A_DIM (mc, 0)!=sizez || A_DIM (mc, 1)!=sizey || A_DIM (mc, 2)!=sizex ) { Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); return ERRSS ( "narstructmesh: z, x, y, and c dimensions do not match." ); } x = ( float *)A_DATA (mx); y = ( float *)A_DATA (my); z = ( float *)A_DATA (mz); c = ( float *)A_DATA (mc); SpxParRect4d(sizex,sizey,sizez,x,y,z,c,sizex,sizey,(SPXFILE *)spxfile) ; Py_DECREF (mx); Py_DECREF (my); Py_DECREF (mz); Py_DECREF (mc); Py_INCREF(Py_None); return Py_None; } /* List of methods defined in the module */ static struct PyMethodDef nar_methods[] = { {"naropen", nar_naropen, 1, nar_naropen__doc__}, {"narclose", nar_narclose, 1, nar_narclose__doc__}, {"narsync", nar_narsync, 1, nar_narsync__doc__}, {"narquery", nar_narquery, 1, nar_narquery__doc__}, {"narinit", nar_narinit, 1, nar_narinit__doc__}, {"narsetai", nar_narsetai, 1, nar_narsetai__doc__}, {"narsetar", nar_narsetar, 1, nar_narsetar__doc__}, {"narsetac", nar_narsetac, 1, nar_narsetac__doc__}, {"narsetaii", nar_narsetaii, 1, nar_narsetaii__doc__}, {"narsetari", nar_narsetari, 1, nar_narsetari__doc__}, {"narsetaci", nar_narsetaci, 1, nar_narsetaci__doc__}, {"narsetvals", nar_narsetvals, 1, nar_narsetvals__doc__}, {"nar1curve", nar_nar1curve, 1, nar_nar1curve__doc__}, {"narncurves", nar_narncurves, 1, nar_narncurves__doc__}, {"narsurf", nar_narsurf, 1, nar_narsurf__doc__}, {"nar3drect", nar_nar3drect, 1, nar_nar3drect__doc__}, {"nar3dtetra", nar_nar3dtetra, 1, nar_nar3dtetra__doc__}, {"nar4drect", nar_nar4drect, 1, nar_nar4drect__doc__}, {"nar4dtetra", nar_nar4dtetra, 1, nar_nar4dtetra__doc__}, {"narnonstructmesh", nar_narnonstructmesh, 1, nar_narnonstructmesh__doc__}, {"narstructmesh", nar_narstructmesh, 1, nar_narstructmesh__doc__}, {NULL, NULL} /* sentinel */ }; /* Initialization function for the module (*must* be called initnarcisse) */ static char narcisse_module_documentation[] = "" ; void initnarcisse() { PyObject *m, *d; /* Create the module and add the functions */ m = Py_InitModule4("narcisse", nar_methods, narcisse_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); ErrorObject = PyString_FromString("narcisse.error"); PyDict_SetItemString(d, "error", ErrorObject); /* XXXX Add constants here */ nar_narinit ( ( PyObject * ) NULL , ( PyObject * ) NULL ) ; /* Check for errors */ if (PyErr_Occurred()) Py_FatalError("can't initialize module narcisse"); }