コード例 #1
0
ファイル: enumerate.c プロジェクト: BackupTheBerlios/opendx2
int
m_Enumerate(Object *in, Object *out)
{
    int i;
    int *ip = NULL;
    char *cp = NULL;
    out[0] = NULL;


    icheck(in[0], "start");
    icheck(in[1], "end");

    if (in[2]) {
	if (!DXExtractInteger(in[2], &i) || (i <= 0)) {
	    DXSetError(ERROR_BAD_PARAMETER, "#10020", "count");
	    goto error;
	}
	ip = &i;
    }
    
    icheck(in[3], "delta");

    if (in[4] && !DXExtractString(in[4], &cp)) {
	DXSetError(ERROR_BAD_PARAMETER, "#10200", "method");
	goto error;
    }
    
    out[0] = (Object)MakeSequence((Array)in[0], (Array)in[1], ip, 
				  (Array)in[3], cp);
    
  error:
    return out[0] ? OK : ERROR;
}
コード例 #2
0
ファイル: mach.c プロジェクト: JasonChunZheng/vtf
Error m_MachNumber (Object * in,Object * out) {
   Object * get;
   int fields,i,ngases;

   /* Verify input */
   if (in[0]==NULL) {
      DXSetError(ERROR_MISSING_DATA,"Input field 0 must be specified");
      goto error;
   }
   if (!DXExtractInteger(in[0],&ngases)) {
      DXSetError(ERROR_DATA_INVALID,"Could not extract INTEGER from field 0");
      goto error;
   }
   fields=INPUT_FIELDS+ngases;
   if (ngases < NGASES_MIN || ngases > NGASES_MAX) {
      DXSetError(ERROR_BAD_PARAMETER,
                 "The value of input field 0 must be %d <= X <= %d",
                 NGASES_MIN,NGASES_MAX);
      goto error;
   }
   for (i=1; i<fields; i++) {
      if (in[i]==NULL) {
         DXSetError(ERROR_MISSING_DATA,"Input field %d must be specified",i);
         goto error;
      }
   }

   /* Since this module is meant to operate on an existing Field / MultiGrid
    * object, initialize the output fields as a copy of the second input
    * field.  */
   for (i=0; i<OUTPUT_FIELDS; i++) {
      if (!(out[i]=DXCopy(in[1],COPY_STRUCTURE)))
         goto error;
      /* If in[1] is an array, DXCopy() will return a pointer to the input
       * object. Since this cannot be written to, an exception will be
       * raised.  */
      if (in[1]==out[i]) {
         DXSetError(ERROR_DATA_INVALID,
                    "Input fields 1-%d should be Field / MultiGrid objects",
                    fields);
         goto error;
      }
   }

   /* Skip the first input field as it is not a Field / MultiGrid object.  */
   get=in+1;
   if (!traverse (w_MachNumber,get,fields-1,out,OUTPUT_FIELDS))
      goto error;

   return OK;
   
error:
   for (i=0; i<OUTPUT_FIELDS; i++) {
      DXDelete(out[i]);
      out[i]=NULL;
   }
   return ERROR;
}
コード例 #3
0
ファイル: catstats.c プロジェクト: BackupTheBerlios/opendx2
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;
}
コード例 #4
0
ファイル: enumerate.c プロジェクト: BackupTheBerlios/opendx2
/* 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;
}
コード例 #5
0
ファイル: cachegraph.c プロジェクト: BackupTheBerlios/opendx2
/*
 * recursively generate the recipes for a node in the graph
 */
void _dxf_ExComputeRecipes(Program *p, int funcInd)
{
    gfunc	*n = FETCH_LIST(p->funcs, funcInd);
    int		i, j, size, ntags, macro_tags=0, extra_tags, async_tags=0;
    gvar	*gv;
    uint32 	tcrc;
    gvar	*out;
    uint32 	*inTags, staticTags[STATIC_TAGS];
    int		varInd, *varIndp;
    int		varInd2;
    ProgramVariable *pv, *inpv, *pv_key;
    MacroRef 	*mr;
    AsyncVars 	*avars;
    _excache    fcache;
    _excache    pvcache;
    Program     *subP=NULL;
    int  tag_changed = FALSE;
    uint32 crc = 0xFFFFFFFF;
    char 	*async_name=NULL, *name;
    int		passthru = FALSE;
    char mod_cache_str[ MAX_PATH_STR_LEN ], *mod;
    
    /*  Get module path string  */
    mod = _dxf_ExGFuncPathToCacheString( n );
    if ( strlen(mod) > sizeof(mod_cache_str)-1 )
    _dxf_ExDie("Module path is too long");
    strcpy( mod_cache_str, mod );

check_async:
    if(n->flags & (MODULE_ASYNC | MODULE_ASYNCLOCAL)) {
        if(p->loopctl.first && (n->flags & MODULE_ASYNCLOCAL)) {
            if(strcmp(n->name, "GetLocal") == 0)
                DXReadyToRunNoExecute(mod_cache_str);
        }
        varInd = *FETCH_LIST(n->inputs, n->nin - 2);
        pv = FETCH_LIST(p->vars, varInd);
        if(!pv->gv)
            _dxf_ExDie("Cannot compute a cache tag from a NULL gvar");
        if(n->flags & MODULE_ASYNCNAMED) {
            varInd2 = *FETCH_LIST(n->inputs, n->rerun_index);
            pv_key = FETCH_LIST(p->vars, varInd2);
            if(pv_key->gv && pv_key->gv->obj) {
                if(pv->gv->obj)
                    DXDelete(pv->gv->obj);
                pv->gv->obj = DXReference(pv_key->gv->obj);    
            }
        }
        if(!pv->gv->obj)
            _dxf_ExDie("Cannot compute a cache tag from a NULL gvar");
        /* Put an extra reference on this input, we don't want this gvar
           to be deleted until the current graph finishes executing. This
           is incase the results were thrown out of cache and because of
           a switch need to run again. If this is in a loop it will get
           an extra ref each time through the loop which isn't needed but
           will get cleaned up ok in the end.
        */
        ExReference(pv->gv);
        pv->refs++;
        async_name = DXGetString((String)pv->gv->obj);
        varInd = *FETCH_LIST(n->inputs, n->nin - 1);
        pv = FETCH_LIST(p->vars, varInd);
        gv = (gvar *)_dxf_ExGlobalVariableSearch(async_name);
        if(gv) {
            if(gv != pv->gv) {
                _dxf_ExUndefineGvar(pv->gv);
                _dxf_ExDefineGvar(pv->gv, gv->obj);
            }
            ExDelete(gv);
        }
        else {
            Object value;
            value = (Object) _dxfExNewInteger (0);
            _dxf_ExDefineGvar(pv->gv, (Object)_dxfExNewInteger(0));
            _dxf_ExUpdateGlobalDict (async_name, value, 0);
        }
        /* Put an extra reference on this input, we don't want this gvar
           to be deleted until the current graph finishes executing. This
           is incase the results were thrown out of cache and because of
           a switch need to run again. If this is in a loop it will get
           an extra ref each time through the loop which isn't needed but
           will get cleaned up ok in the end.
         */
         ExReference(pv->gv);
         pv->refs++;
    }

    if(n->ftype == F_MACRO) {
        subP = n->func.subP;
        macro_tags = SIZE_LIST(subP->macros);
        async_tags = SIZE_LIST(subP->async_vars);
        extra_tags = macro_tags + async_tags;
    }
    else if(n->flags & MODULE_LOOP) {
        /* to cause the cache tag of loop modules to change even though */
        /* their inputs don't change, use the counter for the loop */
        extra_tags = 1;
    }
    else extra_tags = 0;
    ntags = n->nin+extra_tags;

    if(ntags > STATIC_TAGS)
        inTags = (uint32 *)DXAllocate(ntags*sizeof(uint32));
    else inTags = staticTags;

    /* add the crc of all of the module inputs to the total crc */
    for (i = 0; i < SIZE_LIST(n->inputs); i++)
    {
	varIndp = FETCH_LIST(n->inputs, i);
        if(varIndp == NULL)
            _dxf_ExDie("Executive Inconsistency: _dxf_ExComputeRecipes");
        varInd = *varIndp;
      
        inTags[i] = computeRecipe(p, varInd);
	ExDebug ("1", "Cache value for input %s.%d = 0x%08x ",
			    n->name, i, inTags[i]);
    }

    if(n->ftype == F_MACRO) {
        for (j = 0; j < macro_tags; j++, i++)
        {
            crc = 0xFFFFFFFF;
            mr = FETCH_LIST(subP->macros, j);
            inTags[i] = _dxf_ExCRCInt(crc, mr->index);
        }
        for (j = 0; j < async_tags; j++, i++) {
            avars = FETCH_LIST(subP->async_vars, j);
            pv = FETCH_LIST(p->vars, avars->nameindx);
            if(!pv->gv || !pv->gv->obj)
                _dxf_ExDie("Cannot compute a cache tag from a NULL async name");
            name = DXGetString((String)pv->gv->obj);
            pv = FETCH_LIST(p->vars, avars->valueindx);
            gv = (gvar *)_dxf_ExGlobalVariableSearch(name);
            if(gv) {
                if(gv != pv->gv) {
                    _dxf_ExUndefineGvar(pv->gv);
                    _dxf_ExDefineGvar(pv->gv, gv->obj);
                }
                ExDelete(gv);
            }
            else {
                Object value;
                value = (Object) _dxfExNewInteger (0);
                _dxf_ExDefineGvar(pv->gv, (Object)_dxfExNewInteger(0));
                _dxf_ExUpdateGlobalDict (name, value, 0);
            }
            inTags[i] = computeRecipe(p, avars->valueindx);
        }
    }
    else if(n->flags & MODULE_LOOP) {
        /* to cause the cache tag of loop modules to change even though */
        /* their inputs don't change, use the counter for the loop */
        crc = 0xFFFFFFFF;
        inTags[i] = _dxf_ExCRCInt(crc, p->loopctl.counter);
    }

    if((n->flags & MODULE_PASSTHRU) && (n->nin == n->nout+1))
        passthru = TRUE;
        
    if(n->flags & (MODULE_CONTAINS_STATE | MODULE_CHANGES_STATE))
    {
        Object new_tag_obj, old_tag_obj;
        uint32 oldtag, newtag;

        newtag = _dxf_ExGenCacheTag (n->name,0,ntags,inTags);
        new_tag_obj = (Object)DXMakeInteger(newtag);
        old_tag_obj = DXGetCacheEntry(mod_cache_str, ntags, 0);
        if(!old_tag_obj) {
            DXSetCacheEntry(new_tag_obj, CACHE_PERMANENT, mod_cache_str, ntags, 0);
        }
        else {
            /* we don't want an extra reference on this */
            DXDelete(old_tag_obj); 
            if(!DXExtractInteger(old_tag_obj, (int *)&oldtag))
                oldtag = 0;
            /* this means we just caused a DXReadyToRun so we know */
            /* this macro will run this time, save the new cache tag */
            if(oldtag == 0) {
                DXSetCacheEntry(new_tag_obj,CACHE_PERMANENT,mod_cache_str,ntags,0);
                DXDelete(old_tag_obj);
            }
            else if(oldtag != newtag) {
                /* An input has changed since last time, we need to */ 
                /* cause execution of this macro and we need to recompute */
                /* the cache tag. */
                DXReadyToRunNoExecute(async_name);
                DXDelete(new_tag_obj);
                new_tag_obj = (Object)DXMakeInteger(0);
                DXSetCacheEntry(new_tag_obj,CACHE_PERMANENT,mod_cache_str,ntags,0);
                DXDelete(old_tag_obj);
                goto check_async;
            }
            else DXDelete(new_tag_obj);
        }
    }

    /* generate the recipes for all of the outputs from this module */
    /* Update the pathtag table if module cache attribute is "cache last" */
    n->tag_changed = FALSE;
    for (i = 0; i < SIZE_LIST(n->outputs); i++)
    {
	varIndp = FETCH_LIST(n->outputs, i);
        if(varIndp == NULL)
            _dxf_ExDie("Executive Inconsistency: _dxf_ExComputeRecipes");
        varInd = *varIndp;
	pv = FETCH_LIST(p->vars, varInd);
        pv->is_output = TRUE;
	out = pv->gv;

	if (out->reccrc == 0 || 
	    (n->required != -1 && (!IsSwitch(n) || !IsFastSwitch(n)))) {
            /* This code is currently just intended for macrostart */
            if(passthru) {
	        varInd2 = *FETCH_LIST(n->inputs, i+1);
		if (varInd2 != -1) {
                    inpv = FETCH_LIST(p->vars, varInd2);
                    tcrc = inpv->gv->reccrc;
		} else
	            tcrc = _dxf_ExGenCacheTag (n->name,i,n->nin+extra_tags,inTags);
            }
            else
	        tcrc = _dxf_ExGenCacheTag (n->name,i,n->nin+extra_tags,inTags);
            if(out->reccrc != 0 && tcrc != out->reccrc)
                _dxf_ExUndefineGvar(out);
            pv->reccrc = out->reccrc = tcrc;
	    /* make process group name part of cache tag */
	    if(n->procgroupid) {
		size = strlen (n->procgroupid);
		out->reccrc = EXTAG(_dxf_ExCRCByteV(out->reccrc & 0x7fffffff,
		    (unsigned char *) n->procgroupid, 1, size));
	    }
	    ExDebug ("1", "Cache value for %s.%d = 0x%08x ",
			    n->name, i, out->reccrc);
	}
        
        pvcache = pv->excache;
        fcache  = n->excache;
       
        if((n->flags & (MODULE_ASYNC | MODULE_ASYNCLOCAL)) && 
           (pvcache == CACHE_ALL)) 
            pvcache = pv->excache = CACHE_LAST;
  
        /* I don't think we allow the user to turn off cacheing for */
        /* macros that have state in them. */
        if(n->flags & MODULE_CHANGES_STATE)
            pvcache = pv->excache = CACHE_LAST_PERM;
        if(n->flags & MODULE_CONTAINS_STATE)
            pvcache = pv->excache = CACHE_LAST;

        /* object lvl cache attribute overrides function lvl cache attribute */ 
        
        if (pvcache == CACHE_LAST || pvcache == CACHE_LAST_PERM) 
            tag_changed = _dxf_ExManageCacheTable(&n->mod_path, out->reccrc, i);
        else 
            if(fcache == CACHE_LAST && !pv->cacheattr) 
                tag_changed = _dxf_ExManageCacheTable(&n->mod_path, out->reccrc, i);
        n->tag_changed = tag_changed;
    }

    if(n->nout == 0 && !(n->flags & MODULE_SIDE_EFFECT)) {
        tcrc = _dxf_ExGenCacheTag (n->name, 0, n->nin+extra_tags, inTags);
        n->tag_changed = _dxf_ExManageCacheTable(&n->mod_path, tcrc, 0);
    }

    if(ntags > STATIC_TAGS)
        DXFree(inTags);
}
コード例 #6
0
ファイル: light.c プロジェクト: BackupTheBerlios/opendx2
Error
m_Light(Object *in, Object *out)
{
    Vector v;
    RGBColor c;
    int camera = 0;
    char *colorstr;

    /* if first parm isn't a vector, try to see if it's a camera object.
     *  if so, use the same calculation as the renderer uses for the default
     *  light - slightly to the left of the camera position.
     */
    if (!in[0]) {
	v.x = v.y = 0.0;
	v.z = 1.0;
    } 
    else if (!DXExtractParameter(in[0], TYPE_FLOAT, 3, 1, (Pointer)&v)) {

	if (DXGetObjectClass(in[0]) == CLASS_CAMERA) {
	    Point from, to;
	    Vector eye, up, left;

	    DXGetView((Camera)in[0], &from, &to, &up);
	    eye = DXNormalize(DXSub(from,to));
	    left = DXCross(eye, up);
	    v = DXAdd(eye, left);
	} 
	else {
	    DXSetError(ERROR_BAD_PARAMETER, "#10670", "`where'");
	    return ERROR;
	}
    }             


    /* color, default is white */
    if (!in[1]) {
	c.r = c.b = c.g = 1.0;
    } 
    else if (DXExtractString(in[1],&colorstr)) {
        if (!DXColorNameToRGB(colorstr, &c))
	    /* it sets a reasonable error string */
	    return ERROR;
    } 
    else if (!DXExtractParameter(in[1], TYPE_FLOAT, 3, 1, (Pointer)&c)) {
        DXSetError(ERROR_BAD_PARAMETER, "#10510", "color");
        return ERROR;
    }             

    
    /* absolute or camera relative? */
    if (in[2] && !DXExtractInteger(in[2], &camera)) {
        DXSetError(ERROR_BAD_PARAMETER, "#10070", "camera flag");
        return ERROR;
    }


    if (!camera)
	out[0] = (Object)DXNewDistantLight(v, c);
    else
	out[0] = (Object)DXNewCameraDistantLight(v, c);
    
		
    return(out[0] ? OK : ERROR);
}
コード例 #7
0
ファイル: convert.c プロジェクト: BackupTheBerlios/opendx2
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;
}
コード例 #8
0
ファイル: hwRender.c プロジェクト: BackupTheBerlios/opendx2
Error
_dxfAsyncRender (dxObject r, Camera c, char *obsolete, char *displayString)
{
    Private 	    cacheObject = NULL;
    tdmChildGlobalP   globals = NULL;
    char*		    cacheId = NULL;
    tdmParsedFormatT *pFormat = NULL;
    dxObject	   attr;


    ENABLE_DEBUG();
    DEBUG_MARKER("_dxfAsyncRender ENTRY");
    ENTRY(("_dxfAsyncRender (0x%x, 0x%x, \"%s\", \"%s\")",
           r, c, obsolete, displayString));

# if defined(DEBUG)

    if(DXGetAttribute(r, "force env var")) {
        char *Buff;

        if(DXExtractString(DXGetAttribute(r, "force env var"), &Buff)) {
            PRINT(("Putting Variable %s\n", Buff));
            putenv(Buff);
        }
    }
#  endif


    if (!c && !DXGetImageBounds(r,NULL,NULL,NULL,NULL))
        goto error;


    /* get host and window name from display string, fill in the cache id */
    if (!(pFormat = _tdmParseDisplayString (displayString, &cacheId)))
        goto error;

    /* validate the display string */
    if (!(_validateDisplayString(pFormat, 1)))
        goto error ;

    /* Get a pointer to the global data, out of the cache or create a new one. */
    if((cacheObject = (Private) DXGetCacheEntry(cacheId, 0, 0)) != NULL) {
        globals = (tdmChildGlobalP) DXGetPrivateData(cacheObject) ;
#if defined(DX_NATIVE_WINDOWS)
        /*
         * Now lock globals so that rendering doesn't occur in another
         * thread until the setup is done.  If we create a globals structure 
         * here, the lock is created in CreateRenderModule, and its created 
         * owned.
         */
        {
            DEFGLOBALDATA(globals);
            if (DXWaitForSignal(1, &LOCK) == WAIT_TIMEOUT)
                goto error;
        }
#endif

    } else {
        if(!(globals = (tdmChildGlobalP)_dxfCreateRenderModule(pFormat)))
            return ERROR;

        /* save globals in cache; call _dxfEndRenderModule when cache deleted */
        if(!(cacheObject = (Private)
                           DXNewPrivate((Pointer) globals,
                                        (Error (*)(Pointer))_dxfEndRenderModule))) {
            /* Can't cache tdm globals */
            DXErrorGoto (ERROR_INTERNAL, "#13290");
        }

        /* Create a reference so this doesn't get deleted while I'm using it */
        DXReference ((Pointer)cacheObject);

        /* associate cacheId with cacheObject, set to permanent status */
        if(! DXSetCacheEntry((Pointer)cacheObject, CACHE_PERMANENT,
                             cacheId, 0, 0)) {
            /* Can't set cache entry for tdm globals */
            DXErrorGoto (ERROR_INTERNAL, "#13300") ;
        }

        /* save the cacheId to allow cache deletion upon DestroyNotify event */
        if(! (globals->cacheId = tdmAllocate(strlen(cacheId)+1))) {
            DXErrorGoto (ERROR_NO_MEMORY, "") ;
        }

        /* save cacheId */
        strcpy(globals->cacheId,cacheId) ;
    }

    /* Now that we have a global store, use it */
    {
        int needInit = 0;
        DEFGLOBALDATA(globals);

        if (!OBJECT || (OBJECT && OBJECT_TAG != DXGetObjectTag(r)))
        {
            if (OBJECT)
                DXDelete(OBJECT);

            OBJECT = DXReference(r);
            OBJECT_TAG = DXGetObjectTag(r);
            needInit = 1;
        }

        if (!CAMERA || (CAMERA && CAMERA_TAG != DXGetObjectTag((dxObject)c)))
        {
            if (CAMERA)
                DXDelete(CAMERA);

            CAMERA = DXReference((dxObject)c);
            CAMERA_TAG = DXGetObjectTag((dxObject)c);
            needInit = 1;
        }

        _dxfInitializeStereoSystemMode(globals, DXGetAttribute(r, "stereo system mode"));
        _dxfInitializeStereoCameraMode(globals, DXGetAttribute(r, "stereo camera mode"));

        if(CAMERA && needInit)
        {
            if(!_dxfInitRenderObject(LWIN)) {
                /* unable to set up for rendering */
                DXErrorGoto(ERROR_NO_HARDWARE_RENDERING, "#13350");
            }
        }

        /* Handle X events and redraw the image */
#if !defined(DX_NATIVE_WINDOWS)
        if(! _dxfProcessEvents (-1, globals, 1))
            goto error;
#endif

    }

    if ((attr = DXGetAttribute((dxObject)c, "camera interaction mode")) == NULL)
        if ((attr = DXGetAttribute(r, "object interaction mode")) == NULL)
            attr = DXGetAttribute(r, "interaction mode");

    if (attr) {
        Array amode;
        int mode;

        if (DXGetObjectClass(attr) == CLASS_GROUP) {
            if (NULL == (amode = (Array)DXGetMember((Group)attr, "mode")))
                DXErrorGoto(ERROR_DATA_INVALID,
                            "interaction mode args group must contain a member named \"mode\"");
        } else if (DXGetObjectClass(attr) != CLASS_ARRAY) {
            DXErrorGoto(ERROR_DATA_INVALID,
                        "interaction mode args must be a group or array");
        } else
            amode = (Array)attr;

        if (DXExtractInteger((dxObject)amode, &mode))
            _dxfSetInteractionMode(globals, mode, attr);
        else
            DXErrorGoto(ERROR_DATA_INVALID,
                        "interaction mode attribute must be an integer");
    } else
        _dxfSetInteractionMode(globals, 11, NULL);

    if(cacheObject) {
        /* delete the working reference  */
        DXDelete((Pointer)cacheObject) ;
        cacheObject = NULL;
    }

    if (cacheId)
        tdmFree(cacheId);
    if (pFormat)
        _dxfDeleteParsedDisplayString(pFormat);

    EXIT(("OK"));
    DEBUG_MARKER("_dxfAsyncRender EXIT");
    return OK ;

error:

    if(cacheObject) {
        /* delete the working reference  */
        DXDelete((Pointer)cacheObject) ;
        cacheObject = NULL;
    }

    if (cacheId)
        tdmFree(cacheId);
    if (pFormat)
        _dxfDeleteParsedDisplayString(pFormat);

    EXIT(("ERROR"));
    DEBUG_MARKER("_dxfAsyncRender EXIT");
    return ERROR ;
}
コード例 #9
0
ファイル: outglue.c プロジェクト: BackupTheBerlios/opendx2
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;
}
コード例 #10
0
ファイル: outglue.c プロジェクト: BackupTheBerlios/opendx2
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;
}