Exemple #1
0
static Error atleast1image(Object o)
{
    Object subo, old;
    int i;

    switch (DXGetObjectClass(o)) {
      case CLASS_FIELD:
	if (qimage(o))
	    return OK;
	break;

      case CLASS_GROUP:
	/* traverse members */
	for (i=0; subo = DXGetEnumeratedMember((Group)o, i, NULL); i++)
	    if (atleast1image(subo))
		return OK;
	break;
    
      case CLASS_SCREEN:
	if (!DXGetScreenInfo((Screen)o, &subo, NULL, NULL))
	    return ERROR;

	return atleast1image(subo);

      case CLASS_XFORM:
	if (!DXGetXformInfo((Xform)o, &subo, NULL))
	    return ERROR;

	return atleast1image(subo);

      case CLASS_CLIPPED:
	if (!DXGetClippedInfo((Clipped)o, &subo, NULL))
	    return ERROR;

	return atleast1image(subo);

      default:
	break;
    }

    return ERROR;
}
Exemple #2
0
static Error atleast1contype(Object o, int n)
{
    Object subo, old;
    int i;

    switch (DXGetObjectClass(o)) {
      case CLASS_FIELD:
	if (queryNDconnections((Field)o, n))
	    return OK;
	break;

      case CLASS_GROUP:
	/* traverse members */
	for (i=0; subo = DXGetEnumeratedMember((Group)o, i, NULL); i++)
	    if (atleast1contype(subo, n))
		return OK;
	break;
    
      case CLASS_SCREEN:
	/* these don't act like other objs;  don't count them for this */
	break;

      case CLASS_XFORM:
	if (!DXGetXformInfo((Xform)o, &subo, NULL))
	    return ERROR;

	return atleast1contype(subo, n);

      case CLASS_CLIPPED:
	if (!DXGetClippedInfo((Clipped)o, &subo, NULL))
	    return ERROR;

	return atleast1contype(subo, n);

      default:
	break;
    }

    return ERROR;
}
Exemple #3
0
static int qimage(Object o)
{
    int n;
    Array a;
    char *s;
    
    /* an image has got to be a field or a composite field */
    if (DXGetObjectClass(o) != CLASS_FIELD) {
	if (DXGetObjectClass(o) != CLASS_GROUP)
	    return 0;
	if (DXGetGroupClass((Group)o) != CLASS_COMPOSITEFIELD)
	    return 0;
	o = DXGetEnumeratedMember((Group)o, 0, NULL);
    }

    /* check to see if it's the right shape, etc */

    /* check positions */
    a = (Array) DXGetComponentValue((Field)o, "positions");
    if (!a || !DXQueryGridPositions(a, &n, NULL, NULL, NULL) || n!=2)
	return 0;
    
    /* check connections */
    a = (Array) DXGetComponentValue((Field)o, "connections");
    if (!a || !DXQueryGridConnections(a, &n, NULL) || n!=2)
	return 0;

    /* is there a colors component */
    a = (Array) DXGetComponentValue((Field)o, "colors");
    if (!a)
	return 0;

    /* check dep */
    s = DXGetString((String)DXGetAttribute((Object)a, "dep"));
    if (s && strcmp(s, "positions"))
	return 0;
    
    return 1;
}
Exemple #4
0
static Error
traverse(Object *in, Object *out)
{
  switch(DXGetObjectClass(in[0]))
  {
    case CLASS_FIELD:
/*     case CLASS_ARRAY: */
      if (! doLeaf(in, out))
  	     return ERROR;

      return OK;

#if 0
    case CLASS_GROUP:
    {
      int   i, j;
      int   memknt;
      Class groupClass  = DXGetGroupClass((Group)in[0]);

      DXGetMemberCount((Group)in[0], &memknt);

        for (i = 0; i < memknt; i++)
        {
          Object new_in[4], new_out[1];

          if (in[0])
            new_in[0] = DXGetEnumeratedMember((Group)in[0], i, NULL);
          else
            new_in[0] = NULL;

          new_in[1] = in[1];
          new_in[2] = in[2];
          new_in[3] = in[3];

          new_out[0] = DXGetEnumeratedMember((Group)out[0], i, NULL);

          if (! traverse(new_in, new_out))
            return ERROR;

          DXSetEnumeratedMember((Group)out[0], i, new_out[0]);

        }
      return OK;
    }

    case CLASS_XFORM:
    {
      int    i, j;
      Object new_in[4], new_out[1];

      if (in[0])
        DXGetXformInfo((Xform)in[0], &new_in[0], NULL);
      else
        new_in[0] = NULL;

      new_in[1] = in[1];
      new_in[2] = in[2];
      new_in[3] = in[3];

      DXGetXformInfo((Xform)out[0], &new_out[0], NULL);

      if (! traverse(new_in, new_out))
        return ERROR;

      DXSetXformObject((Xform)out[0], new_out[0]);

      return OK;
    }

    case CLASS_SCREEN:
    {
       int    i, j;
       Object new_in[4], new_out[1];

       if (in[0])
         DXGetScreenInfo((Screen)in[0], &new_in[0], NULL, NULL);
       else
         new_in[0] = NULL;

       new_in[1] = in[1];
       new_in[2] = in[2];
       new_in[3] = in[3];

       DXGetScreenInfo((Screen)out[0], &new_out[0], NULL, NULL);

       if (! traverse(new_in, new_out))
         return ERROR;

       DXSetScreenObject((Screen)out[0], new_out[0]);

       return OK;
     }

     case CLASS_CLIPPED:
     {
       int    i, j;
       Object new_in[4], new_out[1];


       if (in[0])
         DXGetClippedInfo((Clipped)in[0], &new_in[0], NULL);
       else
         new_in[0] = NULL;

       new_in[1] = in[1];
       new_in[2] = in[2];
       new_in[3] = in[3];

       DXGetClippedInfo((Clipped)out[0], &new_out[0], NULL);

       if (! traverse(new_in, new_out))
         return ERROR;

       DXSetClippedObjects((Clipped)out[0], new_out[0], NULL);

       return OK;
     }
#endif

     default:
     {
       DXSetError(ERROR_BAD_CLASS, "input must be Field");
       return ERROR;
     }
  }
}
Exemple #5
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 );

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

    if (!sdata)
	return;

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

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

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

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

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

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

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

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

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

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

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

		    DXGetXformInfo(oldx, &xchild, &oldm);

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

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


		    DXGetXformInfo(oldx, &xchild, &oldm);

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


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

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

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

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


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

    return;

}
Exemple #7
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; 
    
  }
Exemple #8
0
static Error
traverse(Object *in, Object *out)
{
    switch(DXGetObjectClass(in[0]))
    {
    case CLASS_FIELD:
    case CLASS_ARRAY:
        /*
         * If we have made it to the leaf level, call the leaf handler.
         */
        if (! doLeaf(in, out))
            return ERROR;

        return OK;

    case CLASS_GROUP:
    {
        int   i, j;
        int   memknt;
        Class groupClass  = DXGetGroupClass((Group)in[0]);

        DXGetMemberCount((Group)in[0], &memknt);


        /*
         * Create new in and out lists for each child
         * of the first input.
         */
        for (i = 0; i < memknt; i++)
        {
            Object new_in[2], new_out[1];

            /*
             * For all inputs that are Values, pass them to
             * child object list.  For all that are Field/Group, get
             * the appropriate decendent and place it into the
             * child input object list.
             */

            /* input "input" is Field/Group */
            if (in[0])
                new_in[0] = DXGetEnumeratedMember((Group)in[0], i, NULL);
            else
                new_in[0] = NULL;

            /* input "size" is Value */
            new_in[1] = in[1];

            /*
             * For all outputs that are Values, pass them to
             * child object list.  For all that are Field/Group,  get
             * the appropriate decendent and place it into the
             * child output object list.  Note that none should
             * be NULL (unlike inputs, which can default).
             */

            /* output "output" is Field/Group */
            new_out[0] = DXGetEnumeratedMember((Group)out[0], i, NULL);

            if (! traverse(new_in, new_out))
                return ERROR;

            /*
             * Now for each output that is not a Value, replace
             * the updated child into the object in the parent.
             */

            /* output "output" is Field/Group */
            DXSetEnumeratedMember((Group)out[0], i, new_out[0]);

        }
        return OK;
    }

    case CLASS_XFORM:
    {
        int    i, j;
        Object new_in[2], new_out[1];


        /*
         * Create new in and out lists for the decendent of the
         * first input.  For inputs and outputs that are Values
         * copy them into the new in and out lists.  Otherwise
         * get the corresponding decendents.
         */

        /* input "input" is Field/Group */
        if (in[0])
            DXGetXformInfo((Xform)in[0], &new_in[0], NULL);
        else
            new_in[0] = NULL;

        /* input "size" is Value */
        new_in[1] = in[1];

        /*
         * For all outputs that are Values, copy them to
         * child object list.  For all that are Field/Group,  get
         * the appropriate decendent and place it into the
         * child output object list.  Note that none should
         * be NULL (unlike inputs, which can default).
         */

        /* output "output" is Field/Group */
        DXGetXformInfo((Xform)out[0], &new_out[0], NULL);

        if (! traverse(new_in, new_out))
            return ERROR;

        /*
         * Now for each output that is not a Value replace
         * the updated child into the object in the parent.
         */

        /* output "output" is Field/Group */
        DXSetXformObject((Xform)out[0], new_out[0]);

        return OK;
    }

    case CLASS_SCREEN:
    {
        int    i, j;
        Object new_in[2], new_out[1];


        /*
         * Create new in and out lists for the decendent of the
         * first input.  For inputs and outputs that are Values
         * copy them into the new in and out lists.  Otherwise
         * get the corresponding decendents.
         */

        /* input "input" is Field/Group */
        if (in[0])
            DXGetScreenInfo((Screen)in[0], &new_in[0], NULL, NULL);
        else
            new_in[0] = NULL;

        /* input "size" is Value */
        new_in[1] = in[1];


        /*
         * For all outputs that are Values, copy them to
         * child object list.  For all that are Field/Group,  get
         * the appropriate decendent and place it into the
         * child output object list.  Note that none should
         * be NULL (unlike inputs, which can default).
         */

        /* output "output" is Field/Group */
        DXGetScreenInfo((Screen)out[0], &new_out[0], NULL, NULL);

        if (! traverse(new_in, new_out))
            return ERROR;

        /*
         * Now for each output that is not a Value, replace
         * the updated child into the object in the parent.
         */

        /* output "output" is Field/Group */
        DXSetScreenObject((Screen)out[0], new_out[0]);

        return OK;
    }

    case CLASS_CLIPPED:
    {
        int    i, j;
        Object new_in[2], new_out[1];


        /* input "input" is Field/Group */
        if (in[0])
            DXGetClippedInfo((Clipped)in[0], &new_in[0], NULL);
        else
            new_in[0] = NULL;

        /* input "size" is Value */
        new_in[1] = in[1];


        /*
         * For all outputs that are Values, copy them to
         * child object list.  For all that are Field/Group,  get
         * the appropriate decendent and place it into the
         * child output object list.  Note that none should
         * be NULL (unlike inputs, which can default).
         */

        /* output "output" is Field/Group */
        DXGetClippedInfo((Clipped)out[0], &new_out[0], NULL);

        if (! traverse(new_in, new_out))
            return ERROR;

        /*
         * Now for each output that is not a Value, replace
         * the updated child into the object in the parent.
         */

        /* output "output" is Field/Group */
        DXSetClippedObjects((Clipped)out[0], new_out[0], NULL);

        return OK;
    }

    default:
    {
        DXSetError(ERROR_BAD_CLASS, "encountered in object traversal");
        return ERROR;
    }
    }
}
Exemple #9
0
/* print something about each member, up to MEMBERCOUNT items */
static Error saymembers(Group g)
{
    int i, count;
    char *name;
    Object subo, firstsubo;
    int same;
    Class grouptype;
    float position;
    
    
    if (!DXGetMemberCount(g, &count))
	return ERROR;
    
    /* no members, nothing to do here */
    if (count <= 0)
	return OK;

    /* save group type; we'll use it later on */
    grouptype = DXGetGroupClass(g);
    switch (grouptype) {
	
      case CLASS_GROUP:
	if (count <= MEMBERCOUNT) {
	    for (i=0; i<count; i++) {
		if (!(subo = DXGetEnumeratedMember(g, i, &name)))
		    return ERROR;
		if (name)
		    DescribeMsg(" member %d is named %s\n", i, name);
	    }
	} else {
	    for (i=0; i<MEMBERCOUNT/2; i++) {
		if (!(subo = DXGetEnumeratedMember(g, i, &name)))
		    return ERROR;
		if (name)
		    DescribeMsg(" member %d is named %s\n", i, name);
	    }
	    DescribeMsg(" ...\n");
	    for (i=count-MEMBERCOUNT/2; i<count; i++) {
		if (!(subo = DXGetEnumeratedMember(g, i, &name)))
		    return ERROR;
		if (name)
		    DescribeMsg(" member %d is named %s\n", i, name);
	    }
	}
	break;
	
      case CLASS_COMPOSITEFIELD:
	break;
	
      case CLASS_MULTIGRID:
	/* bbox? */
	break;
	
      case CLASS_SERIES:
	if (count <= MEMBERCOUNT) {
	    for (i=0; i<count; i++) {
		if (!(subo = DXGetSeriesMember((Series)g, i, &position)))
		    return ERROR;
		DescribeMsg(" member %d is at position %g\n", i, position);
	    }
	} else {
	    for (i=0; i<MEMBERCOUNT/2; i++) {
		if (!(subo = DXGetSeriesMember((Series)g, i, &position)))
		    return ERROR;
		DescribeMsg(" member %d is at position %g\n", i, position);
	    }
	    DescribeMsg(" ...\n");
	    for (i=count-MEMBERCOUNT/2; i<count; i++) {
		if (!(subo = DXGetSeriesMember((Series)g, i, &position)))
		    return ERROR;
		DescribeMsg(" member %d is at position %g\n", i, position);
	    }
	    
	}
	break;
	
      default:
	break;
    }

    /* if only one member, say what it is and return */
    if (count <= 1) {
	subo = DXGetEnumeratedMember(g, 0, NULL);
	return sayclass(subo, "The member", 0);
    }
	
    /* if there is more than one member of this group, check out
     * whether the group members are all the same type of object.
     * this has to be true for a composite field and should be true
     * for a multigrid, and usually for a series.
     */
    same = 1;
    firstsubo = DXGetEnumeratedMember(g, 0, NULL);
    for (i=1; i<count; i++) {
	if (!(subo = DXGetEnumeratedMember(g, i, NULL)))
	    return ERROR;
	if (DXGetObjectClass(firstsubo) != DXGetObjectClass(subo)) {
	    same = 0;
	    break;
	}
    }
    
    switch (grouptype) {
      case CLASS_GROUP:
	if (same)
	    sayclass(firstsubo, "Each group member", 0);
	else 
	    DescribeMsg("The group contains members of different object types\n");
	break;
	
      case CLASS_COMPOSITEFIELD:
	if (!same || (DXGetObjectClass(firstsubo) != CLASS_FIELD)) {
	    DescribeMsg("This is not a well-formed Partitioned Field.\n");
	    DescribeMsg("Members should all be Field objects and they are not.\n");
	    if (!same) 
		DescribeMsg("It contains members of more than one object type.\n");
	    if ((DXGetObjectClass(firstsubo) != CLASS_FIELD))
		DescribeMsg("It contains members which are not Field objects.\n");
	}
	break;
	
      case CLASS_MULTIGRID:
	/* what about partitioned members? i think they are ok */
	break;
#if 0
	if (!same || (DXGetObjectClass(firstsubo) != CLASS_FIELD)) {
	    DescribeMsg("This is not a well-formed MultiGrid Group.\n");
	    DescribeMsg("Members should all be Field objects and they are not.\n");
	    if (!same) 
		DescribeMsg("It contains members of more than one object type.\n");
	    if ((DXGetObjectClass(firstsubo) != CLASS_FIELD))
		DescribeMsg("It contains members which are not Field objects.\n");
	}
	break;
#endif
	
      case CLASS_SERIES:
	if (same)
	    sayclass(firstsubo, "Each series member", 0);
	else 
	    DescribeMsg("The series contains members of different object types\n");
	break;
	
      default:
	break;
    }
    
    return OK;
}
Exemple #10
0
/* accumulate info about what's what
 */
static Error traverse(Object o, struct info *ip, int nosee)
{
    Object subo;
    Class curclass;
    int i;

    switch (curclass = DXGetObjectClass(o)) {
      case CLASS_FIELD:
	return validfield((Field)o, ip, nosee);
	
      case CLASS_GROUP:
	/* traverse members */
	for (i=0; (subo = DXGetEnumeratedMember((Group)o, i, NULL)); i++) {
	    if (!traverse(subo, ip, nosee))
		return ERROR;
	}
	break;
	
      case CLASS_SCREEN:
	if (!DXGetScreenInfo((Screen)o, &subo, NULL, NULL))
	    return ERROR;

	return traverse(subo, ip, 1);

      case CLASS_XFORM:
	if (!DXGetXformInfo((Xform)o, &subo, NULL))
	    return ERROR;

	return traverse(subo, ip, nosee);

      case CLASS_CLIPPED:
	if (!DXGetClippedInfo((Clipped)o, &subo, NULL))
	    return ERROR;

	return traverse(subo, ip, nosee);  /* is this right? */

      case CLASS_LIGHT:
	ip->ri.nlights++;
	break;
	
      case CLASS_INTERPOLATOR:
      case CLASS_MAX:
      case CLASS_MIN:
      case CLASS_PRIVATE:
      case CLASS_DELETED:
      case CLASS_STRING:
      case CLASS_ARRAY:
      case CLASS_CAMERA:	
      default:
	for (i=0; i<ip->ri.badobjs; i++) {
	    if (ip->ri.badclass[i] == curclass)
		return OK;
	}
	ip->ri.badobjs++;
	ip->ri.badclass = (Class *)DXReAllocate((Pointer)ip->ri.badclass, 
						sizeof(Class) * ip->ri.badobjs);
	ip->ri.badclass[ip->ri.badobjs - 1] = curclass;

	break;
    }

    return OK;
}
Exemple #11
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;
}
Exemple #12
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;
}