Ejemplo n.º 1
0
static Error
_newQMesh(int nStrips, int nStrippedPts, QMesh *mesh, dxObject *o)
{
    Private priv = NULL;
    QMesh tmp = NULL;

    *mesh = NULL;
    *o = NULL;

    tmp = (QMesh)DXAllocateZero(sizeof(QMeshS));
    if (! tmp)
        return ERROR;

    tmp->meshArray = DXNewArray(TYPE_INT, CATEGORY_REAL, 1, 2);
    if (! tmp->meshArray)
        goto error;

    DXReference((dxObject)tmp->meshArray);

    if ( !DXAllocateArray (tmp->meshArray, nStrips))
        goto error;

    tmp->connectionArray = DXNewArray(TYPE_INT, CATEGORY_REAL, 0);
    if (! tmp->connectionArray)
        goto error;

    DXReference((dxObject)tmp->connectionArray);

    if ( !DXAllocateArray (tmp->connectionArray, nStrippedPts))
        goto error;

    tmp->meshes       = (int *)DXGetArrayData(tmp->meshArray);
    tmp->connections  = (int *)DXGetArrayData(tmp->connectionArray);
    tmp->nmeshes      = nStrips;
    tmp->nconnections = nStrippedPts;

    priv = (Private)DXNewPrivate((Pointer)tmp, _deleteQMesh);
    if (! priv)
       goto error;

    *mesh = tmp;
    *o = (dxObject)priv;

    return OK;

error:
    if (tmp)
    {
        if (tmp->connectionArray)
            DXDelete((dxObject)tmp->connectionArray);
        if (tmp->meshArray)
            DXDelete((dxObject)tmp->meshArray);

        DXFree((Pointer)tmp);
    }

    return ERROR;
}
Ejemplo n.º 2
0
static Error 
ExtractMatrix(Object o, Matrix *m)
{
    Pointer p;
    int i, items, shape[2];
    Type type;
    float *fp;

    if (DXGetObjectClass(o) != CLASS_ARRAY)
	return ERROR;
    
    if (!DXTypeCheck((Array)o, TYPE_FLOAT, CATEGORY_REAL, 2, 3, 3) &&
	!DXTypeCheck((Array)o, TYPE_FLOAT, CATEGORY_REAL, 2, 4, 3) &&
        !DXTypeCheck((Array)o, TYPE_INT, CATEGORY_REAL, 2, 3, 3) &&
	!DXTypeCheck((Array)o, TYPE_INT, CATEGORY_REAL, 2, 4, 3))
	return ERROR;

    if (!DXGetArrayInfo((Array)o, &items, &type, NULL, NULL, shape))
	return ERROR;

    if (items != 1)
	return ERROR;

    p = DXGetArrayData((Array)o);
    items = shape[0] * shape[1];

    if (type == TYPE_FLOAT)
	memcpy((char *)m, (char *)p, items * sizeof(float));
    else
	for (i=0, fp=(float *)m; i<items; i++, fp++)
	    *fp = (float)((int *)p)[i];

    return OK;
}
Ejemplo n.º 3
0
static void Negate(Array a)
{
    Type t;
    Pointer value;
    
    if (!DXGetArrayInfo(a, NULL, &t, NULL, NULL, NULL))
	return;
    
    value = DXGetArrayData(a);
    if (!value)
	return;
    
    switch (t) {
      case TYPE_BYTE:   *(byte *)value = - *(byte *)value;  break;
      case TYPE_SHORT:  *(short *)value = - *(short *)value;  break;
      case TYPE_INT:    *(int *)value = - *(int *)value;  break;
      case TYPE_FLOAT:  *(float *)value = - *(float *)value;  break;
      case TYPE_DOUBLE: *(double *)value = - *(double *)value;  break;
	
      case TYPE_UBYTE:
      case TYPE_USHORT:
      case TYPE_UINT:
      default:
	/* can't do anything with the unsigned values */
	break;
    }
    
}
Ejemplo n.º 4
0
/* return whether the value is zero or not.  1 = yes, 0 = no
 * assumed to be a single item array, scalar.
 */
static int IsZero(Array a)
{
    Type t;
    Pointer value;
    
    if (!DXGetArrayInfo(a, NULL, &t, NULL, NULL, NULL))
	return 0;

    value = DXGetArrayData(a);
    if (!value)
	return 0;

    switch (t) {
        case TYPE_BYTE:   return (byte)0     == *(byte *)value;
        case TYPE_UBYTE:  return (ubyte)0    == *(ubyte *)value;
        case TYPE_SHORT:  return (short)0    == *(short *)value;
        case TYPE_USHORT: return (ushort)0   == *(ushort *)value;
        case TYPE_INT:    return (int)0      == *(int *)value;
        case TYPE_UINT:   return (uint)0     == *(uint *)value;
        case TYPE_FLOAT:  return (float)0.0  == *(float *)value;
        case TYPE_DOUBLE: return (double)0.0 == *(double *)value;
        default:	  return 0;
    }

    /* NOTREACHED */
}
Ejemplo n.º 5
0
/* return 1 if value is negative, 0 if >= 0
 */
static int IsNegative(Array a)
{
    Type t;
    Pointer value;
    
    if (!DXGetArrayInfo(a, NULL, &t, NULL, NULL, NULL))
	return 0;
    
    value = DXGetArrayData(a);
    if (!value)
	return 0;
    
    switch (t) {
      case TYPE_BYTE:   return (*(byte *)value < (byte)0);
      case TYPE_SHORT:  return (*(short *)value < (short)0);
      case TYPE_INT:    return (*(int *)value < 0);
      case TYPE_FLOAT:  return (*(float *)value < 0.0);
      case TYPE_DOUBLE: return (*(double *)value < 0.0);
	
      case TYPE_UBYTE:
      case TYPE_USHORT:
      case TYPE_UINT:
      default:
	return 0;
    }
    /* NOT REACHED */
}
Ejemplo n.º 6
0
/* return whether two values are the same or not.  in this case, we
 * don't care what the values are, so a byte-by-byte compare is good enough.
 */
static int IsEqual(Array a, Array b)
{
    int size;
    Pointer valueA, valueB;
    
    size = DXGetItemSize(a);
    
    valueA = DXGetArrayData(a);
    valueB = DXGetArrayData(b);
    
    if (size <= 0 || !valueA || !valueB)
	return 0;

    if (memcmp(valueA, valueB, size) == 0)
	return 1;

    return 0;
}
Ejemplo n.º 7
0
static uint32
computeArrayRecipe (Array a)
{
    uint32 		crc;
    Type		type;
    Category		category;
    int			items;
    int			rank;
    int			shape[32];
    int			i, size, tsize;
    unsigned char	*p;

    crc = 0xFFFFFFFF;

    DXGetArrayInfo (a, &items, &type, &category, &rank, shape);
    size = DXGetItemSize(a);
    tsize = DXTypeSize(type);

    crc = _dxf_ExCRCByte (crc, type);
    crc = _dxf_ExCRCByte (crc, category);
    crc = _dxf_ExCRCInt  (crc, items);
    crc = _dxf_ExCRCByte (crc, rank);

    if(DXGetArrayClass(a) == CLASS_REGULARARRAY) {
        Pointer origin;
        Pointer delta; 

        origin = DXAllocateLocal(2*size);
        delta = (Pointer)((char *)origin + size);
        DXGetRegularArrayInfo((RegularArray)a, NULL, origin, delta);
	crc = _dxf_ExCRCByteV (crc, (unsigned char *) "regulararray", 1, 12);
	crc = _dxf_ExCRCByteV (crc, origin, tsize, 2*size/tsize);
        DXFree(origin);
    }
    else {
        p = (unsigned char *) DXGetArrayData (a);
        if (p)
        {
	    if (rank)
	        for (i=0; i < rank; i++)
		    crc = _dxf_ExCRCInt (crc, shape[i]);
	    size *= items;
	    crc = _dxf_ExCRCByteV (crc, p, tsize, size/tsize);
        }
        else
        {
            crc = 0xFFFFFFFF;
	    crc = _dxf_ExCRCInt (crc, 0);
        }
    }

    return (EXTAG(crc));
}
Ejemplo n.º 8
0
Error
_dxf_polylinesToPlines (xfieldT *xf)
{
  int		i;
  int		start, end, knt;
  int		*mesh;

  ENTRY(("_dxf_linesToPlines(0x%x)", xf));
  
  /* allocate permanent xfield pline data of appropriate size */
  /* Allocations are a guess based on 100 lines/polyline */

  if (!(xf->meshes = DXNewArray(TYPE_INT, CATEGORY_REAL, 1, 2)) ||
      !(DXAllocateArray (xf->meshes, xf->npolylines)))
    {
      PRINT(("could not allocate xfield mesh data"));
      DXErrorGoto(ERROR_NO_MEMORY, "#13000") ;
    }

  mesh = (int *)DXGetArrayData(xf->meshes);

  for (i = 0; i < xf->npolylines; i++)
  {
      start = xf->polylines[i];
      end   = (i+1 == xf->npolylines) ? xf->nedges : xf->polylines[i+1];
      knt   = end - start;

      if(xf->invCntns && !DXIsElementValid(xf->invCntns,i)) continue;

      *mesh++ = start;
      *mesh++ = knt;
  }

  xf->connections_array = (Array)DXReference((dxObject)xf->edges);
  xf->nconnections = xf->nedges;

  xf->nmeshes = xf->npolylines;

  /* record connection info */
  xf->posPerConn = 1 ;
  xf->connectionType = ct_pline;

  EXIT(("OK"));
  return OK ;

 error:

  if(xf->meshes) DXDelete((dxObject)xf->meshes);

  EXIT(("ERROR"));
  return 0 ;
}
Ejemplo n.º 9
0
static Quadruple
*getNeighbors (xfieldT *xf)
{
  /*
   *  Gets an array giving all the neighbors of a given quad.
   *  neighbor[quad].p[n] is the quad adjacent to quad quad, across from
   *  quad quad's nth point.  A -1 indicates no quad is adjacent across
   *  from the nth point.
   *
   *  If connections are expressed in a compact representation, then no
   *  neighbors array is necessary.
   */

  ENTRY(("getNeighbors(0x%x)", xf));

  if (DXGetArrayClass(xf->connections_array) == CLASS_MESHARRAY)
    {
      EXIT(("CLASS_MESHARRAY"));
      return 0 ;
    }
  else
    {
      if (!xf->neighbors_array)
	{
	  EXIT(("couldn't get neighbors from xfield"));
	  DXErrorReturn (ERROR_INTERNAL, "#13870") ;
	}

      if (!DXTypeCheck (xf->neighbors_array, TYPE_INT, CATEGORY_REAL, 1, 4))
	{
	  EXIT(("neighbors array has bad type"));
	  DXErrorReturn (ERROR_INTERNAL, "#13870") ;
	}

      EXIT((""));
      return (Quadruple *) DXGetArrayData(xf->neighbors_array) ;
    }
}
Ejemplo n.º 10
0
/* item[n] = start + n * delta */
static 
Array MakeLinearList(Array start, Array end, int *n, Array delta)
{
    int i, j;
    Array a_start = NULL, a_end = NULL, a_delta = NULL;
    int delstart = 0, delend = 0, deldelta = 0;
    Array alist[3];
    Array output = NULL;
    int count = 1;
    int bytes;
    Type t;
    Category c;
    int rank;
    int shape[MAXSHAPE];
    int nitems;
    int i_start, i_end, i_delta;
    float f_start, f_end, f_delta, f_count;
    Pointer dp;
    int *ip;
    Object in[MAXCOMPINPUTS];  /* hardcoded in compute */
    Object out;
    String compstr = NULL;
    char cbuf[64];
    Error rc;

    /* do this or die in compute */
    for (i=0; i<MAXCOMPINPUTS; i++)
	in[i] = NULL;

    /* find common format of start, end, delta and check for 4 parms */
    i = 0;
    if (start)
	alist[i++] = start; 

    if (end)
	alist[i++] = end;

    if (delta)
	alist[i++] = delta;

    if (n) {
	count = *n;
	if (i == 3) {
	    DXWarning("too many inputs specified; ignoring delta");
	    i--;
	    delta = NULL;
	} 
    } 
    else if (i == 2)
	count = 2;

    
    if (i < 2) {
	DXSetError(ERROR_BAD_PARAMETER, 
		   "not enough inputs specified to generate a list");
	return NULL;
    }

    if (!DXQueryArrayCommonV(&t, &c, &rank, shape, i, alist)) {
	DXAddMessage("start, end and/or delta");
	return NULL;
    }

    /* shortcut the process here if the data is scalar integer or
     *  scalar float.  otherwise, if the data is vector or ubyte
     *  or whatever, fall through and use Compute so we can increment
     *  by irregular values.
     */
    if (t != TYPE_INT && t != TYPE_FLOAT)
	goto complicated;
    if (c != CATEGORY_REAL || rank != 0)
	goto complicated;


    /* compute missing value(s):
     * start = end - ((count - 1) * delta) 
     * end = start + ((count - 1) * delta) 
     * count = ((end - start) / delta) + 1 
     * delta = (end - start) / (count - 1) 
     */

    /* convert to the common format */
    if (start)
	a_start = DXArrayConvertV(start, t, c, rank, shape);
    if (end)
	a_end   = DXArrayConvertV(end,   t, c, rank, shape);
    if (delta)
	a_delta = DXArrayConvertV(delta, t, c, rank, shape);


    /* for integer, scalar lists */
    if (t == TYPE_INT) {
	if (!start) {
	    i_end = *(int *)DXGetArrayData(a_end);
	    i_delta = *(int *)DXGetArrayData(a_delta);
	    
	    i_start = i_end - ((count - 1) * i_delta);
	}

	if (!end) {
	    i_start = *(int *)DXGetArrayData(a_start);
	    i_delta = *(int *)DXGetArrayData(a_delta);
	    
	    i_end = i_start + ((count - 1) * i_delta);
	} 

	if (!delta) {
	    /* if count == 1, generate a zero of the right type.  otherwise
	     *  divide to figure out the right delta to make count-1 steps 
	     *  between start and end.  it's count-1 because if you want
	     *  N numbers between start and end, you have N-1 increments.
	     */
	    i_start = *(int *)DXGetArrayData(a_start);
	    i_end = *(int *)DXGetArrayData(a_end);
	    if (count == 1)
		i_delta = 0;
	    else
		i_delta = (i_end - i_start) / (count - 1);
	    
	    /* try to catch the case where delta ends up being 0 (like
	     * because the inputs are int and the count is larger than
	     * the difference between start and end).  allow it to be zero
	     * only if start == end;  i suppose if you ask for 10 things
	     * where start == end you should be able to get them.
	     */
	    if (i_delta == 0 && i_start != i_end) {
		DXSetError(ERROR_BAD_PARAMETER, 
		     "count too large to generate list between start and end");
		goto error;
	    }
	    
	}

	/* if all three arrays are there, count must be missing */
	if (i == 3) {
	    i_start = *(int *)DXGetArrayData(a_start);
	    i_end = *(int *)DXGetArrayData(a_end);
	    i_delta = *(int *)DXGetArrayData(a_delta);

	    if (i_delta == 0)
		count = 1;
	    else {
		if ((i_end >= i_start && i_delta > 0) ||
		    (i_end < i_start && i_delta < 0))
		    count = (int)(((double)i_end-i_start) / (double)i_delta) +1;
		else {
		    if (i_delta < 0)
			DXSetError(ERROR_BAD_PARAMETER,
			   "delta must be positive if start is less than end");
		    else
			DXSetError(ERROR_BAD_PARAMETER,
			   "delta must be negative if end is less than start");
		    goto error;
		}
	    }
	}

	output = (Array)DXNewRegularArray(TYPE_INT, 1, count, 
					 (Pointer)&i_start, (Pointer)&i_delta);
    }

    /* for float, scalar lists */
    if (t == TYPE_FLOAT) {
	if (!start) {
	    f_end = *(float *)DXGetArrayData(a_end);
	    f_delta = *(float *)DXGetArrayData(a_delta);
	    
	    f_start = f_end - ((count - 1.0) * f_delta);
	}

	if (!end) {
	    f_start = *(float *)DXGetArrayData(a_start);
	    f_delta = *(float *)DXGetArrayData(a_delta);
	    
	    f_end = f_start + ((count - 1.0) * f_delta);
	}

	if (!delta) {
	    /* if count == 1, generate a zero of the right type.  otherwise
	     *  divide to figure out the right delta to make count-1 steps 
	     *  between start and end.  it's count-1 because if you want
	     *  N numbers between start and end, you have N-1 increments.
	     */
	    f_start = *(float *)DXGetArrayData(a_start);
	    f_end = *(float *)DXGetArrayData(a_end);
	    if (count == 1)
		f_delta = 0.0;
	    else 
		f_delta = (f_end - f_start) / (count - 1.0);

	    /* try to catch the case where delta ends up being 0 (like
	     * because the inputs are int and the count is larger than
	     * the difference between start and end).  allow it to be zero
	     * only if start == end;  i suppose if you ask for 10 things
	     * where start == end you should be able to get them.
	     */
	    if (f_delta == 0.0 && f_start != f_end) {
		DXSetError(ERROR_BAD_PARAMETER, 
		   "count too large to generate list between start and end");
		goto error;
	    }
	}

	/* if all three arrays are there, count must be missing */
	if (i == 3) {
	    f_start = *(float *)DXGetArrayData(a_start);
	    f_end = *(float *)DXGetArrayData(a_end);
	    f_delta = *(float *)DXGetArrayData(a_delta);

	    if (f_delta == 0.0)
		count = 1;
	    else {
		if ((f_end >= f_start && f_delta > 0) ||
		    (f_end < f_start && f_delta < 0)) {
		    /* the intermediate float variable below is to minimize
		     * float round-off error.  if delta is 0.1 and you
		     * ask for a list between 0 and 1, it does the math in
		     * double, the delta used is actually 0.10000001, and 
		     * you get counts = 10.9999999 instead of 11.  when
		     * converted directly to int it becomes just 10 and your 
		     * list ends at 0.9 instead of 1.  
		     * math in base 2 has some problems.
		     */
		    f_count = ((f_end - f_start) / f_delta) +1;
		    count = (int)f_count;
		} else {
		    if (f_delta < 0)
			DXSetError(ERROR_BAD_PARAMETER,
			   "delta must be positive if start is less than end");
		    else
			DXSetError(ERROR_BAD_PARAMETER,
			   "delta must be negative if end is less than start");
		    goto error;
		}
	    }
	}

	output = (Array)DXNewRegularArray(TYPE_FLOAT, 1, count, 
					 (Pointer)&f_start, (Pointer)&f_delta);
    }
    
    DXDelete((Object)a_start);
    DXDelete((Object)a_end);
    DXDelete((Object)a_delta);
    
    /* return Array */
    return output;
    

    /* input is a vector, or a data type different from int or float.
     * use compute so this code doesn't have to be replicated for each
     * different shape and type.
     */

  complicated:
    nitems = 1;
    for (j=0; j<rank; j++)
	nitems *= shape[j];

    /* compute missing value(s):
     * start = end - ((count - 1) * delta) 
     * end = start + ((count - 1) * delta) 
     * count = ((end - start) / delta) + 1 
     * delta = (end - start) / (count - 1) 
     */

    if (!start) {
	compstr = DXNewString("$0 - (($1 - 1) * $2)");
	if (!compstr)
	    goto error;
	
	in[0] = (Object)compstr;
	in[1] = (Object)end;
	in[3] = (Object)delta;
	in[2] = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, 0);
	if (!in[2])
	    goto error;
	if (!DXAddArrayData((Array)in[2], 0, 1, (Pointer)&count))
	    goto error;

	/* i need to explain this - it's basically so if compute was 
         * going to try to cache this, it could add a reference and
         * then later when i call delete the object won't get deleted
         * out from underneath compute.  (i know compute doesn't cache
         * things, but a different module might.)
	 */
	DXReference((Object)compstr);
	DXReference(in[2]);

	rc = m_Compute(in, &out);

	DXDelete((Object)compstr);
	compstr = NULL;
	DXDelete(in[2]);
	in[2] = NULL;

	if (rc == ERROR)
	    goto error;

	start = (Array)out;
	delstart++;
    }

    if (!end) {
	compstr = DXNewString("$0 + (($1 - 1) * $2)");
	if (!compstr)
	    goto error;
	
	in[0] = (Object)compstr;
	in[1] = (Object)start;
	in[3] = (Object)delta;
	in[2] = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, 0);
	if (!in[2])
	    goto error;
	if (!DXAddArrayData((Array)in[2], 0, 1, (Pointer)&count))
	    goto error;

	DXReference((Object)compstr);
	DXReference(in[2]);

	rc = m_Compute(in, &out);

	DXDelete((Object)compstr);
	compstr = NULL;
	DXDelete(in[2]);
	in[2] = NULL;

	if (rc == ERROR)
	    goto error;

	end = (Array)out;
	delend++;
    }

    if (!delta) {
	/* if count == 1, generate a zero of the right type.  otherwise
         *  divide to figure out the right delta to make count-1 steps 
	 *  between start and end.  it's count-1 because if you want
         *  N numbers between start and end, you have N-1 increments.
	 */
	if (count == 1)
	    compstr = DXNewString("$1 - $1");
	else
	    compstr = DXNewString("($2 - $0) / ($1 - 1)");
	if (!compstr)
	    goto error;
	
	in[0] = (Object)compstr;
	in[1] = (Object)start;
	in[3] = (Object)end;
	in[2] = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, 0);
	if (!in[2])
	    goto error;
	if (!DXAddArrayData((Array)in[2], 0, 1, (Pointer)&count))
	    goto error;

	DXReference((Object)compstr);
	DXReference(in[2]);

	rc = m_Compute(in, &out);

	DXDelete((Object)compstr);
	compstr = NULL;
	DXDelete(in[2]);
	in[2] = NULL;

	if (rc == ERROR)
	    goto error;

	delta = (Array)out;
	deldelta++;

	/* try to catch the case where delta ends up being 0 (like
	 * because the inputs are int and the count is larger than
	 * the difference between start and end).  allow it to be zero
	 * only if start == end;  i suppose if you ask for 10 things
	 * where start == end you should be able to get them.
	 */
	if (IsZero(delta) && !IsEqual(start, end)) {
	    DXSetError(ERROR_BAD_PARAMETER, 
		    "count too large to generate list between start and end");
	    goto error;
	}

    }

    /* if all three arrays are there, count must be missing */
    if (i == 3) {
	char tbuf[512];
	int firsttime = 1;
	int lastcount = 0;

	/* this loop allows us to to handle vectors or matricies as
	 *  well as scalars.   it requires that the deltas compute to
         *  a consistent count.  like start=[0 2 4], end=[4 8 16],
	 *  would work if delta=[1 2 4] but not if delta was [1 2 2].
	 */
	for (j=0; j < nitems; j++) {
	    /* i think this code only works for vectors - i'm not sure
             * what it will do with rank=2 data.
	     */

	    /* this point of this next compute expression:
	     * if the delta is 0, don't divide by zero - the count is 1. 
	     * if the end is smaller than the start, the delta has to be
             *  negative.  if it's not, return -1.  you can't generate a
             *  negative count from the equations, so this is a safe signal.
	     */
	    sprintf(tbuf, 
		    "float($2.%d) == 0.0   ? "
		    "  1 : "
		    " (  (($1.%d >= $0.%d) && ($2.%d > 0) || "
		    "     ($1.%d <  $0.%d) && ($2.%d < 0))    ? "
		    "       int(float($1.%d - $0.%d) / float($2.%d)) + 1 : "
		    "       -1 ) ", 
		    j, j, j, j, j, j, j, j, j, j);
	    compstr = DXNewString(tbuf);
	    if (!compstr)
		goto error;
	    
	    in[0] = (Object)compstr;
	    in[1] = (Object)start;
	    in[2] = (Object)end;
	    in[3] = (Object)delta;
	    
	    DXReference((Object)compstr);

	    rc = m_Compute(in, &out);
	    
	    DXDelete((Object)compstr);
	    compstr = NULL;
	    
	    if (rc == ERROR)
		goto error;
	    
	    if (!DXExtractInteger(out, &count)) {
		DXSetError(ERROR_BAD_PARAMETER, 
			   "can't compute number of items");
		goto error;
	    }

	    DXDelete((Object)out);
	    if (count == 0)
		continue;

	    if (count < 0) {
		if (IsNegative(delta))
		    DXSetError(ERROR_BAD_PARAMETER,
			 "delta must be positive if start is less than end");
		else
		    DXSetError(ERROR_BAD_PARAMETER,
			 "delta must be negative if end is less than start");
		goto error;
	    }

	    if (firsttime) {
		lastcount = count;
		firsttime = 0;
	    } else {
		if (count != lastcount) {
		    DXSetError(ERROR_BAD_PARAMETER, 
			   "inconsistent number of items required by inputs");
		    goto error;
		}
	    }
	}    
    }

    /* now have 4 consistant values - once again make sure they are
     * converted into an identical format.
     */
    a_start = DXArrayConvertV(start, t, c, rank, shape);
    a_end   = DXArrayConvertV(end,   t, c, rank, shape);
    a_delta = DXArrayConvertV(delta, t, c, rank, shape);

    /* make empty array with n items */
    output = DXNewArrayV(t, c, rank, shape);
    if (!output)
	goto error;

    if (!DXAddArrayData(output, 0, count, NULL))
	goto error;

    dp = DXGetArrayData(output);
    if (!dp)
	goto error;

    /* foreach n */
    /*  call compute to add delta */
    /*  memcpy to right offset in array */
    /* end */

    bytes = DXGetItemSize(output);

    sprintf(cbuf, "%s($0 + ($1 * $2))", TypeName(t));
    compstr = DXNewString(cbuf);
    if (!compstr)
	goto error;
    
    in[0] = (Object)compstr;
    in[1] = (Object)a_start;
    in[3] = (Object)a_delta;

    in[2] = (Object)DXNewArray(TYPE_INT, CATEGORY_REAL, 0);
    if (!in[2])
	goto error;
    if (!DXAddArrayData((Array)in[2], 0, 1, NULL))
	goto error;
    ip = (int *)DXGetArrayData((Array)in[2]);
    
    DXReference((Object)compstr);
    DXReference(in[2]);

    for (i=0; i<count; i++) {

	*ip = i;

	rc = m_Compute(in, &out);
	if (rc == ERROR)
	    goto error;

	memcpy(INCVOID(dp, bytes*i), DXGetArrayData((Array)out), bytes);
	DXDelete((Object)out);
    }

    DXDelete((Object)compstr);
    DXDelete(in[2]);
    DXDelete((Object)a_start);
    DXDelete((Object)a_end);
    DXDelete((Object)a_delta);
    if (delstart)
	DXDelete((Object)start);
    if (delend)
	DXDelete((Object)end);
    if (deldelta)
	DXDelete((Object)delta);

    /* return Array */
    return output;
    
  error:
    DXDelete((Object)output);
    DXDelete((Object)compstr);
    DXDelete((Object)a_start);
    DXDelete((Object)a_end);
    DXDelete((Object)a_delta);
    if (delstart)
	DXDelete((Object)start);
    if (delend)
	DXDelete((Object)end);
    if (deldelta)
	DXDelete((Object)delta);

    return NULL;
}
Ejemplo n.º 11
0
static Error DoSXEnum( Object o, char *name, char *dep ){

      Array a;
      int n, i, *to;
      Object oo;


/*  If the supplied object is a field... */

      switch( DXGetObjectClass( o ) ){
      case CLASS_FIELD:


/*  See how many items there are in the requested component. */

         a = (Array) DXGetComponentValue( (Field) o, dep );
         if( !a ) {
            DXSetError( ERROR_DATA_INVALID, "field has no \"%s\" component", dep );
            return( ERROR );
         }

         DXGetArrayInfo( a, &n, NULL, NULL, NULL, NULL );


/*  Create a new array to hold the enumeration, and get a pointer to it. */

         a = (Array) DXNewArray( TYPE_INT, CATEGORY_REAL, 0 );
         if( !DXAddArrayData( a, 0, n, NULL ) ) return( ERROR );
         to = (int *) DXGetArrayData( a );


/*  Add this new array to the field. */

         DXSetComponentValue( (Field) o, name, (Object) a );


/*  Store a value for the "dep" attribute of the new array. */

         DXSetComponentAttribute( (Field) o, name, "dep", (Object) DXNewString( dep ) );


/*  Store the enumeration values. */

         for( i=0; i<n; i++ ) *(to++) = i;


/*  Indicate that the component values have changed, and complete the
 *  output field. */

         DXChangedComponentValues( (Field) o, name );
         if( !DXEndField( (Field) o ) ) return( ERROR );

         break;


/*  If the supplied object is a group, call this function recursively for
 *  each member of the group. */

      case CLASS_GROUP:

         for( i=0; oo=(Object)DXGetEnumeratedMember((Group)o,i,NULL); i++ ){
            if( !DoSXEnum( oo, name, dep ) ) return( ERROR );
         }

         break;

      }

      return( OK );

}
Ejemplo n.º 12
0
static void
CaptionKeyStruck(void *data, DXKeyPressEvent *event)
{
    CaptionData sdata = (CaptionData)data;
    ModuleInput min[2];
    ModuleOutput mout[1];
    Object caption, strattr, posattr;
    Object postion;
    float *xyz;
    int i, oldl, n, *ptr;
    char *oldstr;
    char *newstr;
    Object obType = NULL;
    int x = event->x;
    int y = event->y;
    char c = event->key;

    if (sdata->label == NULL)
	return;

    caption = DXGetMember((Group)sdata->obj, sdata->label);
    if (caption)
    {
	/*
	 * If there was already a member by that name, make sure its
	 * an appropriate object and get its state attributes.
	 */
	obType = DXGetAttribute(caption, "object type");
	if (!obType || strcmp(DXGetString((String)obType), "caption"))
	    return;

	strattr = DXGetAttribute(caption, "string");
	posattr = DXGetAttribute(caption, "position");
    }
    else
    {
	/*
	 * Otherwise, we'll initialize the state.  We'll need an object
	 * type attribute to put on the result (We re-use the one on the
	 * input if there already was a caption)
	 */
	obType = (Object)DXNewString("caption");

	/*
	 * Initial state is an empty string at the current mouse
	 * position.
	 */
	strattr = (Object)DXNewString("");
	posattr = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 3);
	DXAddArrayData((Array)posattr, 0, 1, NULL);
	xyz = (float *)DXGetArrayData((Array)posattr);
	xyz[0] = ((float)x)/sdata->w;
	xyz[1] = ((float)(sdata->h - y))/sdata->w;
	xyz[2] = 0.0;
    }

    DXExtractString(strattr, &oldstr);

    /*
     * Update the string.
     */
    oldl = strlen(oldstr);

    if (c == 0x8 /* BACKSPACE */)
    {
	if (oldl > 0)
	{
	    newstr = (char *)DXAllocate(oldl + 1);
	    for (i = 0; i < oldl-1; i++)
		newstr[i] = oldstr[i];
	    newstr[oldl-1] = '\0';
	}
    }
    else
    {
	newstr = (char *)DXAllocate(oldl + 2);
	for (i = 0; i < oldl; i++)
	    newstr[i] = oldstr[i];
	newstr[oldl] = c;
	newstr[oldl+1] = '\0';
    }

    strattr = (Object)DXNewString(newstr);
	
    DXReference(strattr);
    DXReference(posattr);

    /*
     * Use CallModule to call the Caption module.  This creates the
     * new caption object.
     */
    DXModSetObjectInput(min+0, "string", strattr);
    DXModSetObjectInput(min+1, "position", posattr);
    DXModSetObjectOutput(mout+0, "caption", &caption);
    DXCallModule("Caption", 2, min, 1, mout);

    /*
     * Replace attributes onto caption
     */
    DXSetAttribute(caption, "string", strattr);
    DXSetAttribute(caption, "position", posattr);
    DXSetAttribute(caption, "object type", obType);

    /* 
     * Replace it into scene object group
     */
    DXSetMember((Group)sdata->obj, sdata->label, caption);

    DXDelete(strattr);
    DXDelete(posattr);

    return;
}
Ejemplo n.º 13
0
static void 
CaptionMouseButton(void *data, DXMouseEvent *event)
{
    Object caption;
    Object obType;
    CaptionData sdata = (CaptionData)data;
    int b = WHICH_BUTTON(event);
    int x, y;

    x = event->x;
    y = event->y;

    if (sdata->label == NULL)
	return;

    /*
     * Get the member by name.  If no caption by this name exists,
     * there's nothing to move, so we return.
     */
    caption = DXGetMember((Group)sdata->obj, sdata->label);
    if (! caption)
	return;
    
    /*
     * Make sure its an appropriate object 
     */
    obType = DXGetAttribute(caption, "object type");
    if (!obType || strcmp(DXGetString((String)obType), "caption"))
	return;

    /*
     * Only should see left buttons, but check anyway.
     */
    if (b == 0)
    {
	ModuleInput min[2];
	ModuleOutput mout[1];
	Object strattr, posattr;
	float *xyz;

	/*
	 * If its a caption object, it better have these attributes.
	 * A little error checking might be called for.
	 */
	strattr = DXGetAttribute(caption, "string");
	posattr = (Object)DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 3);
	DXAddArrayData((Array)posattr, 0, 1, NULL);
	xyz = (float *)DXGetArrayData((Array)posattr);

	/*
	 * Move to the current position (0-1 space requires the division 
	 * by the screen width in pixels.
	 */
	xyz[0] = ((float)x)/sdata->w;
	xyz[1] = ((float)(sdata->h - y))/sdata->w;
	xyz[2] = 0.0;

	DXReference(strattr);
	DXReference(posattr);

	/*
	 * Use CallModule to call the Caption module.  This creates the
	 * new caption object.
	 */
	DXModSetObjectInput(min+0, "string", strattr);
	DXModSetObjectInput(min+1, "position", posattr);
	DXModSetObjectOutput(mout+0, "caption", &caption);
	DXCallModule("Caption", 2, min, 1, mout);

	/*
	 * Replace attributes onto caption
	 */
	DXSetAttribute(caption, "string", strattr);
	DXSetAttribute(caption, "position", posattr);
	DXSetAttribute(caption, "object type", obType);

	/* 
	 * Replace it into scene object group
	 */
	DXSetMember((Group)sdata->obj, sdata->label, caption);

	DXDelete(strattr);
	DXDelete(posattr);
    }

    return;
}
Ejemplo n.º 14
0
Error DXGetInputs(Object *in, int dxfd)
{
    static int  firsttime = 1;
    int		nin	= 0;
    Group	iobj	= NULL;
    int		i;
    int		*iptr;
    int		count	= 0;


    if (firsttime && ! callsetup (dxfd)) {
	host_status = HOST_CLOSED;
	return ERROR;
    }

    /*
     * Import the remote object, extract the number of inputs and outputs,
     * and rip them apart appropriately.  group members are: 
     * input parm count, 
     * input object list (the pointers values don't mean anything in this
     * address space; the interesting part is whether they are NULL or not),
     * the output parm count,
     * and then each input object which isn't null.
     */

    iobj = (Group) _dxfImportBin_FP(dxfd);
    if(iobj == NULL)
        goto error;

    if (!DXExtractInteger (DXGetEnumeratedMember (iobj, 0, NULL), &nin))
	goto error;

    memset(in, '\0', sizeof(Object)*nin);
    iptr = (int *)DXGetArrayData((Array)DXGetEnumeratedMember (iobj, 1, NULL));

    /* was nout */
    if (!DXExtractInteger (DXGetEnumeratedMember (iobj, 2, NULL), 
			   &number_of_outputs))
	goto error;

    count = 3;
    for (i=0; i<nin; i++) 
    {
	if (iptr[i] == (int)NULL)
	    continue;

	in[i] = DXGetEnumeratedMember(iobj, count++, NULL);
    }

    /* when does iobj get freed? */
    /* and how does nout get saved? */

    last_inputs = (Object)iobj;
    in_module++;
    return OK;

  error:
    DXDelete ((Object) iobj);
    last_inputs = NULL;
    return ERROR;
}
Ejemplo n.º 15
0
Error m_SXBin( Object *in, Object *out ){
/*
*+
*  Name:
*     SXBin

*  Purpose:
*     bins a field into a grid defined by a another field

*  Language:
*     ANSI C

*  Syntax:
*     output = SXBin( input, grid, type );

*  Classification:
*     Realization

*  Description:
*     The SXBin module bins the "data" component of the "input" field into
*     the bins defined by the "connections" component of the "grid" field.
*     The input field can hold scattered or regularly gridded points, but
*     the "data" component must depend on "positions". The "grid" field must
*     contain "connections" and "positions" components but need not contain
*     a "data" component. The input"data" component must be either TYPE_FLOAT
*     or TYPE_DOUBLE.
*
*     The "data" component in the "output" field contains either the mean
*     or sum of the "input" data values falling within each connection, or
*     the number of data values falling within each connection, as specified
*     by "type".
*
*     When binning a regular grid into another regular grid, beware of the
*     tendancy to produce artificial large scale structure representing the
*     "beat frequency" of the two grids.

*  Parameters:
*     input = field (Given)
*        field or group with positions to bin [none]
*     grid = field (Given)
*        grid to define the bins [none]
*     type = integer (Given)
*        type of output values required: 0 - mean, 1 - sum,
*                                        2 - count [0]
*     output = field (Returned)
*        bined field

*  Components:
*     All components except the "data" component are copied from the "grid"
*     field. The output "data" component added by this module depends on
*     "connections". An "invalid connections" component is added if any output
*     data values could not be calculated (e.g. if the mean is required of an
*     empty bin).

*  Examples:
*     This example bins the scattered data described in "CO2.general" onto a
*     regular grid, and displays it. SXBin is used to find the mean data
*     value in each grid connection.
*
*        input = Import("/usr/lpp/dx/samples/data/CO2.general")$
*        frame17 = Select(input,17);
*        camera = AutoCamera(frame17);
*        grid = Construct([-100,-170],deltas=[10,10],counts=[19,34]);
*        bin = SXBin(frame17,grid);
*        coloured = AutoColor(bin);
*        Display(coloured,camera);
*
*     This example produces a grid containing an estimate of the density of
*     the scattered points (i.e. the number of points per unit area). The
*     positions of the original scattered points are shown as dim grey
*     circles. SXBin finds the number of input positions in each bin,
*     Measure finds the area of each bin, and Compute divides the counts
*     by the areas to get the densities:
*
*        input = Import("/usr/lpp/dx/samples/data/CO2.general")$
*        frame17 = Select(input,17);
*        camera = AutoCamera(frame17);
*        glyphs = AutoGlyph(frame17,scale=0.1,ratio=1);
*        glyphs = Color(glyphs,"dim grey");
*        grid = Construct([-100,-170],deltas=[40,40],counts=[6,10]);
*        counts = SXBin(frame17,grid,type=2);
*        areas = Measure(counts,"element");
*        density = Compute("$0/$1",counts,areas);
*        coloured = AutoColor(density);
*        collected=Collect(coloured,glyphs);
*        Display(collected,camera);

*  See Also:
*     SXRegrid, Map, Construct, Measure

*  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:
*     9-OCT-1995 (DSB):
*        Original version
*     {enter_further_changes_here}

*  Bugs:
*     {note_any_bugs_here}

*-
*/


/*  Local Variables: */

      Array    a;            /* Array to hold reduced dimension positions */
      float   *a_ptr;        /* Pointer to reduced dimension positions */
      Category cat;          /* Array category type */
      Type     dtype;        /* Type of current input data array */
      int      fld;          /* Field counter */
      Object   grid;         /* The grid object */
      int      i;            /* Loop count */
      void    *indata[MAXFLD];/* Pointer to input data array */
      float   *inpos;        /* Pointer to input positions array */
      Array    inpos_array;  /* Input positions array */
      Object   input;        /* A copy of the input object */
      Interpolator interp;   /* Interpolator for grid */
      int      j;            /* Loop count */
      Array    map;          /* Map from input position to output bin number */
      int     *map_ptr;      /* Pointer to map */
      char     more;         /* Are there more input fields to do? */
      Fpair   *next;         /* The next Fpair structure in the linked list */
      int      ndim;         /* No. of dimensions in grid positions array */
      int      nfld;         /* No. of fields sharing current positions array */
      int      npos;         /* No. of input positions */
      int      npindim;      /* No. of dimensions in input positions array */
      int      nbin;         /* No. of grid positions */
      int      outbad[MAXFLD];/* No. of invalid output positions in each field*/
      void    *outdata[MAXFLD];/* Pointers to output data arrays */
      Array    outdata_array;/* Output data array */
      Object   output;       /* The output object */
      int      outtype;      /* Type of output values required */
      float   *pa;           /* Pointer to next reduced dimension position */
      float   *pin;          /* Pointer to next full dimension position */
      int      rank;         /* Array rank */
      int      tag;          /* The tag for the current input positions array */
      Type     type;         /* Array numeric type */
      int      veclen[MAXFLD];/* Dimensionality of each input data array */
      int     *work;         /* Pointer to work array */


/*  Initialise all created objects so that they can safely be deleted if
 *  an error occurs. */

      input = NULL;
      output = NULL;
      grid = NULL;
      outdata_array = NULL;
      work = NULL;
      a = NULL;


/*  Check that the "input" object has been supplied. */

      if( !in[0] ) {
         DXSetError( ERROR_BAD_PARAMETER, "missing parameter \"input\"." );
         goto error;
      }


/*  Remove (cull) all invalid positions and connections from the input. It is
 *  necessary to take a copy of the input first, because the input object
 *  itself cannot be modified. */

      input = DXCopy( in[0], COPY_STRUCTURE );
      if( !DXCull( input ) ) goto error;


/*  Check that the "grid" object has been supplied. */

      if( !in[1] ) {
         DXSetError( ERROR_BAD_PARAMETER, "missing parameter \"grid\"." );
         goto error;
      }


/*  Create an interpolator which identifies the grid connection containing any
 *  given position. */

      interp = SXGetIntp( in[1], &nbin, &ndim, &grid );
      if( !interp ) goto error;


/*  Allocate a work array for use by SXBinD or SXBinF. */

      work = (int *) DXAllocate( sizeof( int )*nbin );
      if( !work ) goto error;


/*  Get the type of output value required. */

      if( !in[2] ){
         outtype = 0;
      } else {
         if( !SXGet0is( "type", in[2], 2, 0, 0, NULL, &outtype, NULL ) ) goto error;
      }


/*  Produce a copy of the "input" object to use as the output, replacing all
 *  fields within it with the grid field. Also form a linked list of Fpair
 *  structures describing the fields. */

      output = SXMakeOut( input, (Field) grid, 1, 1, 3, "positions" );
      if( !output ) goto error;


/*  Abort if no fields were found. */

      if( !head ) {
         DXSetError( ERROR_DATA_INVALID, "no fields found in \"input\"." );
         goto error;
      }


/*  Go through the list of fields looking for fields which share the same
 *  positions component. */

      more = 1;
      while( more ){


/*  Find the first field with a non-zero positions tag. */

         next = head;
         while( next && !next->postag ) next = next->next;


/*  If no non-zero positions tags were found, we've finished. */

         if( !next ){
            more = 0;
            break;
         }


/*  Find the input positions array. Get its shape, size and type. Check it is
 *  usable. */

         inpos_array = (Array) next->pos;
         if( !DXGetArrayInfo( inpos_array, &npos, &type, &cat, &rank, &npindim ) ) goto error;

         if( type != TYPE_FLOAT ){
            DXSetError( ERROR_DATA_INVALID, "positions component in \"input\" is not of type FLOAT." );
            goto error;
         }

         if( cat != CATEGORY_REAL ){
            DXSetError( ERROR_DATA_INVALID, "positions component in \"input\" is not of category REAL." );
            goto error;
         }

         if( rank > 1 ){
            DXSetError( ERROR_DATA_INVALID, "rank %d positions component found in \"input\".", rank );
            goto error;
         }

         if( rank == 0 ){   /* Scalar data is equivalent to 1-d vector data */
            rank = 1;
            npindim = 1;
         }

         if( npindim < ndim ){
            DXSetError( ERROR_DATA_INVALID, "dimensionality of \"input\" (%d) is less than \"grid\" (%d).", npindim, ndim );
            goto error;
         }


/*  Get a pointer to the positions values. */

         inpos = (float *) DXGetArrayData( inpos_array );


/*  If the number of dimensions in the input positions is greater than the
 *  number of dimensions in the grid, remove trailing dimensions from the
 *  input positions so that they match the dimensionality of the grid. */

         if( npindim > ndim ){
            a = DXNewArrayV( TYPE_FLOAT, CATEGORY_REAL, 1, &ndim );
            if( !DXAddArrayData( a, 0, npos, NULL ) ) goto error;
            a_ptr = (float *) DXGetArrayData( a );

            for( i=0; i<npos; i++ ){
               pin = inpos + i*npindim;
               pa = a_ptr + i*ndim;
               for(j=0;j<ndim;j++) pa[j] = pin[j];
            }

            inpos_array = a;

         } else {
            a = NULL;
         }

/*  Create an array of the same shape and size as the input positions
 *  array, which holds integer identifiers for the grid connections
 *  containing each input position. These identifiers start at 1 and
 *  go upto nbin. Positions returned holding an identifier of zero do
 *  not fall within the supplied grid. */

         map = (Array) DXMap( (Object) inpos_array, (Object) interp,
                              NULL, NULL );
         map_ptr = (int *) DXGetArrayData( map );


/*  Find all fields which have the same positions tag and the same data
 *  type. */

         tag = next->postag;
         dtype = next->datatype;

         nfld = 0;
         while( next ){

            if( next->postag == tag && next->datatype == dtype ){


/*  Increment the number of fields found so far which share this
 *  positions component. */

               nfld++;

               if( nfld > MAXFLD ){
                  DXSetError( ERROR_MAX, "\"input\" has too many fields.", MAXFLD );
                  goto error;
               }


/*  Store a pointer to the input data array, and its dimensionality. */

              indata[nfld-1] = (void *) DXGetArrayData( (Array) next->data );
              veclen[nfld-1] = next->datalen;


/*  Make a new array to hold the output data values. The output data will
 *  have the same dimensionality as the input data unless the required output
 *  data is "counts (i.e if parameter "type" is 2), in which case the
 *  output data will be scalar. */

              if( outtype == 2 ) veclen[nfld-1] = 1;

              outdata_array = DXNewArrayV( dtype, CATEGORY_REAL, 1, &veclen[nfld-1] );
              if( !outdata_array ) goto error;

              if( !DXAddArrayData( outdata_array, 0, nbin, NULL ) ) goto error;


/*  Get a pointer to the output data array. */

              outdata[nfld-1] = (void *) DXGetArrayData( outdata_array );
              if( !outdata[nfld-1] ) goto error;


/*  Place the new data component in the output field, and indicate that
 *  it now does not need to be deleted explicitly in the event of an error. */

              if( !DXSetComponentValue( next->outfld, "data", (Object) outdata_array ) ) goto error;
              outdata_array = NULL;

            }

            next = next->next;

         }


/*  Now bin the input data arrays into the output connections, storing the
 *  resulting bin values in the output data arrays. */

         if( dtype == TYPE_FLOAT ){
            if( ! SXBinF( nfld, veclen, npos, (float **)indata, nbin,
                          (float **) outdata, map_ptr, work, outtype,
                          outbad ) ) goto error;
         } else {
            if( ! SXBinD( nfld, veclen, npos, (double **)indata, nbin,
                          (double **) outdata, map_ptr, work, outtype,
                          outbad ) ) goto error;
         }


/*  Loop round all the fields that have just been created. */

         next = head;
         fld = 0;
         while( next ){
            if( next->postag == tag ){


/*  Create invalid positions components in each output field which have any
 *  undefined data values */

               if( outbad[fld] ){
                  if( dtype == TYPE_FLOAT ){
                     if( !SXSetInvPosF( (Object) next->outfld, nbin, veclen[fld],
                                        (float *) outdata[fld], "connections" ) ) goto error;
                  } else {
                     if( !SXSetInvPosD( (Object) next->outfld, nbin, veclen[fld],
                                        (double *) outdata[fld], "connections" ) ) goto error;
                  }
               }


/*  Indicate that the data values are dependant on connections. */

               if( !DXSetComponentAttribute( next->outfld, "data", "dep",
                                        (Object) DXNewString("connections")) ) goto error;


/*  Indicate that the data component of the output field has been
 *  changed. */

               DXChangedComponentValues( next->outfld, "data" );


/*  Complete the construction of this output field. */

               DXEndField( next->outfld );


/*  Increment the field index, and indicate that this input field has
 *  been done. */

               fld++;
               next->postag = 0;

            }

            next = next->next;

         }


/*  Delete the array used to store the reduced dimensionality input positions
 *  (if used). */

         if( a ) {
            DXDelete( (Object) a );
            a = NULL;
         }


      }

error:

/*  Free the storage used to hold the link list of Fpair structures
 *  describing the fields in the "input" object. */

      while( head ){
         next = head->next;
         DXFree( (Pointer) head );
         head = next;
      }


/*  Free the work array. */

      if( work ) DXFree( (Pointer) work );


/*  Delete the copy of the input and grid objects, and the array used to
 *  store the reduced dimensionality input positions (if used). */

      DXDelete( grid );
      DXDelete( input );
      if( a ) DXDelete( (Object) a );


/*  If all is OK, return the "output" object with a good status. */

      if( DXGetError() == ERROR_NONE ){
         out[0] = output;
         return( OK );


/*  If an error has occurred, ensure temporary objects are deleted and return
 *  with a bad status. */

      } else {
         DXDelete( (Object) outdata_array );
         DXDelete( output );
         return( ERROR );
      }

}
Ejemplo n.º 16
0
int
_dxfPlineDraw (tdmPortHandleP portHandle, xfieldT *xf, int buttonUp)
{
  Vector *normals ;
  Point *points = 0 ;
  struct p2d {float x, y ;} *pnts2d = 0 ;
  RGBColor *fcolors, *color_map ;
  char *cache_id ;
  enum approxE approx ;
  tdmStripArraySB *stripsSB = 0 ;
  int type, rank, shape, is_2d ;

  DEFPORT(portHandle) ;

  ENTRY(("_dxfPlineDraw(0x%x, 0x%x, %d)", portHandle, xf, buttonUp));

  /*
   *  Transparent surfaces are stripped for those ports which implement
   *  transparency with the screen door technique, but we need to sort them
   *  as individual polygons to apply the more accurate alpha composition
   *  method supported by Starbase.
   *
   *  Connection-dependent colors are not supported by Starbase strips.
   */

  approx = buttonUp ? xf->attributes.buttonUp.approx :
	              xf->attributes.buttonDown.approx ;

  if (
#ifdef ALLOW_LINES_APPROX_BY_DOTS
      (approx == approx_dots) ||
#endif
      (xf->colorsDep == dep_connections))
    {
      int status ;
      PRINT(("drawing as individual polygons"));
      status = _dxfLineDraw (portHandle, xf, buttonUp) ;
      EXIT((""));
      return status ;
    }

  /*
   *  Extract rendering data from the xfield.
   */

  if (DXGetArrayClass(xf->fcolors_array) == CLASS_CONSTANTARRAY)
      fcolors = (Pointer) DXGetArrayEntry(xf->fcolors, 0, NULL) ;
  else
      fcolors = (Pointer) DXGetArrayData(xf->fcolors_array) ;

  color_map = (RGBColor *) DXGetArrayData(xf->cmap_array) ;

  if (DXGetArrayClass(xf->normals_array) == CLASS_CONSTANTARRAY)
      normals = (Pointer) DXGetArrayEntry(xf->normals, 0, NULL) ;
  else
      normals = (Pointer) DXGetArrayData(xf->normals_array) ;

#if 0
  if (xf->colorsDep != dep_field)
  {
    /*
     *  Dense fields of varying colors are visually confusing
     *  without hidden surface, even with wireframe approximation.
     */
    hidden_surface (FILDES, TRUE, FALSE) ;
  }
  else /* RE : <LUMBA281> */
  {
     hidden_surface(FILDES, TRUE, FALSE);
  }
#endif 

  hidden_surface(FILDES, TRUE, FALSE);

  if (xf->colorsDep == dep_field)
    {
      /* render field in constant color */
      cache_id = "CpfPline" ;
      SET_COLOR(fill_color, 0) ;
      SET_COLOR(line_color, 0) ;
    }
  else
    {
      cache_id = "CpfPline" ;
    }

  /*
   *  Render strips.
   */
  
  PRINT(("%s", cache_id));
  if (stripsSB = tdmGetTmeshCacheSB (cache_id, xf))
    {
      /*
       *  Use pre-constructed Starbase strips obtained from executive cache.
       */
      
      register tdmTmeshCacheSB *stripArray, *end ;
      PRINT(("got strips from cache"));
      PrintBounds() ;
      
      stripArray = stripsSB->stripArray ;
      end = &stripArray[stripsSB->num_strips] ;
      
      for ( ; stripArray < end ; stripArray++)
	{
	  polyline_with_data3d
	    (FILDES, stripArray->clist, stripArray->numverts,
	     stripArray->numcoords, stripArray->vertex_flags, NULL) ;
	}
    }
  else
    {
      /*
       *  Construct an array of Starbase strips and cache it.
       */

      register int vsize ;
      int *connections, (*strips)[2] ;
      int cOffs, nOffs, vertex_flags, facet_flags, numStrips ;
      tdmTmeshCacheSB *stripArray ;
      PRINT(("building new strips"));

      /* determine vertex and facet types and sizes */
      vertex_flags = 0 ;
      facet_flags = UNIT_NORMALS ;
      vsize = 3 ;

      if (fcolors && xf->colorsDep != dep_field)
	{
	  /* vertex has at least 6 floats, with color at float 3 */
	  vsize = 6 ; cOffs = 3 ;
	  vertex_flags |= VERTEX_COLOR ;
	}
      
      /* get positions */
      if (is_2d = IS_2D (xf->positions_array, type, rank, shape))
	pnts2d = (struct p2d *) DXGetArrayData(xf->positions_array) ;
      else
	points = (Point *) DXGetArrayData(xf->positions_array) ;
      
      /* get strip topology */
      connections = (int *)DXGetArrayData(xf->connections_array) ;
      strips = (int (*)[2])DXGetArrayData(xf->meshes) ;
      numStrips = xf->nmeshes ;
      
      DebugMessage() ;
      
      /* allocate space for Starbase strip data */
      stripsSB = (tdmStripArraySB *) tdmAllocate(sizeof(tdmStripArraySB)) ;
      if (!stripsSB)
	{
	  PRINT(("out of memory allocating strip structure"));
	  DXErrorGoto (ERROR_INTERNAL, "#13000") ;
	}
      
      stripsSB->stripArray = 0 ;
      stripsSB->num_strips = 0 ;
      
      /* allocate array of Starbase strips */
      stripArray =
	stripsSB->stripArray = (tdmTmeshCacheSB *)
	  tdmAllocate(numStrips*sizeof(tdmTmeshCacheSB));
      
      if (!stripArray)
	{
	  PRINT(("out of memory allocating array of strips"));
	  DXErrorGoto (ERROR_INTERNAL, "#13000") ;
	}
      
      for ( ; stripsSB->num_strips < numStrips ; stripsSB->num_strips++)
	{
	  /* each iteration constructs and draws one Starbase strip */
	  register float *clist = 0, *gnormals = 0 ;
	  register int i, dV, *pntIdx, numPnts ;
	  
	  stripArray->clist = 0 ;
	  stripArray->gnormals = 0 ;
	  
	  /* get the number of points in this strip */
	  numPnts = strips[stripsSB->num_strips][1] ;
	  
	  /* allocate coordinate list */
	  stripArray->clist = clist =
	    (float *) tdmAllocate(numPnts*vsize*sizeof(float)) ;
	  
	  if (!clist)
	    {
	      PRINT(("out of memory allocating coordinate list"));
	      DXErrorGoto(ERROR_INTERNAL, "#13000") ;
	    }
	  
	  /* get the sub-array of connections making up this strip */
	  pntIdx = &connections[strips[stripsSB->num_strips][0]] ;
	  
	  /* copy vertex coordinates into clist */
	  if (is_2d)
	    for (i=0, dV=0 ; i<numPnts ; i++, dV+=vsize)
	      {
		*(struct p2d *)(clist+dV) = pnts2d[pntIdx[i]] ;
		((Point *)(clist+dV))->z = 0 ;
	      }
	  else
	    for (i=0, dV=0 ; i<numPnts ; i++, dV+=vsize)
	      *(Point *)(clist+dV) = points[pntIdx[i]] ;
	  
	  /* copy vertex colors */
	  if (vertex_flags & VERTEX_COLOR)
	    if (color_map)
	      for (i=0, dV=cOffs ; i<numPnts ; i++, dV+=vsize)
		*(RGBColor *)(clist+dV) =
		  color_map[((char *)fcolors)[pntIdx[i]]] ;
	    else
	      for (i=0, dV=cOffs ; i<numPnts ; i++, dV+=vsize)
		*(RGBColor *)(clist+dV) = fcolors[pntIdx[i]] ;
	  
	  /* save other strip info */
	  stripArray->numverts = numPnts ;
	  stripArray->numcoords = vsize-3 ;
	  stripArray->vertex_flags = vertex_flags ;
	  stripArray->facet_flags = facet_flags ;
	  
	  polyline_with_data3d (FILDES, clist, numPnts,
				vsize-3, vertex_flags, NULL) ;
	  
	  /* increment strip */
	  stripArray++ ;
	}
      
      /* cache strip array */
      tdmPutTmeshCacheSB (cache_id, xf, stripsSB) ;
    }

  /* restore hidden surface OFF */
  hidden_surface(FILDES, FALSE, FALSE) ;
  EXIT(("OK"));
  return OK ;

 error:
  tdmFreeTmeshCacheSB((Pointer)stripsSB) ;
  hidden_surface(FILDES, FALSE, FALSE) ;
  EXIT(("ERROR"));
  return ERROR ;
}
Ejemplo n.º 17
0
static Error ConvertFieldObject(Object out, char *strin)
{

Class cl;
int i, rank, shape[30], numitems;
Type type;
Category category;
Array data, new_data;
RGBColor *dp_old, *dp_new;
Object subo;
float red, green, blue, hue, sat, val;
    
    if (!(cl = DXGetObjectClass(out))) 
      return ERROR;
    switch (cl) {
       case CLASS_GROUP:
	  for (i=0; (subo = DXGetEnumeratedMember((Group)out, i, NULL)); i++) {
            if (!ConvertFieldObject((Object)subo, strin))
	        return ERROR;
            }
	  break;
       case CLASS_FIELD:
          if (DXEmptyField((Field)out))
             return OK;
          data = (Array)DXGetComponentValue((Field)out,"data");
          if (!data) { 
             DXSetError(ERROR_MISSING_DATA,"#10240", "data");
             return ERROR;
          }
          DXGetArrayInfo(data,&numitems,&type,&category,&rank,shape);
          if ((type != TYPE_FLOAT)||(category != CATEGORY_REAL)) {
             DXSetError(ERROR_DATA_INVALID,"#10331", "data");
             return ERROR;
          }
          if ((rank != 1)||(shape[0] != 3)) {
             DXSetError(ERROR_DATA_INVALID,"#10331", "data");
             return ERROR;
          }
          new_data = DXNewArray(TYPE_FLOAT,CATEGORY_REAL,1,3);
          new_data = DXAddArrayData(new_data, 0, numitems, NULL);
          dp_old = (RGBColor *)DXGetArrayData(data);
          dp_new = (RGBColor *)DXGetArrayData(new_data);
          if (!strcmp(strin,"hsv"))  {
              for (i=0; i<numitems; i++) {
                 if (!_dxfHSVtoRGB(dp_old[i].r, dp_old[i].g, dp_old[i].b,
                               &red, &green, &blue))
                     return ERROR;
                 dp_new[i] = DXRGB(red,green,blue);
              }
          }
          else {
              for (i=0; i<numitems; i++) {
                 if (!_dxfRGBtoHSV(dp_old[i].r, dp_old[i].g, dp_old[i].b,
                               &hue, &sat, &val))
                     return ERROR;
                 dp_new[i] = DXRGB(hue, sat, val);
              }
          }
          DXSetComponentValue((Field)out, "data", (Object)new_data);
          DXChangedComponentValues((Field)out,"data");
          DXEndField((Field)out);
	  break;
       default:
          break;
    }

    return OK; 
    
  }
Ejemplo n.º 18
0
int
_dxfPlineDraw (tdmPortHandleP portHandle, xfieldT *xf, int buttonUp)
{
  Point *points = 0 ;
  struct p2d {float x, y ;} *pnts2d = 0 ;
  Vector *normals ;
  RGBColor *fcolors, *color_map ;
  Type type ;
  int rank, shape, is_2d ;
  float *opacities, *opacity_map ;
  char *cache_id ;
  tdmStripDataXGL *stripsXGL = 0 ;

  DEFPORT(portHandle) ;
  DPRINT("\n(_dxfPlineDraw") ;

  if(xf->colorsDep == dep_connections)
    return _dxfLineDraw(portHandle, xf, buttonUp);

  /*
   *  Extract required data from the xfield.
   */

  if (is_2d = IS_2D(xf->positions_array, type, rank, shape))
      pnts2d = (struct p2d *) DXGetArrayData(xf->positions_array) ;
  else
      points = (Point *) DXGetArrayData(xf->positions_array) ;

  color_map = (RGBColor *) DXGetArrayData(xf->cmap_array) ;
  opacity_map = (float *) DXGetArrayData(xf->omap_array) ;

  if (DXGetArrayClass(xf->fcolors_array) == CLASS_CONSTANTARRAY)
      fcolors = (Pointer) DXGetArrayEntry(xf->fcolors, 0, NULL) ;
  else
      fcolors = (Pointer) DXGetArrayData(xf->fcolors_array) ;

  if (DXGetArrayClass(xf->opacities_array) == CLASS_CONSTANTARRAY)
      opacities = (Pointer) DXGetArrayEntry(xf->opacities, 0, NULL) ;
  else
      opacities = (Pointer) DXGetArrayData(xf->opacities_array) ;

  DebugMessage() ;

  /* set default attributes for surface and wireframe approximation */
  xgl_object_set (XGLCTX,
		  XGL_CTX_LINE_COLOR_SELECTOR, XGL_LINE_COLOR_VERTEX,
		  XGL_3D_CTX_LINE_COLOR_INTERP, TRUE,
		  0) ;

  /* override above attributes according to color dependencies and lighting */
  if (xf->colorsDep == dep_field)
    {
      /*
       *  Field has constant color.  Get color from context.
       */
      CLAMP(&fcolors[0],&fcolors[0]) ;
      cache_id = "CpfPline" ;
      /* get line color from context */
      xgl_object_set
	(XGLCTX,
	 XGL_CTX_LINE_COLOR_SELECTOR, XGL_LINE_COLOR_CONTEXT,
	 XGL_CTX_LINE_COLOR, &fcolors[0],
	 NULL) ;
    }
  else
    {
      /*
       *  Field has varying colors.  Get colors from point data.
       */
      cache_id = "CppPline" ;
    }

  DPRINT1("\n%s", cache_id) ;

#if 0 /* may want this when we add transparent lines */
  /*
   *  Set up a simple 50% screen door approximation for opacities < 0.75.
   *  We can't do opacity dep position or connection with this technique,
   *  but constant opacity per field is adequate for many visualizations.
   *
   *  USE_SCREEN_DOOR should only be true if we're using the GT through
   *  the XGL 3.0 interface on Solaris; no other access to this effect is
   *  provided by Sun.  The GT with XGL 3.0 also provides alpha
   *  transparency of some sort.  It's not implemented here.
   */

  xgl_object_set
      (XGLCTX,
       XGL_CTX_SURF_FRONT_FILL_STYLE, XGL_SURF_FILL_SOLID,
       NULL) ;

  if (opacities && USE_SCREEN_DOOR)
      if ((opacity_map? opacity_map[*(char *)opacities]: opacities[0]) < 0.75)
	  xgl_object_set
	      (XGLCTX,
	       XGL_CTX_SURF_FRONT_FILL_STYLE, XGL_SURF_FILL_STIPPLE,
	       XGL_CTX_SURF_FRONT_FPAT, SCREEN_DOOR_50,
	       NULL) ;
#endif

  if (stripsXGL = _dxf_GetTmeshCacheXGL (cache_id, xf))
    {
      /*
       *  Use pre-constructed xgl strips obtained from executive cache.
       */
      register Xgl_pt_list *pt_list, *end ;
      DPRINT("\ngot strips from cache");

      pt_list = stripsXGL->pt_lists ;
      end = &pt_list[stripsXGL->num_strips] ;

      for ( ; pt_list < end ; pt_list++)
	xgl_multipolyline (XGLCTX, NULL, 1, pt_list) ;

    }
  else
    {
      /*
       *  Construct an array of xgl strips and cache it.
       */
      register int vsize, fsize ;
      int v_cOffs, v_nOffs, vertex_flags, numStrips ;
      int *connections, (*strips)[2] ;
      Xgl_pt_list *xgl_pt_list ;
      DPRINT("\nbuilding new strips");

      /* determine vertex types and sizes */
      vsize = 3 ;
      fsize = 0 ;
      vertex_flags = XGL_D_3 | XGL_FLT | XGL_NFLG | XGL_NHOM | XGL_DIRECT ;

      if (fcolors && xf->colorsDep != dep_field) {
	/* vertex has 3 more floats to accomodate color */
	v_cOffs = vsize ; vsize += 3 ; 
	vertex_flags |= XGL__CLR ;
      }	

      /* get strip topology */
      connections = (int *)DXGetArrayData(xf->connections_array) ;
      strips = (int (*)[2])DXGetArrayData(xf->meshes) ;
      numStrips = xf->nmeshes ;

      /* allocate space for strip data */
      stripsXGL = (tdmStripDataXGL *) tdmAllocate(sizeof(tdmStripDataXGL));
      if (!stripsXGL)
	  DXErrorGoto (ERROR_INTERNAL, "#13000") ;

      stripsXGL->pt_lists = 0 ;
      stripsXGL->facet_lists = 0 ;
      stripsXGL->num_strips = 0 ;

      /* allocate array of xgl point lists */
      xgl_pt_list =
	  stripsXGL->pt_lists = (Xgl_pt_list *)
	      tdmAllocate(numStrips*sizeof(Xgl_pt_list));

      if (!xgl_pt_list)
	  DXErrorGoto (ERROR_INTERNAL, "#13000") ;

      for ( ; stripsXGL->num_strips < numStrips ; stripsXGL->num_strips++)
	{
	  /* each iteration constructs and draws one xgl strip */
	  register float *clist, *flist ;
	  register int i, dV, *pntIdx, numPnts ;

	  /* get the number of points in this strip */
	  numPnts = strips[stripsXGL->num_strips][1] ;

	  /* allocate coordinate list */
	  xgl_pt_list->pts.color_normal_f3d =
	      (Xgl_pt_color_normal_f3d *) (clist =
		  (float *) tdmAllocate(numPnts*vsize*sizeof(float))) ;

	  if (!clist)
	      DXErrorGoto (ERROR_INTERNAL, "#13000") ;

	  /* get the sub-array of connections making up this strip */
	  pntIdx = &connections[strips[stripsXGL->num_strips][0]] ;

	  /* copy vertex coordinates into clist */
	  if (is_2d)
	      for (i=0, dV=0 ; i<numPnts ; i++, dV+=vsize)
		{
		  *(struct p2d *)(clist+dV) = pnts2d[pntIdx[i]] ;
		  ((Point *)(clist+dV))->z = 0 ;
		}
	  else
	      for (i=0, dV=0 ; i<numPnts ; i++, dV+=vsize)
		  *(Point *)(clist+dV) = points[pntIdx[i]] ;

	  /* copy vertex colors */
	  if (vertex_flags & XGL__CLR)
	      if (color_map)
		  for (i=0, dV=v_cOffs ; i<numPnts ; i++, dV+=vsize)
		      CLAMP((clist+dV),
			  &color_map[((char *)fcolors)[pntIdx[i]]]);
	      else
		  for (i=0, dV=v_cOffs ; i<numPnts ; i++, dV+=vsize)
		      CLAMP((clist+dV),&fcolors[pntIdx[i]] ) ;

	  /* set up other point list info */
	  xgl_pt_list->bbox = NULL ;
	  xgl_pt_list->num_pts = numPnts ;
	  xgl_pt_list->pt_type = vertex_flags ;

	  /* send strip to xgl, increment pointlist pointers */
	  xgl_multipolyline (XGLCTX, NULL, 1, xgl_pt_list++) ;
	}

      /* cache all strip data */
      _dxf_PutTmeshCacheXGL (cache_id, xf, stripsXGL) ;
    }

  DPRINT(")") ;
  return OK ;

error:
  _dxf_FreeTmeshCacheXGL((Pointer)stripsXGL) ;
  DPRINT("\nerror)") ;
  return ERROR ;
}
Ejemplo n.º 19
0
Error m_SXRegrid( Object *in, Object *out ){
/*
*+
*  Name:
*     SXRegrid

*  Purpose:
*     samples a field at positions defined by a another field

*  Language:
*     ANSI C

*  Syntax:
*     output = SXRegrid( input, grid, nearest, radius, scale, exponent,
*                        coexp, type );

*  Classification:
*     Realisation

*  Description:
*     The SXRegrid module samples the "data" component of the "input"
*     field at the positions held in the "positions" component of the
*     "grid" field. It is similar to the standard "Regrid" module, but
*     provides more versatility in assigning weights to each input position,
*     the option of returning the sums of the weights or the weighted sum
*     instead of the weighted mean, and seems to be much faster. Both
*     supplied fields can hold scattered or regularly gridded points, and
*     need not contain "connections" components. The "data" component in the
*     "input" field must depend on "positions".
*
*     For each grid position, a set of near-by positions in the input
*     field are found (using "nearest" and "radius"). Each of these input
*     positions is given a weight dependant on its distance from the current
*     grid position. The output data value (defined at the grid position) can
*     be the weighted mean or weighted sum of these input data values, or
*     the sum of the weights (selected by "type").
*
*     The weight for each input position is of the form:
*
*        (d/d0)**exponent
*
*     where "d" is the distance from the current grid position to the
*     current input position. If a single value is given for "scale" then
*     that value is used for the d0 constant for all the near-by input
*     positions. If more than 1 value is given for "scale" then the first
*     value is used for the closest input position, the second value for the
*     next closest, etc. The last supplied value is used for any remaining
*     input positions. A value of zero for "scale" causes the
*     corresponding input position to be given zero weight.
*
*     If "coexp" is not zero, then the above weights are modified to
*     become:
*
*        exp( coexp*( (d/d0)**exponent ) )
*
*     If "nearest" is given an integer value, it specifies N, the maximum
*     number of near-by input positions to use for each output position.
*     The N input positions which are closest to the output position are
*     used. If the string "infinity" is given, then all input positions
*     closer than the distance given by "radius" are used. Using "radius",
*     you may specify a maximum radius (from the output position) within
*     which to find the near-by input positions. If the string "infinity"
*     is given for "radius" then no limit is placed on the radius.

*  Parameters:
*     input = field (Given)
*        field or group with positions to regrid [none]
*     grid = field (Given)
*        grid to use as template [none]
*     nearest = integer or string (Given)
*        number of nearest neighbours to use, or "infinity" [1]
*     radius = scalar or string (Given)
*        radius from grid point to consider, or "infinity" ["infinity"]
*     scale = scalar or vector or scalar list (Given)
*        scale lengths for weights [1.0]
*     exponent = scalar (Given)
*        weighting exponent [1.0]
*     coexp = scalar (Given)
*        exponential co-efficient for weights [0.0]
*     type = integer (Given)
*        type of output values required: 0 - weighted mean, 1 - weighted sum,
*                                        2 - sum of weights [0]
*     output = field (Returned)
*        regridded field

*  Components:
*     All components except the "data" component are copied from the "grid"
*     field. The output "data" component added by this module depends on
*     "positions". An "invalid positions" component is added if any output
*     data values could not be calculated (e.g. if there are no near-by input
*     data values to define the weighted mean, or if the weights are too
*     large to be represented, or if the input grid position was invalid).

*  Examples:
*     This example maps the scattered data described in "CO2.general" onto a
*     regular grid, and displays it. SXRegrid is used to find the data value
*     at the nearest input position to each grid position.
*
*        input = Import("/usr/lpp/dx/samples/data/CO2.general")$
*        frame17 = Select(input,17);
*        camera = AutoCamera(frame17);
*        grid = Construct([-100,-170],deltas=[10,10],counts=[19,34]);
*        regrid = SXRegrid(frame17,grid);
*        coloured = AutoColor(regrid);
*        Display(coloured,camera);
*
*     The next example produces a grid containing an estimate of the density
*     of the scattered points (i.e. the number of points per unit area). The
*     positions of the original scattered points are shown as dim grey
*     circles. SXRegrid finds the 5 closest input positions at each grid
*     position. Zero weight is given to the closest 3 positions. The fourth
*     position has a weight which is half the density of the points within the
*     circle passing through the fourth point (i.e. if the fourth point
*     is at a distance D from the current grid position, there are 3 points
*     within a circle of radius D, so the density within that circle is
*     3/(PI*(D**2)) ). The fifth position has a weight which is half the
*     density of the points within the circle passing through the fifth
*     point. The output data value is the sum of the weights (because
*     "type" is set to 2), which is the mean of the densities within the
*     circles touching the fourth and fifth points.
*
*        input = Import("/usr/lpp/dx/samples/data/CO2.general")$
*        frame17 = Select(input,17);
*        camera = AutoCamera(frame17);
*        glyphs=AutoGlyph(frame17,scale=0.1,ratio=1);
*        glyphs=Color(glyphs,"dim grey");
*        grid = Construct([-100,-170],deltas=[10,10],counts=[19,34]);
*        density=SXRegrid(frame17,grid,nearest=5,scale=[0,0,0,0.691,0.798],
*                         exponent=-2,type=2);
*        coloured = AutoColor(density);
*        collected=Collect(coloured,glyphs);
*        Display(collected,camera);

*  See Also:
*     SXBin, ReGrid, Map, Construct

*  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:
*     3-OCT-1995 (DSB):
*        Original version
*     {enter_further_changes_here}

*  Bugs:
*     {note_any_bugs_here}

*-
*/


/*  Local Variables: */

      Category cat;          /* Array category type */
      float    coexp;        /* Exponential co-efficient for weights */
      Type     dtype;        /* Type of current input data array */
      float    ext;          /* Amount by which to extend grid bounds */
      int      fld;          /* Field counter */
      Object   grid;         /* The grid object */
      float   *gridpos;      /* Pointer to grid positions array */
      int      i;            /* Loop count */
      void    *indata[MAXFLD];/* Pointer to input data array */
      float   *inpos;        /* Pointer to input positions array */
      Array    inpos_array;  /* Input positions array */
      Object   input;        /* A copy of the input object */
      int      iopt;         /* Index of selected option */
      int      j;            /* Loop count */
      float    lbnd[3];      /* Lower bounds of grid */
      char    *opt;          /* Textual option for a parameter value */
      float    radius;       /* Max. radius for contributing input positions */
      char     more;         /* Are there more input fields to do? */
      int      nearest;       /* Max. no. of input positions which can contribute to an output position */
      Fpair   *next;         /* The next Fpair structure in the linked list */
      int      ndim;         /* No. of dimensions in grid positions array */
      int      nfld;         /* No. of fields sharing current positions array */
      int      npos;         /* No. of input positions */
      int      npindim;      /* No. of dimensions in input positions array */
      int      nsamp;        /* No. of grid positions */
      int      nscale;       /* No. of scale distances supplied */
      int      outbad[MAXFLD];/* No. of invalid output positions in each field*/
      void    *outdata[MAXFLD];/* Pointers to output data arrays */
      Array    outdata_array;/* Output data array */
      Object   output;       /* The output object */
      int      outtype;      /* Type of output values required */
      float    exponent;     /* Power for weights */
      int      rank;         /* Array rank */
      float    rsc;          /* Reciprocal squared scale distance*/
      float   *rscale;       /* Scale distances for weights */
      int      tag;          /* The tag for the current input positions array */
      Type     type;         /* Array numeric type */
      float    ubnd[3];      /* Upper bounds of grid */
      int      veclen[MAXFLD];/* Dimensionality of each input data array */


/*  Initialise all created objects so that they can safely be deleted if
 *  an error occurs. */

      input = NULL;
      output = NULL;
      grid = NULL;
      outdata_array = NULL;


/*  Check that the "input" object has been supplied. */

      if( !in[0] ) {
         DXSetError( ERROR_BAD_PARAMETER, "missing parameter \"input\"." );
         goto error;
      }


/*  Remove (cull) all invalid positions and connections from the input. It is
 *  necessary to take a copy of the input first, because the input object
 *  itself cannot be modified. */

      input = DXCopy( in[0], COPY_STRUCTURE );
      if( !DXCull( input ) ) goto error;


/*  Check that the "grid" object has been supplied. */

      if( !in[1] ) {
         DXSetError( ERROR_BAD_PARAMETER, "missing parameter \"grid\"." );
         goto error;
      }


/*  Get a pointer to an array holding the grid positions, and get the
 *  size and shape of the grid. Any invalid positions are flagged with the
 *  value FLT_MAX (defined in float.h). */

      gridpos = SXGetGrid( in[1], &nsamp, &ndim, lbnd, ubnd, &grid );
      if( !gridpos ) goto error;


/*  Get the number of input positions allowed to contribute to each
 *  output position. */

      if( !in[2] ){
         nearest = 1;

      } else {

         opt = "infinity";
         if( !SXGet0is( "nearest", in[2], INT_MAX, 1, 1, &opt, &nearest, &iopt ) ) goto error;
         if( iopt == 0 ) nearest = INT_MAX;

      }


/*  Get the maximum radius for input positions which contribute to each
 *  output position. */

      if( !in[3] ){
         radius = FLT_MAX;

      } else {

         opt = "infinity";
         if( !SXGet0rs( "radius", in[3], FLT_MAX, 0.0, 1, &opt, &radius, &iopt ) ) goto error;
         if( iopt == 0 ) radius = FLT_MAX;

      }


/*  If a maximum radius has been given, extend the bounds by one radius
 *  at each end to catch some extra input positions. Otherwise, extend
 *  the bounds by 10%. */

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

      } else {
         for( j=0; j<ndim; j++ ){
            ext = 0.1*( ubnd[j] - lbnd[j] );
            lbnd[j] -= ext;
            ubnd[j] += ext;
         }

      }


/*  Get the scale distances used to create weights for each input
 *  position. Convert them to squared reciprocal scale distances. If
 *  no value is supplied for the "scale" parameter, use a single scale
 *  length of 1.0 */

      if( !in[4] ){
         rsc = 1.0;
         rscale = &rsc;
         nscale = 1;

      } else {
         rscale = SXGet1r( "scale", in[4], &nscale );
         if( !rscale ) goto error;

         for( i=0; i<nscale; i++ ) {
            rsc = rscale[i];
            if( rsc != 0.0 ){
               rscale[i] = 1.0/(rsc*rsc);
            } else {
               rscale[i] = 0.0;
            }
         }

      }


/*  Get the exponent used to create weights for each input position. */

      if( !in[5] ){
         exponent = 1.0;
      } else {
         if( !SXGet0rs( "exponent", in[5], FLT_MAX, -FLT_MAX, 0, &opt, &exponent, &iopt ) ) goto error;
      }


/*  Get the co-efficient to used in the exponential when creating weights for
 *  each input position. */

      if( !in[6] ){
         coexp = 0.0;
      } else {
         if( !SXGet0rs( "coexp", in[6], FLT_MAX, -FLT_MAX, 0, &opt, &coexp, &iopt ) ) goto error;
      }


/*  Get the type of output value required. */

      if( !in[7] ){
         outtype = 0;
      } else {
         if( !SXGet0is( "type", in[7], 2, 0, 0, &opt, &outtype, &iopt ) ) goto error;
      }


/*  Produce a copy of the "input" object to use as the output, replacing all
 *  fields within it with the grid field. Also form a linked list of Fpair
 *  structures describing the fields. */

      output = SXMakeOut( input, (Field) grid, 1, 1, 3, "positions" );
      if( !output ) goto error;


/*  Abort if no fields were found. */

      if( !head ) {
         DXSetError( ERROR_DATA_INVALID, "no fields found in \"input\"." );
         goto error;
      }


/*  Go through the list of fields looking for fields which share the same
 *  positions component. */

      more = 1;
      while( more ){


/*  Find the first field with a non-zero positions tag. */

         next = head;
         while( next && !next->postag ) next = next->next;


/*  If no non-zero positions tags were found, we've finished. */

         if( !next ){
            more = 0;
            break;
         }


/*  Find the input positions array. Get its shape, size and type. Check it is
 *  usable. */

         inpos_array = (Array) next->pos;
         if( !DXGetArrayInfo( inpos_array, &npos, &type, &cat, &rank, &npindim ) ) goto error;

         if( type != TYPE_FLOAT ){
            DXSetError( ERROR_DATA_INVALID, "positions component in \"input\" is not of type FLOAT." );
            goto error;
         }

         if( cat != CATEGORY_REAL ){
            DXSetError( ERROR_DATA_INVALID, "positions component in \"input\" is not of category REAL." );
            goto error;
         }

         if( rank > 1 ){
            DXSetError( ERROR_DATA_INVALID, "rank %d positions component found in \"input\".", rank );
            goto error;
         }

         if( rank == 0 ){   /* Scalar data is equivalent to 1-d vector data */
            rank = 1;
            npindim = 1;
         }

         if( npindim != ndim ){
            DXSetError( ERROR_DATA_INVALID, "dimensionality of \"input\" (%d) does not match \"grid\" (%d).", npindim, ndim );
            goto error;
         }


/*  Get a pointer to the positions values. */

         inpos = (float *) DXGetArrayData( inpos_array );


/*  Find all fields which have the same positions tag and the same data
 *  type. */

         tag = next->postag;
         dtype = next->datatype;

         nfld = 0;
         while( next ){

            if( next->postag == tag && next->datatype == dtype ){


/*  Increment the number of fields found so far which share this
 *  positions component. */

               nfld++;

               if( nfld > MAXFLD ){
                  DXSetError( ERROR_MAX, "\"input\" has too many fields.", MAXFLD );
                  goto error;
               }


/*  Store a pointer to the input data array, and its dimensionality. */

              indata[nfld-1] = (void *) DXGetArrayData( (Array) next->data );
              veclen[nfld-1] = next->datalen;


/*  Make a new array to hold the output data values. The output data will
 *  have the same dimensionality as the input data unless the required output
 *  data is "sum of weights" (i.e. if parameter "type" is 2), in which case the
 *  output data will be scalar. */

              if( outtype == 2 ) veclen[nfld-1] = 1;

              outdata_array = DXNewArrayV( dtype, CATEGORY_REAL, 1, &veclen[nfld-1] );
              if( !outdata_array ) goto error;

              if( !DXAddArrayData( outdata_array, 0, nsamp, NULL ) ) goto error;


/*  Get a pointer to the output data array. */

              outdata[nfld-1] = (void *) DXGetArrayData( outdata_array );
              if( !outdata[nfld-1] ) goto error;


/*  Place the new data component in the output field, and indicate that
 *  it now does not need to be deleted explicitly in the event of an error. */

              if( !DXSetComponentValue( next->outfld, "data", (Object) outdata_array ) ) goto error;
              outdata_array = NULL;


/*  Indicate that the data component of the output field has been
 *  changed. */

              DXChangedComponentValues( next->outfld, "data" );


/*  Indicate that the data values are dependant on positions. */

              if( !DXSetComponentAttribute( next->outfld, "data", "dep",
                                        (Object) DXNewString("positions")) ) goto error;

            }

            next = next->next;

         }


/*  Now sample the input data arrays at the output positions, storing the
 *  resulting sample values in the output data arrays. */

         if( dtype == TYPE_FLOAT ){
            if( ! SXSampleF( nfld, ndim, veclen, npos, inpos, (float **)indata,
                             nsamp, gridpos, (float **) outdata, lbnd, ubnd,
                             nearest, radius, rscale, nscale, exponent, coexp,
                             outtype, outbad ) ) goto error;
         } else {
            if( ! SXSampleD( nfld, ndim, veclen, npos, inpos, (double **)indata,
                             nsamp, gridpos, (double **) outdata, lbnd, ubnd,
                             nearest, radius, rscale, nscale, exponent, coexp,
                             outtype, outbad ) ) goto error;
         }


/*  Loop round all the fields that have just been created. */

         next = head;
         fld = 0;
         while( next ){
            if( next->postag == tag ){


/*  Create invalid positions components in each output field which have any
 *  undefined data values */

               if( outbad[fld] ){
                  if( dtype == TYPE_FLOAT ){
                     if( !SXSetInvPosF( (Object) next->outfld, nsamp, veclen[fld],
                                        (float *) outdata[fld], "positions" ) ) goto error;
                  } else {
                     if( !SXSetInvPosD( (Object) next->outfld, nsamp, veclen[fld],
                                        (double *) outdata[fld], "positions" ) ) goto error;
                  }
               }



/*  Complete the construction of this output field. */

               DXEndField( next->outfld );


/*  Increment the field index, and indicate that this input field has
 *  been done. */

               fld++;
               next->postag = 0;

            }

            next = next->next;

         }


      }

error:

/*  Free the storage used to hold the link list of Fpair structures
 *  describing the fields in the "input" object. */

      while( head ){
         next = head->next;
         DXFree( (Pointer) head );
         head = next;
      }


/*  Delete the copy of the input objects. Return the "output" object with a good status. */

      DXDelete( grid );
      DXDelete( input );


/*  If all is OK, return the "output" object with a good status. */

      if( DXGetError() == ERROR_NONE ){
         out[0] = output;
         return( OK );


/*  If an error has occurred, ensure temporary objects are deleted and return
 *  with a bad status. */

      } else {
         DXDelete( (Object) outdata_array );
         DXDelete( output );
         return( ERROR );
      }

}
Ejemplo n.º 20
0
static int
doLeaf(Object *in, Object *out)
{
    int i, result=0;
    Array array;
    Field field;
    Pointer *in_data[2], *out_data[1];
    int in_knt[2], out_knt[1];
    Type type;
    Category category;
    int rank, shape;
    Object attr, src_dependency_attr = NULL;
    char *src_dependency = NULL;
    /*
     * Irregular positions info
     */
    int p_knt, p_dim;
    float *p_positions;
    int c_knt = -1;

    /* User-added declarations */
    float *scratch, *in_ptr, size;
    Point inpoint, *out_pos_ptr;
    ArrayHandle handle;
    Array connections;
    Line *conn_ptr;

    /*
     * positions and/or connections are required, so the first must
     * be a field.
     */
    if (DXGetObjectClass(in[0]) != CLASS_FIELD)
    {
        DXSetError(ERROR_DATA_INVALID,
                   "positions and/or connections unavailable in array object");
        goto error;
    }
    else
    {

        field = (Field)in[0];

        if (DXEmptyField(field))
            return OK;

        /*
         * Determine the dependency of the source object's data
         * component.
         */
        src_dependency_attr = DXGetComponentAttribute(field, "data", "dep");
        if (! src_dependency_attr)
        {
            DXSetError(ERROR_MISSING_DATA, "\"input\" data component is missing a dependency attribute");
            goto error;
        }

        if (DXGetObjectClass(src_dependency_attr) != CLASS_STRING)
        {
            DXSetError(ERROR_BAD_CLASS, "\"input\" dependency attribute");
            goto error;
        }

        src_dependency = DXGetString((String)src_dependency_attr);

        array = (Array)DXGetComponentValue(field, "positions");
        if (! array)
        {
            DXSetError(ERROR_BAD_CLASS, "\"input\" contains no positions component");
            goto error;
        }

        /* change to doLeaf so that regular positions are not expanded */

        if (!(handle = DXCreateArrayHandle(array)))
            goto error;

        scratch = DXAllocate(3*sizeof(float));
        if (!scratch)
            goto error;

        DXGetArrayInfo(array, &p_knt, NULL, NULL, NULL, &p_dim);


    }

    /* New User code starts here */

    /* Make the new positions array for the output */
    array = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 3);
    if (! array)
        goto error;


    /* Check that the positions are three dimensional: */
    if (p_dim != 3) {
        DXSetError(ERROR_DATA_INVALID,"input positions must be 3-dimensional");
        goto error;
    }
    /* Allocate space in the new positions array */
    if (! DXAddArrayData(array, 0, 4*p_knt, NULL))
        goto error;

    /* Get a pointer to the output positions */
    out_pos_ptr  = (Point *)DXGetArrayData(array);


    /* Make a connections component for the output */
    connections = DXNewArray(TYPE_INT, CATEGORY_REAL, 1, 2);

    /* Allocate space in the new connections array */
    if (! DXAddArrayData(connections, 0, 2*p_knt, NULL))
        goto error;
    DXSetAttribute((Object)connections, "element type",
                   (Object)DXNewString("lines"));
    /* Get a pointer to the new connections */
    conn_ptr = (Line *)DXGetArrayData(connections);

    /* Now "draw" the x's */
    for (i=0; i< p_knt; i++) {
        /* the following line accesses the position via the
         * array handling routines
         */
        in_ptr = (float *)DXIterateArray(handle, i, in_ptr, scratch);
        inpoint = DXPt(in_ptr[0], in_ptr[1], in_ptr[2]);
        DXExtractFloat(in[1], &size);
        out_pos_ptr[4*i]   = DXPt(inpoint.x - size, inpoint.y, inpoint.z);
        out_pos_ptr[4*i+1] = DXPt(inpoint.x + size, inpoint.y, inpoint.z);
        out_pos_ptr[4*i+2] = DXPt(inpoint.x, inpoint.y - size, inpoint.z);
        out_pos_ptr[4*i+3] = DXPt(inpoint.x, inpoint.y + size, inpoint.z);

        conn_ptr[2*i] = DXLn(4*i, 4*i+1);
        conn_ptr[2*i+1] = DXLn(4*i+2, 4*i+3);
    }

    /* Clean up; we're about to significantly modify the positions and connections
     */
    DXChangedComponentStructure((Field)out[0],"positions");
    DXChangedComponentStructure((Field)out[0],"connections");

    /* Now place the new positions and connections in the output field */
    DXSetComponentValue((Field)out[0], "positions", (Object)array);
    DXSetComponentValue((Field)out[0], "connections", (Object)connections);

    /* Finalize the field */
    DXEndField((Field)out[0]);

    /* Delete scratch and handle */
    DXFree((Pointer)scratch);
    DXFreeArrayHandle(handle);

    /* return */
    return OK;
error:

    /* Delete scratch and handle */
    DXFree((Pointer)scratch);
    DXFreeArrayHandle(handle);
    return ERROR;


}
Ejemplo n.º 21
0
static void *
Slide2DInitMode(Object args, int w, int h, int *mask)
{
    Slide2DData sdata = (Slide2DData)DXAllocateZero(sizeof(struct slide2DData));
    if (! sdata)
	return NULL;

    /* 
     * Parse the argument.  It better be a string or an integer.
     */
    if (! args)
    {
        DXWarning("Slide2D: argument required (index 0 used)");
	sdata->label = NULL;
	sdata->index = 0;
    }
    else if (DXGetObjectClass(args) == CLASS_STRING)
    {
	sdata->args = DXReference(args);
	sdata->label = DXGetString((String)args);
    }
    else if (DXGetObjectClass(args) == CLASS_ARRAY)
    {
	Type t;

	DXGetArrayInfo((Array)args, NULL, &t, NULL, NULL, NULL);
	if (t == TYPE_INT)
	{
	    sdata->args = DXReference(args);
	    sdata->index = *(int *)DXGetArrayData((Array)args);
	    sdata->label = NULL;
	}
	else if (t == TYPE_UBYTE ||
		 t == TYPE_BYTE  ||
		 t == TYPE_STRING)
	{
	    sdata->args = DXReference(args);
	    sdata->label = (char *)DXGetArrayData((Array)args);
	    sdata->index = -1;
	}
	else
	{
	    DXWarning("Slide2D: argument must be string or int (index 0 used)");
	    sdata->label = NULL;
	    sdata->index = 0;
	}

    }

    /*
     * Save the window width and height for scaling purposes
     */
    sdata->w = w;
    sdata->h = h;

    /*
     * Initially, the button is up
     */
    sdata->strokeStart = 1;

    /* 
     * Pay attention to only the left and middle buttons
     */
    *mask = DXEVENT_LEFT | DXEVENT_MIDDLE;
	
    return (void *)sdata;
}
Ejemplo n.º 22
0
int
m_Convert(Object *in, Object *out)
{
  Array    incolorvec, outcolorvec;
  int      ismap, isfield, count, i, ii, numitems, addpoints;
  char     *colorstrin, *colorstrout; 
  char     newstrin[30], newstrout[30];
  Object   gout;
  float    *dpin=NULL, *dpout=NULL;

  gout=NULL;
  incolorvec = NULL;
  outcolorvec = NULL;
   
  if (!in[0]) {
    DXSetError(ERROR_MISSING_DATA,"#10000","data");
    return ERROR;
  }
  out[0] = in[0];
  ismap = 0; 
  isfield = 0; 
  

  /*
   *  if it's an array (vector or list of vectors)
   */

  if (DXGetObjectClass(in[0]) == CLASS_ARRAY) {
    if (!(DXQueryParameter((Object)in[0], TYPE_FLOAT, 3, &numitems))) {
      /* must be a list of 3-vectors or a field */
      DXSetError(ERROR_BAD_PARAMETER,"#10550","data");
      out[0] = NULL;
      return ERROR;
    }
    if (!(incolorvec = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 1, 3))){
      out[0] = NULL;
      return ERROR;
    }
    if (!(DXAddArrayData(incolorvec,0,numitems,NULL)))
      goto error;
    if (!(dpin = (float *)DXGetArrayData(incolorvec)))
      goto error;
    if (!(DXExtractParameter((Object)in[0], TYPE_FLOAT, 3, numitems,
			   (Pointer)dpin))) {
      /* must be a list of 3-vectors or a field */
      DXSetError(ERROR_BAD_PARAMETER,"#10550","data");
      goto error;
    }

    /*    
     *  also make the output array
     */
    if (!(outcolorvec = DXNewArray(TYPE_FLOAT,CATEGORY_REAL, 1, 3)))
      goto error;
    if (!(DXAddArrayData(outcolorvec,0,numitems,NULL)))
      goto error;
    if (!(dpout = (float *)DXGetArrayData(outcolorvec)))
      goto error;

  }
  else { 
    if (_dxfIsColorMap(in[0])) 
      ismap = 1;
    else {
      DXResetError();
      isfield = 1;
    }
  }




  
  /* now extract the to and from space names */
  /*  get color name  */
  if (!(in[1]))
    colorstrin = "hsv";
  else 
    if (!DXExtractString((Object)in[1], &colorstrin)) {
      /* invalid input string */
      DXSetError(ERROR_BAD_PARAMETER,"#10200","incolorspace");
      goto error;
    }
  /*  convert color name to all lower case and remove spaces */
  count = 0;
  i = 0;
  while ( i<29 && colorstrin[i] != '\0') {
    if (isalpha(colorstrin[i])){
      if (isupper(colorstrin[i]))
	newstrin[count]= tolower(colorstrin[i]);
      else
	newstrin[count]= colorstrin[i];
      count++;
    }
    i++;
  }

  newstrin[count]='\0';
  if (strcmp(newstrin,"rgb")&&strcmp(newstrin,"hsv")) {
    DXSetError(ERROR_BAD_PARAMETER,"#10210", newstrin, "incolorspace");
    goto error;
  }
  
  
  if (!in[2]) 
    colorstrout = "rgb";
  else if (!DXExtractString((Object)in[2], &colorstrout)) {
      /* invalid outcolorspace string */
    DXSetError(ERROR_BAD_PARAMETER,"#10200","outcolorspace");
    goto error;
  }
  
  /*  convert color name to all lower case and remove spaces */
  count = 0;
  i = 0;
  while ( i<29 && colorstrout[i] != '\0') {
    if (isalpha(colorstrout[i])){
      if (isupper(colorstrout[i]))
	newstrout[count]= tolower(colorstrout[i]);
      else
	newstrout[count]= colorstrout[i];
      count++;
    }
    i++;
  }
  newstrout[count]='\0';
  if (strcmp(newstrout,"rgb")&&strcmp(newstrout,"hsv")){
    /* invalid outcolorspace string */
    DXSetError(ERROR_BAD_PARAMETER,"#10210", newstrout, "outcolorspace");
    goto error;
  }
  
  if (!strcmp(newstrin,newstrout)) {
    DXWarning("incolorspace and outcolorspace are the same");
    return OK;
  }

  if (!in[3]) {
     /* default behavior is to treat maps like maps (adding points)
        and to treat fields like fields (not adding points) */
  }
  else {
     if (!DXExtractInteger(in[3], &addpoints)) {
        DXSetError(ERROR_BAD_PARAMETER, "#10070",
                   "addpoints");
        goto error;
     }
     if ((addpoints < 0) || (addpoints > 1)) {
        DXSetError(ERROR_BAD_PARAMETER, "#10070",
                   "addpoints");
        goto error;
     }
     if (isfield && addpoints) {
        DXSetError(ERROR_BAD_PARAMETER, "#10370",
         "for a field with greater than 1D positions, addpoints", "0");
        goto error;
     }
     if (ismap && (!addpoints)) {
        /* treat the map like a field */
        ismap = 0;
        isfield = 1;
     }
  }

  /* we have been given a vector value or list of values, not a map */
  if ((!ismap)&&(!isfield)) {
    if (!strcmp(newstrin,"hsv")) {
      for (ii = 0; ii < numitems*3; ii = ii+3) {
	if (!(_dxfHSVtoRGB(dpin[ii], dpin[ii+1], dpin[ii+2],
		       &dpout[ii], &dpout[ii+1], &dpout[ii+2]))) 
	  goto error;
      }
    }
    else {
      for (ii = 0; ii < numitems*3; ii = ii+3) {
	if (!(_dxfRGBtoHSV(dpin[ii], dpin[ii+1], dpin[ii+2],
		       &dpout[ii], &dpout[ii+1], &dpout[ii+2]))) 
	  goto error;
      }
    }
    out[0] = (Object)outcolorvec;
    DXDelete((Object)incolorvec);
    return OK;
  }

  /* we have a map or field */
  else {
    if (ismap) {
      if (!(ConvertObject(in[0], newstrin, &gout)))
        goto error;
    }
    else {
      gout = DXCopy(in[0], COPY_STRUCTURE);
      if (!gout) goto error;
      if (!(ConvertFieldObject(gout, newstrin)))
         goto error;
    }
    out[0] = gout;
    return OK;
  }

  error:
    out[0] = NULL;
    DXDelete((Object)gout);
    DXDelete((Object)incolorvec);
    DXDelete((Object)outcolorvec);
    return ERROR;
}
Ejemplo n.º 23
0
Error
_dxf_quadsToQmesh (xfieldT *xf, void *globals)
{
  DEFGLOBALDATA(globals) ;
  Quadruple *neighbors ;       /* neighbors array gives a quad's neighbors  */
  Qstrip *stripArray = 0 ;     /* temp array of strips                      */
  int point[MaxQstripSize] ;   /* array into which to build point list      */
  char *usedArray = 0 ;        /* marks quads already used                  */
  int nStrips = 0 ;            /* number of strips generated                */
  int nStrippedPts = 0 ;       /* number of points stripped                 */
  int nPtsInStrip ;            /* number of points in current strip         */
  int start_quad ;             /* first quad of the strip                   */
  int quad ;                   /* the current quad                          */
  int dir, i0, i1, i2, i3 ;    /* the 4 indexes into quads[quad].p[?]       */
  int prev_quad, prev_i0,      /* used to determine the same current info   */
      prev_i1,prev_i2,prev_i3 ;
  Quadruple *quads ;           /* array of original quad connections        */
  int nquads ;                 /* number of original quad connections       */
  int i, j, k ;                /* misc. indices                             */
  QMesh qmesh = NULL;
  dxObject qmesho = NULL;

  ENTRY(("_dxf_quadsToQmesh(0x%x)", xf));

  qmesho = _dxf_QueryObject(MESHHASH, (dxObject)xf->field);
  if (qmesho)
  {
      xf->meshObject = DXReference(qmesho);
      qmesh = (QMesh)DXGetPrivateData((Private)qmesho);
      _installQMeshInfo(xf, qmesh);

      return OK;
  }

  if (xf->connectionType != ct_quads)
    {
      EXIT(("xf->connectionType not ct_quads"));
      return OK ;
    }

  PRINT(("invalid connections: %d",
	   xf->invCntns? DXGetInvalidCount(xf->invCntns): 0)) ;

  neighbors = getNeighbors(xf);

  /* get quad connection info; quad connections are replaced by strips */
  quads = DXGetArrayData(xf->connections_array) ;
  nquads = xf->nconnections ;
  /*npoints = xf->npositions ;*/

  xf->origNConnections = nquads;
  xf->origConnections_array = xf->connections_array;
  xf->connections_array = NULL;

  /* allocate temporary array to hold maximum possible number of strips */
  if (!(stripArray = (Qstrip *) tdmAllocate(sizeof(Qstrip) * nquads)))
    {
      PRINT(("out of memory"));
      DXErrorGoto (ERROR_NO_MEMORY, "#13000") ;
    }

  if (neighbors)
    {
      /* quad connections expressed explicitly, we need usedArray */
      if (!(usedArray = tdmAllocateZero(sizeof(char) * Bytes(nquads))))
	{
	  PRINT(("out of memory"));
	  DXErrorGoto (ERROR_NO_MEMORY, "#13000") ;
	}

      /* strip the field, placing strip info into temporary arrays */
      for (start_quad = 0; start_quad < nquads; start_quad++)
	{
	  if (GoodQuad(start_quad))
	    {
	      nPtsInStrip = 0 ;
	      quad = start_quad ;
	      InitFirstQuad(i0,i1,i2,i3) ; /* pick 1st quad initial vertices */
	      AddPoint(quad,i1) ;          /* add the 1st two...             */
	      AddPoint(quad,i0) ;          /* ...points to the mesh          */
	      while (quad >= 0)            /* while there's a valid quad...  */
		{
		  AddPoint(quad,i3) ;      /*  add another quad to the strip */
		  AddPoint(quad,i2) ;
		  MarkQuad(quad) ;         /*  mark it as used               */
		  NextQuad(quad) ;         /*  move on to next quad          */
		}

	      /* save strip points */
	      AllocateAndCopyQstripPointArray() ;
	    }
	}
      tdmFree((Pointer)usedArray) ;
      usedArray = NULL;
    }
  else
    {
      /* quad connections expressed in compact mesh array form */
      int n, counts[100] ;

      if (!DXQueryGridConnections (xf->origConnections_array, &n, counts) || n != 2)
	  DXErrorGoto (ERROR_INTERNAL, "#13140") ;

      PRINT(("counts[0] = %d", counts[0]));
      PRINT(("counts[1] = %d", counts[1]));

      for (n = 0, i = 0 ; i < counts[0]-1 ; i++)
	{
	  j = 0 ;
	  while (j < counts[1]-1)
	    {
	      for ( ; j < counts[1]-1 && !ValidQuad(xf->invCntns, n) ; j++, n++)
		  /* skip invalid quads up to end of row/column */ ;

	      if (j == counts[1]-1)
		  break ;

	      /* start triangle strip */
	      nPtsInStrip = 0 ;
	      point[nPtsInStrip++] = n + i ;
	      point[nPtsInStrip++] = n + i + counts[1] ;

	      while (j < counts[1]-1 &&
		     nPtsInStrip < MaxQstripSize &&
		     ValidQuad(xf->invCntns, n))
		{
		  /* add valid quads up to end of row/column or strip limit  */
		  point[nPtsInStrip++] = n + i + 1 ;
		  point[nPtsInStrip++] = n + i + 1 + counts[1] ;
		  j++ ; n++ ;
		}

	      /* save strip points */
	      AllocateAndCopyQstripPointArray() ;
	    }
	}
    }

  PRINT(("stripped %d quadrangles", (nStrippedPts - 2*nStrips)/2));
  PRINT(("generated %d triangle strips", nStrips));
  PRINT(("average number of triangles per strip: %f",
	   nStrips? (nStrippedPts - 2*nStrips)/(float)nStrips: 0));

  if (! _newQMesh(nStrips, nStrippedPts, &qmesh, &qmesho))
      goto error;

  for (i=j=k=0 ; i<nStrips ; i++)
    {
      qmesh->meshes[j++] = k;
      qmesh->meshes[j++] = stripArray[i].points;
      memcpy(qmesh->connections+k, stripArray[i].point, stripArray[i].points*sizeof(int));
      k += stripArray[i].points;
    }

  _dxf_InsertObject(MESHHASH, (dxObject)(xf->field), (dxObject)qmesho);
  xf->meshObject = DXReference(qmesho);
  _installQMeshInfo(xf, qmesh);

  /* free temporary array of strips */
  if (usedArray)
      tdmFree((Pointer)usedArray);
  if (stripArray)
      FreeTempStrips() ;

  EXIT(("OK"));
  return OK ;

 error:
  if (usedArray)
      tdmFree((Pointer)usedArray);
  if (stripArray)
      FreeTempStrips() ;

  EXIT(("ERROR"));
  return 0 ;
}
Ejemplo n.º 24
0
Error 
_dxfValidate(Field f)
{
    Array current = NULL;
    Array target = NULL;
    char *tname, *cname;
    int ncurrent, ntarget, *ip;
    int index;
    unsigned char *cp;
    int i, j, lim, nitems;
    Type type, ref_type;
    Category cat;
    String s = NULL;
    Object o = NULL;
    int rank, shape[MAXRANK];
    int counts[MAXRANK];

    for (i=0; (current=(Array)DXGetEnumeratedComponentValue(f, i, &cname)); i++) {

	/* dep */
	if ((s = (String)DXGetAttribute((Object)current, "dep")) != NULL) {
	    /* make sure number of items matches number of items in dep */
	    if ((DXGetObjectClass((Object)s) != CLASS_STRING) ||
	        ((tname = DXGetString(s)) == NULL)) {
		DXSetError(ERROR_DATA_INVALID, 
			 Err_MustBeString, "dep", cname);
		return ERROR;
	    }
	    
	    if ((target = (Array)DXGetComponentValue(f, tname)) == NULL) {
		DXSetError(ERROR_DATA_INVALID, 
			 Err_MissingComp, tname, "dep", cname);
		return ERROR;
	    }
	    
	    if (DXGetObjectClass((Object)target) != CLASS_ARRAY) {
		DXSetError(ERROR_DATA_INVALID,
			 Err_NotArray, tname, "dep", cname);
		return ERROR;
	    }
	    
	    if (!DXGetArrayInfo(current, &nitems, &type, &cat, &rank, shape))
		return ERROR;
	    
	    ncurrent = nitems;

	    if (!DXGetArrayInfo(target, &nitems, &type, &cat, &rank, shape))
		return ERROR;
	    
	    ntarget = nitems;
	    
	    if (ncurrent != ntarget) {
		DXSetError(ERROR_DATA_INVALID,
			 Err_DiffCount, "dep",
			 ncurrent, cname, ntarget, tname);
		return ERROR;
	    }

	} /* end of if (has dep) */


	/* ref */
	if ((s = (String)DXGetAttribute((Object)current, "ref")) != NULL) {
	    if ((DXGetObjectClass((Object)s) != CLASS_STRING) ||
	        ((tname = DXGetString(s)) == NULL)) {
		DXSetError(ERROR_DATA_INVALID, 
			   Err_MustBeString, "ref", cname);
		return ERROR;
	    }
	    
	    if ((target = (Array)DXGetComponentValue(f, tname)) == NULL) {
		DXSetError(ERROR_DATA_INVALID,
			   Err_MissingComp, tname, "ref", cname);
		return ERROR;
	    }
	    
	    if (DXGetObjectClass((Object)target) != CLASS_ARRAY) {
		DXSetError(ERROR_DATA_INVALID, 
			   Err_NotArray, tname, "ref", cname);
		return ERROR;
	    }
	    
	    if (!DXGetArrayInfo(current, &nitems, &type, &cat, &rank, shape))
		return ERROR;
	    
	    if ( !( type == TYPE_INT || type == TYPE_UBYTE ) ) {
		DXSetError(ERROR_DATA_INVALID, Err_RefNotInt, cname);
		return ERROR;
	    }
	    ref_type = type;
	    
	    ncurrent = nitems;
	    for (j=0; j<rank; j++)
	        ncurrent *= shape[j];
	    
	    if (ncurrent > 0) {
                
		if (!DXGetArrayInfo(target, &nitems, &type, &cat, &rank, shape))
		    return ERROR;
		
		ntarget = nitems;
                
                /* only do this if they are already irregular */
                if (DXGetArrayClass(current) == CLASS_ARRAY) {
                    if ((ip = (int *)DXGetArrayData(current)) == NULL)
                        return ERROR;
		    cp = (unsigned char *) ip;
                    
		    /* neighbors can have -1's as indicies */
                    lim = strcmp(cname, "neighbors") ? 0 : -1;

		    for (j=0; j < ncurrent; j++) {
			if (ref_type == TYPE_INT) index = *(ip++);
			else                      index = *(cp++);

			if (index < lim || index >= ntarget) {
			    DXSetError(ERROR_DATA_INVALID, Err_OutOfRange,
				j+1, ending(j+1), cname, index, lim, ntarget-1);
			    return ERROR;
			}
		    }

                } else if (DXQueryGridConnections(current, &rank, counts)) {
		    for (j=0, ncurrent=1; j<rank; j++)
			ncurrent *= counts[j];
                    if (ncurrent > ntarget) {
                        DXSetError(ERROR_DATA_INVALID,
                                 Err_DiffCount, "ref",
                                 ncurrent, cname, ntarget, tname);
                        return ERROR;
                    }
                } else {
                    /* mesh array of mixed path and irregular arrays. */
                    /* have to handle the terms separately */
                }
	    }
	} /* end of if (has ref) */


        /* der - can be string lists here */
	if ((o = DXGetAttribute((Object)current, "der")) != NULL) {

	    if (DXExtractString(o, &tname)) {    /* simple string? */
		if ((target = (Array)DXGetComponentValue(f, tname)) == NULL) {
		    DXSetError(ERROR_DATA_INVALID,
			       Err_MissingComp, tname, "der", cname);
		    return ERROR;
		}
		
		if (DXGetObjectClass((Object)target) != CLASS_ARRAY) {
		    DXSetError(ERROR_DATA_INVALID,
			       Err_NotArray, tname, "der", cname);
		    return ERROR;
		}
	    } else if (DXExtractNthString(o, 0, &tname)) {  /* string list? */
		for (j=0; DXExtractNthString(o, j, &tname); j++) {
		    
		    if ((target = (Array)DXGetComponentValue(f, tname)) == NULL) {
			DXSetError(ERROR_DATA_INVALID,
				   Err_MissingComp, tname, "der", cname);
			return ERROR;
		    }
		    
		    if (DXGetObjectClass((Object)target) != CLASS_ARRAY) {
			DXSetError(ERROR_DATA_INVALID,
				   Err_NotArray, tname, "der", cname);
			return ERROR;
		    }
		}
	    } else {  /* neither string or string list */
		DXSetError(ERROR_DATA_INVALID, 
			   Err_MustBeStringList, "der", cname);
		return ERROR;
	    }
	    
	} /* end of if (has der) */

        /* element type */
	if ((s = (String)DXGetAttribute((Object)current, "element type")) != NULL) {
	    if ((DXGetObjectClass((Object)s) != CLASS_STRING) ||
	        ((tname = DXGetString(s)) == NULL)) {
		DXSetError(ERROR_DATA_INVALID, 
			 Err_MustBeString, "element type", cname);
		return ERROR;
	    }
	    
	    if (!strcmp(cname, "connections") && 
		DXQueryGridConnections(current, &rank, counts)) {

		if (!elemtypecheck(rank, tname))
		    return ERROR;
	    }

	} /* end of if (has element type) */

    }  /* for each component in the field */

    /* check for missing positions component if the field has more than
     *  one component.
     */
    if (i > 1 && !DXGetComponentValue(f, "positions"))
	DXWarning("importing a field with no `positions' component");

    return OK;
}
Ejemplo n.º 25
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.º 26
0
static int
doLeaf(Object *in, Object *out)
{
  int result=0;
  Field field;
  Category category;
  Category lookup_category;
  int rank, shape[30];
  char *cat_comp;
  char *data_comp;
  char *lookup_comp;
  char name_str[256];
  char *opstr;
  int operation;
  int lookup_knt;
  int lookup_knt_provided = 0;
  Array cat_array = NULL;
  Array data_array = NULL;
  Array out_array = NULL;
  Array array = NULL;
  Array lookup_array = NULL;
  float *out_data;
  int data_knt, cat_knt;
  int out_knt=0;
  Type cat_type, data_type, lookup_type;
  float floatmax;
  ICH invalid;

  if (DXGetObjectClass(in[0]) == CLASS_FIELD)
  {
    field = (Field)in[0];

    if (DXEmptyField(field))
      return OK;
  }

  if (!DXExtractString((Object)in[1], &opstr))
	opstr = STR_COUNT;

  if (!strcmp(opstr, STR_COUNT))
    operation = STAT_COUNT;
  else if (!strcmp(opstr, STR_MEAN))
    operation = STAT_MEAN;
  else if (!strcmp(opstr, STR_SD))
    operation = STAT_SD;
  else if (!strcmp(opstr, STR_VAR))
    operation = STAT_VAR;
  else if (!strcmp(opstr, STR_MIN))
    operation = STAT_MIN;
  else if (!strcmp(opstr, STR_MAX))
    operation = STAT_MAX;
  else if (!strcmp(opstr, STR_ACCUM))
    operation = STAT_ACCUM;
  else
    operation = STAT_UNDEF;

  if (operation == STAT_UNDEF) {
    DXSetError(ERROR_BAD_PARAMETER, "statistics operation must be one of: count, mean, sd, var, min, max");
    goto error;
  }

  if (!DXExtractString((Object)in[2], &cat_comp))
	cat_comp = STR_DATA;
  if (!DXExtractString((Object)in[3], &data_comp))
	data_comp = STR_DATA;

  if (in[0])
  {
      if (DXGetObjectClass(in[0]) != CLASS_FIELD)
      {
        DXSetError(ERROR_BAD_CLASS, "\"input\" should be a field");
        goto error;
      }

      cat_array = (Array)DXGetComponentValue((Field)in[0], cat_comp);
      if (! cat_array)
      {
        DXSetError(ERROR_MISSING_DATA, "\"input\" has no \"%s\" categorical component", cat_comp);
        goto error;
      }

      if (DXGetObjectClass((Object)cat_array) != CLASS_ARRAY)
      {
        DXSetError(ERROR_BAD_CLASS, "categorical component \"%s\" of \"input\" should be an array", cat_comp);
        goto error;
      }

      if (!HasInvalid((Field)in[0], cat_comp, &invalid))
      {
        DXSetError(ERROR_INTERNAL, "Bad invalid component");
        goto error;
      }

      if (invalid)
      {
        DXSetError(ERROR_DATA_INVALID, "categorical component must not contain invalid data");
        goto error;
      }

      DXGetArrayInfo(cat_array, &cat_knt, &cat_type, &category, &rank, shape);
      if ( (cat_type != TYPE_BYTE && cat_type != TYPE_UBYTE && cat_type != TYPE_INT && cat_type != TYPE_UINT)
             || category != CATEGORY_REAL || !((rank == 0) || ((rank == 1)&&(shape[0] == 1))))
      {
        DXSetError(ERROR_DATA_INVALID, "categorical component %s must be scalar non-float", cat_comp);
        goto error;
      }

      if (operation != STAT_COUNT) {
        data_array = (Array)DXGetComponentValue((Field)in[0], data_comp);
        if (! data_array)
        {
          DXSetError(ERROR_MISSING_DATA, "\"input\" has no \"%s\" data component", data_comp);
          goto error;
        }

        if (DXGetObjectClass((Object)data_array) != CLASS_ARRAY)
        {
          DXSetError(ERROR_BAD_CLASS, "data component \"%s\" of \"input\" should be an array", data_comp);
          goto error;
        }

        DXGetArrayInfo(data_array, &data_knt, &data_type, &category, &rank, shape);
        if ( (data_type != TYPE_BYTE && data_type != TYPE_UBYTE && data_type != TYPE_INT && data_type != TYPE_UINT
             && data_type != TYPE_FLOAT && data_type != TYPE_DOUBLE)	
               || category != CATEGORY_REAL || !((rank == 0) || ((rank == 1)&&(shape[0] == 1))))
        {
          DXSetError(ERROR_DATA_INVALID, "data component \"%s\" must be scalar", data_comp);
          goto error;
        }

        if (data_knt != cat_knt)
        {
	  DXSetError(ERROR_DATA_INVALID, "category and data counts must be the same");
	  goto error;
        }
      }
  }

  if (in[4]) {
      if (DXExtractString((Object)in[4], &lookup_comp)) {
	    lookup_array = (Array)DXGetComponentValue((Field)in[0], lookup_comp);
	    if (!lookup_array)
	    {
	      DXSetError(ERROR_MISSING_DATA, "\"input\" has no \"%s\" lookup component", lookup_comp);
	      goto error;
	    }
      } else if (DXExtractInteger((Object)in[4], &lookup_knt)) {
	    lookup_knt_provided = 1;
	    out_knt = lookup_knt;
      } else if (DXGetObjectClass((Object)in[4]) == CLASS_ARRAY) {
	    lookup_array = (Array)in[4];
	    sprintf(name_str, "%s lookup", cat_comp);
	    lookup_comp = name_str;
      } else { 
            DXSetError(ERROR_DATA_INVALID, "lookup component must be string, integer, or array");
	    goto error;
      }
  } else {
      sprintf(name_str, "%s lookup", cat_comp);
      lookup_comp = name_str;
      lookup_array = (Array)DXGetComponentValue((Field)in[0], lookup_comp);
  } 

  if (lookup_array) {
    DXGetArrayInfo(lookup_array, &lookup_knt, &lookup_type, &lookup_category, &rank, shape);
    out_knt = lookup_knt;
  } else if (!lookup_knt_provided){
    if (!DXStatistics((Object)in[0], cat_comp, NULL, &floatmax, NULL, NULL)) {
      DXSetError(ERROR_INTERNAL, "Bad statistics on categorical component");
      goto error;
    }
    out_knt = (int)(floatmax+1.5);
  }

  out_array = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 0);
  if (! out_array)
    goto error;

  if (! DXSetAttribute((Object)out_array, "dep", (Object)DXNewString("positions")))
    goto error;

  if (! DXAddArrayData(out_array, 0, out_knt, NULL))
    goto error;

  if (out[0])
  {
    if (DXGetObjectClass(out[0]) != CLASS_FIELD)
    {
      DXSetError(ERROR_INTERNAL, "non-field object found in output");
      goto error;
    }

    if (DXGetComponentValue((Field)out[0], "data"))
      DXDeleteComponent((Field)out[0], "data");

    if (! DXSetComponentValue((Field)out[0], "data", (Object)out_array))
      goto error;

    if (lookup_array) {
      if (! DXSetComponentValue((Field)out[0], lookup_comp, (Object)lookup_array))
        goto error;
    }
  }
  else
  {
    out[0] = (Object)DXNewField();
    array = DXMakeGridPositions(1, out_knt, 0.0, 1.0);
    if (!array)
	goto error;
    DXSetComponentValue((Field)out[0], "positions", (Object)array);
    array = DXMakeGridConnections(1, out_knt);
    if (!array)
	goto error;
    DXSetComponentValue((Field)out[0], "connections", (Object)array);
    DXSetComponentValue((Field)out[0], "data", (Object)out_array);
    if (lookup_array) {
      if (! DXSetComponentValue((Field)out[0], lookup_comp, (Object)lookup_array))
        goto error;
    }
  }

  out_data = DXGetArrayData(out_array);
  if (! out_data)
    goto error;

  result = CategoryStatistics_worker(
  		out_data, cat_knt, out_knt, cat_array, data_array,
		cat_type, data_type, operation);

  if (! result) {
     if (DXGetError()==ERROR_NONE)
        DXSetError(ERROR_INTERNAL, "error return from user routine");
     goto error;
  }

  result = (DXEndField((Field)out[0]) != NULL);

error:
  return result;
}
Ejemplo n.º 27
0
Error DXCallOutboard (PFE m, int dxfd)
{
    static int  firsttime = 1;
    Array	oarr;
    int		nin	= 0;
    int		nout	= 0;
    Object	*ilist = NULL;
    Object	*olist = NULL;
    Error	ret    = ERROR;
    Error	modret;
    ErrorCode	ecode;
    char        *emessptr = NULL;
    Group	iobj	= NULL;
    Group	oobj	= NULL;
    Array	code	= NULL;
    String	mess	= NULL;
    int		i;
    int		*iptr;
    int		count	= 0;
    int		one = 1;
    int         zero = 0;


    if (firsttime && ! callsetup (dxfd)) {
	host_status = HOST_CLOSED;
	return ERROR;
    }

	
    /*
     * Import the remote object, extract the number of inputs and outputs,
     * and rip them apart appropriately.  group members are: 
     * input parm count, 
     * input object list (the pointers values don't mean anything in this
     * address space; the interesting part is whether they are NULL or not),
     * the output parm count,
     * and then each input object which isn't null.
     */

    iobj = (Group) _dxfImportBin_FP(dxfd);
    if(iobj == NULL)
        goto finish_up;

    if (!DXExtractInteger (DXGetEnumeratedMember (iobj, 0, NULL), &nin))
	goto finish_up;

    ilist = (Object *) DXAllocateZero(sizeof (Object) * nin);
    if (!ilist)
	goto finish_up;
    
    iptr = (int *)DXGetArrayData((Array)DXGetEnumeratedMember (iobj, 1, NULL));

    if (!DXExtractInteger (DXGetEnumeratedMember (iobj, 2, NULL), &nout))
	goto finish_up;

    count = 3;
    for (i=0; i<nin; i++) 
    {
	if (iptr[i] == (int)NULL)
	    continue;

	ilist[i] = DXGetEnumeratedMember(iobj, count++, NULL);
    }

    olist = (Object *) DXAllocateZero(sizeof (Object) * nout);
    if (!olist)
	goto finish_up;

    /*
     * Call the module, and save the error code if set.
     */

    DXResetError();
    
    _dxd_exOutboard = TRUE;
    modret = m (ilist, olist);
    _dxd_exOutboard = FALSE;

    /*
     * get these now, before we do something else which overwrites them.
     */
    ecode = DXGetError ();
    emessptr = DXGetErrorMessage();

    /* 
     * now BEFORE we do anything which allocates memory or new objects
     * check the return objects for validity.  we saw a case where the
     * object being returned was deleted, and then the DXNewGroup() 
     * below got the exact same address allocated, so when we put the
     * group together we put a reference to the parent group into the
     * same group as a child.  bad things followed...
     *
     * (the two calls above to geterror & geterrormsg don't allocate anything;
     * they return a value & ptr to a static respectively)
     */
    for (i = 0; i < nout; i++) {
	if (olist[i] == NULL)
	    continue;

	switch (DXGetObjectClass(olist[i])) {
	  case CLASS_DELETED:
	  case CLASS_MIN:
	  case CLASS_MAX:
	    if (ecode == ERROR_NONE) {
		DXSetError(ERROR_BAD_CLASS, "bad object returned as output %d from outboard module", i);
		ecode = DXGetError ();
		emessptr = DXGetErrorMessage();
	    } else
		DXAddMessage("bad object returned as output %d from outboard module", i);

	    olist[i] = NULL;
	  default: /* Lots of other classes */
	    break;
	}
    }

    /*
     * Set up for return, at least the return code and message.
     */
    
    oobj = DXNewGroup ();
    if (oobj == NULL)
	goto finish_up;

    if (!(code = DXNewArray (TYPE_INT, CATEGORY_REAL, 0)))
	goto finish_up;

    if (! DXAddArrayData (code, 0, 1, (Pointer) &ecode))
	goto finish_up;

    mess = DXNewString (emessptr);
    if (mess == NULL)
	goto finish_up;

    if (! DXSetEnumeratedMember (oobj, 0, (Object) code) ||
	! DXSetEnumeratedMember (oobj, 1, (Object) mess))
	goto finish_up;

    /*
     * If everything is OK then go ahead and return any objects too.
     */

    if (modret == OK)
    {
	/* send output list so the caller can tell which outputs
	 * were set.  only send the non-NULL ones.
	 */
	oarr = DXNewArray(TYPE_INT, CATEGORY_REAL, 0);
	if (!oarr)
	    goto finish_up;
	for (i = 0; i < nout; i++) {
	    if (! DXAddArrayData(oarr, i, 1, (olist+i) ? 
                                 (Pointer)&one : (Pointer)&zero))
		goto finish_up;
	}
	
	if (! DXSetEnumeratedMember(oobj, 2, (Object)oarr))
	    goto finish_up;
	

	count = 3;
        for (i = 0; i < nout; i++)
        {
	    if (olist[i] == NULL)
		continue;

	    if (! DXSetEnumeratedMember (oobj, count++, olist[i]))
		goto finish_up;

	}
    }

    if (!_dxfExportBin_FP ((Object)oobj, dxfd))
	goto finish_up;

    /* 
     * if you get to this point, there were no other errors.
     */
    ret = OK;


finish_up:

    /*
     * get rid of space not needed anymore.  this doesn't matter for
     * one-shots, but for persistent modules we will run out of memory
     * eventually if these aren't deleted.
     */

    DXDelete ((Object) iobj);
    DXDelete ((Object) oobj);

    DXFree ((Pointer) ilist);
    DXFree ((Pointer) olist);

    return ret;
}