Ejemplo n.º 1
0
Object _dxf_BBoxDistance(Object o, float *distance, int flag)
{
    Point b[8];
    Vector v;

    if(!distance || !DXBoundingBox(o, b))
        return NULL;

    v = DXSub(b[7], b[0]);

    switch(flag) {
      case BB_WIDTH:
        *distance = v.x;
        break;

      case BB_HEIGHT:
        *distance = v.y;
        break;

      case BB_DEPTH:
        *distance = v.z;
        break;

      case BB_DIAGONAL:
        *distance = DXLength(v);
        break;

      default:
        DXSetError(ERROR_BAD_PARAMETER, "bad flag value");
        return NULL;
    }


    return o;
}
Ejemplo n.º 2
0
Object _dxf_BBoxPoint(Object o, Point *p, int flag)
{
    Point b[8];
    
    if(!p || !DXBoundingBox(o, b))
        return NULL;

    
    switch(flag) {

      case BB_CENTER:
        p->x = (b[7].x + b[0].x) / 2;
        p->y = (b[7].y + b[0].y) / 2;
        p->z = (b[7].z + b[0].z) / 2;
        break;

      case BB_FRONT:
        p->x = (b[7].x + b[0].x) / 2;
        p->y = (b[7].y + b[0].y) / 2;
        p->z = b[7].z;
        break;

      case BB_BACK:
        p->x = (b[7].x + b[0].x) / 2;
        p->y = (b[7].y + b[0].y) / 2;
        p->z = b[0].z;
        break;

      case BB_RIGHT:
        p->x = b[7].x;
        p->y = (b[7].y + b[0].y) / 2;
        p->z = (b[7].z + b[0].z) / 2;
        break;

      case BB_LEFT:
        p->x = b[0].x;
        p->y = (b[7].y + b[0].y) / 2;
        p->z = (b[7].z + b[0].z) / 2;
        break;

      case BB_TOP:
        p->x = (b[7].x + b[0].x) / 2;
        p->y = b[7].y;
        p->z = (b[7].z + b[0].z) / 2;
        break;

      case BB_BOTTOM:
        p->x = (b[7].x + b[0].x) / 2;
        p->y = b[0].y;
        p->z = (b[7].z + b[0].z) / 2;
        break;

        
      case BB_FRONTTOPRIGHT:
        p->x = b[7].x;
        p->y = b[7].y;
        p->z = b[7].z;
        break;

      case BB_FRONTTOPLEFT:
        p->x = b[0].x;
        p->y = b[7].y;
        p->z = b[7].z;
        break;

      case BB_FRONTBOTRIGHT:
        p->x = b[7].x;
        p->y = b[0].y;
        p->z = b[7].z;
        break;

      case BB_FRONTBOTLEFT:
        p->x = b[0].x;
        p->y = b[0].y;
        p->z = b[7].z;
        break;

      case BB_BACKTOPRIGHT:
        p->x = b[7].x;
        p->y = b[7].y;
        p->z = b[0].z;
        break;

      case BB_BACKTOPLEFT:
        p->x = b[0].x;
        p->y = b[7].y;
        p->z = b[0].z;
        break;

      case BB_BACKBOTRIGHT:
        p->x = b[7].x;
        p->y = b[0].y;
        p->z = b[0].z;
        break;

      case BB_BACKBOTLEFT:
        p->x = b[0].x;
        p->y = b[0].y;
        p->z = b[0].z;
        break;


      default:
        DXSetError(ERROR_BAD_PARAMETER, "bad flag value");
        return NULL;
    }

    return o;
}
Ejemplo n.º 3
0
Error m_SXConstruct( Object *in, Object*out){
/*
*+
*  Name:
*     SXConstruct

*  Purpose:
*     constructs a regular field with regular connections

*  Language:
*     ANSI C

*  Syntax:
*     output = SXConstruct( object, lower, upper, deltas, counts );

*  Classification:
*     Realization

*  Description:
*     The SXConstruct module constructs a field with regular positions
*     and connections covering a volume with specified bounds. It is
*     similar to the standard Construct module, but is somewhat easier to
*     use if a simple grid is required.

*     If "object" is given, its bounds define the extent of the output
*     field. Otherwise, the vectors given for "upper" and "lower" define
*     the extent of the output field.

*     If "deltas" is supplied, it defines the distances between adjacent
*     positions on each axis. It should be a vector with the same number
*     of dimensions as "upper" and "lower", or a single value (in which
*     case the supplied value is used for all axes). The upper and lower
*     bounds are expanded if necessary until they span an integer number
*     of deltas.
*
*     If "deltas" is not supplied, then "counts" must be supplied and
*     should be an integer vector giving the number of positions on each
*     axis, or a single integer (in which case the same value is used for
*     all axes).

*  Parameters:
*     object = field (given)
*        object to define extent of new field [none]
*     lower = vector (Given)
*        explicit lower bounds of new field [none]
*     upper = vector (Given)
*        explicit upper bounds of new field [none]
*     deltas = scalar or vector (Given)
*        increment for each axis
*     counts = integer or vector (Given)
*        number of positions along each axis
*     output = field (Returned)
*        output field

*  Components:
*     The output has "positions", "connections" and "box" components, but
*     no "data" component.

*  Examples:
*     This example imports a scattered data set from "C02.general",
*     extracts a single frame, uses SXConstruct to make a grid covering the
*     bounds of the frame, with increments of 10.0 along each axis, and
*     then uses SXBIN to find the mean data value in each of the square
*     connections of this new grid. the resulting field is displayed.
*
*     data = Import("/usr/lpp/dx/samples/data/CO2.general");
*     frame17 = Select(data,17);
*     newgrid = SXConstruct(frame17,deltas=10);
*     binned = SXBin(frame17,newgrid);
*     coloured = AutoColor(binned);
*     camera = AutoCamera(coloured);
*     Display(coloured,camera);

*  See Also:
*     Construct, Grid

*  Returned Value:
*     OK, unless an error occurs in which case ERROR is returned and the
*     DX error code is set.

*  Copyright:
*     Copyright (C) 1995 Central Laboratory of the Research Councils.
*     All Rights Reserved.

*  Licence:
*     This program is free software; you can redistribute it and/or
*     modify it under the terms of the GNU General Public License as
*     published by the Free Software Foundation; either version 2 of
*     the License, or (at your option) any later version.
*
*     This program is distributed in the hope that it will be
*     useful,but WITHOUT ANY WARRANTY; without even the implied
*     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
*     PURPOSE. See the GNU General Public License for more details.
*
*     You should have received a copy of the GNU General Public License
*     along with this program; if not, write to the Free Software
*     Foundation, Inc., 51 Franklin Street,Fifth Floor, Boston, MA
*     02110-1301, USA

*  Authors:
*     DSB: David Berry (STARLINK)
*     {enter_new_authors_here}

*  History:
*     18-OCT-1995 (DSB):
*        Original version
*     {enter_further_changes_here}

*  Bugs:
*     {note_any_bugs_here}

*-
*/


/*  Local Variables. */


      int      cnt[3];       /* Counts */
      int     *counts;       /* Pointers to counts */
      float    del[3];       /* Deltas */
      float    del3d[9];     /* 3-D Deltas */
      float   *deltas;       /* Pointers to deltas */
      float   *lower;        /* Pointer to lower bounds */
      float   *upper;        /* Pointer to upper bounds */
      float    lbnd[3];      /* lower bounds */
      float    ubnd[3];      /* upper bounds */
      int      ndim;         /* No. of components for each vector */
      int      ndim2;        /* No. of dimensions in second object */
      Object   o=NULL;       /* Output object */
      float    bnd;          /* Current bound value */
      Point    box[8];       /* Bounding box */
      Category cat;          /* Array category */
      Array    array;        /* An array */
      float   *box_ptr;      /* Pointer to box array */
      int      i;            /* Loop count */
      int      j;            /* Loop count */
      int      ncorn;        /* No. of corners in the bounding box */
      int      rank;         /* Array rank */
      float    tmp;          /* Swapping space */
      Type     type;         /* Array numeric type */


/*  If OBJECT was supplied, check it is a field. */

      if( in[0] ){

         if( DXGetObjectClass(in[0]) != CLASS_FIELD ){
            DXSetError( ERROR_BAD_TYPE, "input object is not a field" );
            goto error;
         }


/*  Take a copy of it. */

         o = DXCopy( in[0], COPY_STRUCTURE );


/*  Get the bounding box component from the object */

         array = (Array) DXGetComponentValue( (Field) o, "box" );


/*  If no bounding box was found, create one. */

         if( !array ){
            if( !DXBoundingBox( o, box ) ){
               DXSetError( ERROR_UNEXPECTED, "cannot obtain a bounding box." );
               goto error;
            }
            array = (Array) DXGetComponentValue( (Field) o, "box" );
         }


/*  Get a pointer to the bounding box array and the number of items in
 *  the array, etc. */

         box_ptr = (float *) DXGetArrayData( array );
         DXGetArrayInfo( array, &ncorn, &type, &cat, &rank, &ndim );

         if( type != TYPE_FLOAT ){
            DXSetError( ERROR_BAD_TYPE, "input object positions are not TYPE_FLOAT");
            goto error;
         }

         if( cat != CATEGORY_REAL ){
            DXSetError( ERROR_BAD_TYPE, "input object positions are not REAL");
            goto error;
         }

         if( rank > 1 ){
            DXSetError( ERROR_BAD_TYPE, "input object positions have rank larger than 1");
            goto error;
         }

         if( rank == 0 ) ndim = 1;

         if( ndim > 3 ){
            DXSetError( ERROR_BAD_TYPE, "input object positions have more than 3 dimensions");
            goto error;
         }


/*  Store the bounds for each dimension. */

         for( j=0; j<ndim; j++){
            lbnd[j] = FLT_MAX;
            ubnd[j] = FLT_MIN;
         }

         for( i=0; i<ncorn; i++ ){
            for( j=0; j<ndim; j++ ){
               bnd = *(box_ptr++);
               if( bnd < lbnd[j] ) lbnd[j]=bnd;
               if( bnd > ubnd[j] ) ubnd[j]=bnd;
            }
         }


/*  Delete the copy of the input object */

         DXDelete( o );
         o = NULL;
         array = NULL;


/*  If OBJECT was not supplied, get the bounds from LOWER and UPPER. */

      } else {

         if( !in[1] ) {
            DXSetError( ERROR_MISSING_DATA, "No lower bounds supplied");
            goto error;

         } else {
            lower = SXGet1r( "lower", in[1], &ndim );
            if( !lower ) goto error;

            if( ndim > 3 ){
               DXSetError( ERROR_BAD_TYPE, "lower bounds have more than 3 dimensions");
               goto error;
            }

         }

         if( !in[2] ) {
            DXSetError( ERROR_MISSING_DATA, "No upper bounds supplied");
            goto error;

         } else {
            upper = SXGet1r( "upper", in[2], &ndim2 );
            if( !upper ) goto error;

            if( ndim2 != ndim ){
               DXSetError( ERROR_BAD_TYPE, "number of upper and lower bounds does not match");
               goto error;
            }

         }

         for( j=0; j<ndim; j++){
            lbnd[j] = lower[j];
            ubnd[j] = upper[j];
         }

      }


/*  Ensure bounds are OK. */

      for( j=0; j<ndim; j++ ){
         if( ubnd[j] < lbnd[j] ) {
            tmp = ubnd[j];
            ubnd[j] = lbnd[j];
            lbnd[j] = tmp;
         }
      }


/*  If DELTAS was supplied, get its values and check dimensionality. */

      if( in[3] ){
         deltas = SXGet1r( "deltas", in[3], &ndim2 );

         if( ndim2 == 1 ){
            for( j=0; j<ndim; j++){
               del[j] = *deltas;
            }

         } else {
            if( ndim2 != ndim ){
               DXSetError( ERROR_BAD_TYPE, "incorrect number of deltas given");
               goto error;
            } else {
               for( j=0; j<ndim; j++){
                  del[j] = deltas[j];
               }
            }
         }


/*  Find the corresponding counts and adjust lower bounds */

         for( j=0; j<ndim; j++ ){
            if( del[j] > 0.0 ){
               cnt[j] = 1 + (int) ( 0.9999 + (ubnd[j]-lbnd[j])/del[j] );
               lbnd[j] = 0.5*( ubnd[j] + lbnd[j] - ( cnt[j] - 1 )*del[j] );
            } else {
               DXSetError( ERROR_BAD_TYPE, "negative or zero delta given");
               goto error;
            }
         }


/*  If COUNTS was supplied, get its values and check dimensionality. */

      } else if( in[4] ){
         counts = SXGet1i( "counts", in[4], &ndim2 );

         if( ndim2 == 1 ){
            for( j=0; j<ndim; j++){
               cnt[j] = *counts;
            }

         } else {
            if( ndim2 != ndim ){
               DXSetError( ERROR_BAD_TYPE, "incorrect number of counts given");
               goto error;
            } else {
               for( j=0; j<ndim; j++){
                  cnt[j] = counts[j];
               }
            }
         }


/*  Find corresponding DELTAS */

         for( j=0; j<ndim; j++ ){
            if( cnt[j] > 1 ) {
               del[j] = ( ubnd[j] - lbnd[j] )/( (float) cnt[j] - 1 );

            } else {
               cnt[j] = 1;
               del[j] = 1.0;
               tmp = 0.5*( ubnd[j]+ lbnd[j] );
               ubnd[j] = tmp;
               lbnd[j] = tmp;
            }

         }


/*  report an error if neither COUNTS nor DELTAS was supplied. */

      } else {
         DXSetError( ERROR_MISSING_DATA, "no deltas or counts given");
         goto error;
      }


/*  Construct the n-d delta vectors, form the increments on each axis. */

      for( j=0; j<9; j++ ) del3d[j] = 0.0;
      for( j=0; j<ndim; j++ ) del3d[ j*(ndim+1) ] = del[j];


/*  Create the output field. */

      o = (Object) DXNewField();
      if( !o ) goto error;


/* Create the positions array and put it in the field. */

      array = DXMakeGridPositionsV( ndim, cnt, lbnd, del3d );
      if( !array ) goto error;
      if( !DXSetComponentValue( (Field) o, "positions", (Object) array ) ) goto error;
      array = NULL;


/* Create the connections array and put it in the field. */

      array = DXMakeGridConnectionsV( ndim, cnt );
      if( !array ) goto error;
      if( !DXSetComponentValue( (Field) o, "connections", (Object) array ) ) goto error;
      array = NULL;


/*  Finish the field */

      if( !DXEndField( (Field) o ) ) goto error;


/*  Return the output field. */

      out[0] = o;
      return( OK );

error:
      DXDelete( o );
      return( ERROR );

}
Ejemplo n.º 4
0
static void
Slide2DEndStroke(void *data, DXMouseEvent *event)
{
    Slide2DData sdata = (Slide2DData)data;
    int b = WHICH_BUTTON(event);
    int dx, dy;
    Object member;
    char *name;
    Point corners[8];
    int i;

    if (!sdata)
	return;

    sdata = (Slide2DData)data;
    if (! sdata)
	return;
    
    dx = sdata->buttonPosition[b].x - event->x;
    dy = -(sdata->buttonPosition[b].y - event->y);

    sdata->buttonPosition[b].x = event->x;
    sdata->buttonPosition[b].y = event->y;

    sdata->strokeStart = 1;
    
    /*
     * End stroke.  If its the left button or up'n'downish right button,
     * we operate on a member of the scene group.  If its a left'n'right
     * middle button, we operate on the camera
     */
    if (b == 0 || ((b == 1) && (abs(dy) > abs(dx))))
    {
	Group og = (Group)sdata->obj, ng;

	/*
	 * Can't do anything if we don't have a scene object group or an 
	 * arg telling us what member to operate on
	 */
	if ((sdata->label == NULL && sdata->index == -1) || !sdata->obj)
	    return;

	/*
	 * Create a new group header.
	 */
	ng = (Group)DXCopy(sdata->obj, COPY_ATTRIBUTES);
	if (! ng)
	    return;

	/*
	 * Loop through the scene object group.  For each member NOT matching
	 * the argument, just copy it into the new group.  Otherwise, twiddle
	 * its transform matrix and put it there.
	 */
	i = 0;
	while (NULL != (member = DXGetEnumeratedMember((Group)og, i++, &name)))
	{
	    if ((sdata->label && !strcmp(name, sdata->label)) 
		    || ((i-1) == sdata->index))
	    {
		Object attr;

		/* 
		 * This is the one to manipulate.  It better be a 
		 * 'transformed object' type.
		 */

		attr = DXGetAttribute(member, "object type");
		if (! attr)
		    continue;
		
		if (strcmp(DXGetString((String)attr), "transformed object"))
		    continue;

		if (b == 0)
		{
		    Vector x;
		    Xform oldx = (Xform)member;
		    Matrix oldm, newm;
		    Object xchild;

		    /*
		     * Its the left button.  Determine the world space
		     * vector corresponding to the screen-space stroke, and
		     * concatenate it onto the matrix already associated with
		     * the object, and create a new DX Transform object with
		     * the old transforms child and the concatenated matrices.
		     */

		    x.x = -(dx * sdata->gt);
		    x.y = -(dy * sdata->gt);
		    x.z = 0.0;

		    DXGetXformInfo(oldx, &xchild, &oldm);

		    newm = DXTranslate(x);
		    newm = DXConcatenate(oldm, newm);
		    member = (Object)DXNewXform(xchild, newm);
		    DXSetAttribute(member, "object type", attr);
		}
		else if (DXBoundingBox(member, corners))
		{
		    Angle r;
		    Xform oldx = (Xform)member;
		    Matrix oldm, newm;
		    Object xchild;
		    Vector center;

		    /*
		     * Then its an up'n'down middle button stroke. Create
		     * a matrix that transforms the object back to the origin,
		     * rotates it, and then back to where it was.
		     */


		    DXGetXformInfo(oldx, &xchild, &oldm);

		    /*
		     * Move the object so its center is at the origin
		     */
		    center.x = -(corners[0].x + corners[7].x) / 2.0;
		    center.y = -(corners[0].y + corners[7].y) / 2.0;
		    center.z = -(corners[0].z + corners[7].z) / 2.0;
		    newm = DXTranslate(center);
		    oldm = DXConcatenate(oldm, newm);


		    /*
		     * Rotate
		     */
		    r = dy * sdata->gr * (2*3.14159);
		    newm = DXRotateZ(r);
		    oldm = DXConcatenate(oldm, newm);

		    /*
		     * Move the object back to its original location
		     */
		    center.x = -center.x;
		    center.y = -center.y;
		    center.z = -center.z;
		    newm = DXTranslate(center);
		    oldm = DXConcatenate(oldm, newm);

		    member = (Object)DXNewXform(xchild, oldm);
		    DXSetAttribute(member, "object type", attr);
		}
	    }
	    DXSetMember(ng, name, member);
	}

	DXDelete(sdata->obj);
	sdata->obj = DXReference((Object)ng);


    }
    else if ((b == 1) && (abs(dx) > abs(dy)))
    {
	/*
	 * Its a left'n'right middle button.  Alter the camera's width
	 * parameter based on a scaled stroke dx.
	 */
	sdata->width += (sdata->width * dx)/sdata->w;
    }

    return;

}
Ejemplo n.º 5
0
static Error saydata(Object o, char *opt)
{
    Array a;
    int nitems;
    Type type;
    Category category;
    int rank;
    int shape[MAXRANK];
    int valids;
    Point boxlist[8];
    Point vboxlist[8];
    float min, max, avg;

    if (DXGetObjectClass(o) == CLASS_ARRAY) {
	DXGetArrayInfo((Array)o, &nitems, &type, &category, &rank, shape);
	pinfo(1, nitems, nitems, type, category, rank, shape);
    } else if (DXGetObjectClass(o) == CLASS_FIELD) {
	a = (Array)DXGetComponentValue((Field)o, "positions");
	if (!a) {
	    DescribeMsg("The Field does not contain any positions.  It will not cause an error, but will be\n");
	    DescribeMsg("silently ignored by most modules since positions are required.\n");
	    DescribeMsg("Use the `Mark' or `Replace' module to create a `positions' component.\n");
	}
	a = (Array)DXGetComponentValue((Field)o, "data");
	if (!a) {
	    DescribeMsg("The Field contains nothing marked as data items.\n");
            DescribeMsg("If the Field does contain data under another name, use the `Mark' module\n");
            DescribeMsg("to select what should be used as data.\n");
	} else {
	    DXGetArrayInfo(a, &nitems, &type, &category, &rank, shape);
	    if (!validcount((Field)o, "data", &valids))
		return ERROR;
	    pinfo(1, nitems, valids, type, category, rank, shape);
	}
    } else if (!DXGetType((Object)o, &type, &category, &rank, shape)) {
	/* DescribeMsg("no data type information\n"); */
	DXResetError();
    } else
	pinfo(0, 0, 0, type, category, rank, shape);

    /* get bbox and print it in a non-threatening format */
    if (!DXBoundingBox(o, boxlist)) {
	/* DescribeMsg("Cannot get information about the positions of the data\n"); */
	DXResetError();
    } else {
	DescribeMsg("The positions are enclosed within the box defined by the corner points:\n");
	DescribeMsg("[ %g %g %g ] and [ %g %g %g ]\n", 
		  boxlist[0].x, boxlist[0].y, boxlist[0].z,
		  boxlist[7].x, boxlist[7].y, boxlist[7].z);
    }
    if (!DXValidPositionsBoundingBox(o, vboxlist)) {
	/* DescribeMsg("Cannot get information about the valid positions of the data\n"); */
	DXResetError();
    } else {
	if ((boxlist[0].x != vboxlist[0].x) || (boxlist[7].x != vboxlist[7].x)
	 || (boxlist[0].y != vboxlist[0].y) || (boxlist[7].y != vboxlist[7].y)
	 || (boxlist[0].z != vboxlist[0].z) || (boxlist[7].z != vboxlist[7].z)) {
	    DescribeMsg("The VALID positions are enclosed within the box defined by the corner points:\n");
	    DescribeMsg("[ %g %g %g ] and [ %g %g %g ]\n", 
		      vboxlist[0].x, vboxlist[0].y, vboxlist[0].z,
		      vboxlist[7].x, vboxlist[7].y, vboxlist[7].z);
	}
    }

    /* something about data stats */
    if (!DXStatistics(o, "data", &min, &max, &avg, NULL)) {
	/* DescribeMsg("Cannot get information about the data values\n"); */
	DXResetError();
    } else {
	DescribeMsg("Data range is:\n");
	DescribeMsg("minimum = %g, maximum = %g, average = %g\n", 
		    min, max, avg);
	if (rank > 0) {
	    /* ??? call vectorstats here if rank >= 1 
	     * look at the code in histogram; does rank=1, nothing
	     * about larger.
	     */
	    DescribeMsg("(These are the scalar statistics which will be used by modules\n");
	    DescribeMsg("which need scalar values.  The length is computed for vectors and\n");
	    DescribeMsg("the determinant for matricies.)\n");
	}
    }
    return OK;
	
}