home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / graphic / qrt / instance.c < prev    next >
C/C++ Source or Header  |  1989-03-26  |  5KB  |  241 lines

  1.  
  2. /**********************************************************
  3.  
  4.     Routines for user-defined primitives (INSTANCE_OF)
  5.  
  6.  **********************************************************/
  7.  
  8. #include "qrt.h"
  9.  
  10. float Get_Next_Num(), IsPos();
  11. char  *Get_Next_Name();
  12.  
  13. /* #define INSTANCEDEBUG TRUE */
  14.  
  15.  
  16. /**********************************************************
  17.  
  18.      Returns a pointer to the object in the object
  19.      tree with the given name.
  20.  
  21.  **********************************************************/
  22.  
  23.  
  24. OBJ_PTR Name_Find(obj,name)
  25.   OBJ_PTR obj;
  26.   char *name;
  27. {
  28.   OBJ_PTR temp;
  29.  
  30.   if (obj==NULL) return(NULL);
  31.  
  32.   if (obj->name!=NULL)
  33.     if (strcmp(name,obj->name)==0) return(obj);
  34.  
  35.   if (obj->child != NULL)
  36.     if ((temp=Name_Find(obj->child,name))!=NULL)
  37.       return(temp);
  38.  
  39.   if (obj->nextobj != NULL)
  40.     if ((temp=Name_Find(obj->nextobj,name))!=NULL)
  41.       return(temp);
  42.  
  43.   return(NULL);
  44. }
  45.  
  46.  
  47. /**********************************************************
  48.  
  49.     Copies a given sub-tree and returns a pointer to
  50.     the copy.    Always pass fflag=TRUE
  51.  
  52.  **********************************************************/
  53.  
  54. OBJ_PTR Subtree_Copy(obj, fflag)
  55.   OBJ_PTR obj;
  56.   int fflag;
  57. {
  58.   OBJ_PTR newobj, new_obj();
  59.  
  60.   if (obj==NULL) return(NULL);
  61.  
  62. # ifdef INSTANCEDEBUG
  63.     printf("SUBTREECOPY: name = %s\n",obj->name);
  64. # endif
  65.  
  66.   newobj = new_obj( obj->type,         /* make new obj */
  67.                     &(obj->loc),
  68.                     &(obj->vect1),
  69.                     &(obj->vect2),
  70.                     &(obj->vect3),
  71.                     &(obj->cinfo),
  72.                     obj->pattern,
  73.                     obj->remove,
  74.                     NULL,              /* no name here */
  75.                     &(obj->upper),
  76.                     &(obj->lower),
  77.                     obj->cterm,
  78.                     obj->xmult,
  79.                     obj->ymult );
  80.  
  81.   newobj->child   = Subtree_Copy(obj->child,FALSE);
  82.  
  83.   if (!fflag)
  84.     newobj->nextobj = Subtree_Copy(obj->nextobj,FALSE);
  85.   else
  86.     newobj->nextobj = NULL;
  87.  
  88.   return(newobj);
  89. }
  90.  
  91. /**********************************************************
  92.  
  93.           Offsets sub-tree by offset distance units
  94.           ALWAYS pass fflag = TRUE
  95.  
  96.  **********************************************************/
  97.  
  98. Subtree_Offset(obj,offset,fflag)
  99.   OBJ_PTR obj;
  100.   VECT_PTR offset;
  101.   int fflag;
  102. {
  103.   if (obj==NULL) return;
  104.  
  105. # ifdef INSTANCEDEBUG
  106.     printf("SUBTREEOFFSET: type = %d offset = %f %f %f\n",
  107.            obj->type,
  108.            offset->x,
  109.            offset->y,
  110.            offset->z);
  111. # endif
  112.  
  113.   (*(ObjData[obj->type].Offset))(obj,offset);
  114.  
  115.   Subtree_Offset(obj->child,offset,FALSE);
  116.  
  117.   if (!fflag)
  118.     Subtree_Offset(obj->nextobj,offset,FALSE);
  119. }
  120.  
  121. /**********************************************************
  122.  
  123.           Scales a sub-tree by mult distance units
  124.           ALWAYS pass fflag = TRUE
  125.  
  126.  **********************************************************/
  127.  
  128. Subtree_Scale(obj,mult,fflag)
  129.   OBJ_PTR obj;
  130.   VECT_PTR mult;
  131.   int fflag;
  132. {
  133.   if (obj==NULL) return;
  134.  
  135. # ifdef INSTANCEDEBUG
  136.     printf("SUBTREESCALE: type = %d mult = %f %f %f\n",
  137.            obj->type,
  138.            mult->x,
  139.            mult->y,
  140.            mult->z);
  141. # endif
  142.  
  143.   (*(ObjData[obj->type].Resize))(obj,mult);
  144.  
  145.   Subtree_Scale(obj->child,mult,FALSE);
  146.  
  147.   if (!fflag)
  148.     Subtree_Scale(obj->nextobj,mult,FALSE);
  149. }
  150.  
  151. /**********************************************************
  152.  
  153.   Load an "Instance_of" structure.  This really makes a
  154.   copy of another part of the tree, offsets it, and returns
  155.   a pointer to this copy.  All "name" fields for the copy
  156.   are set to null to avoid duplicate names.  Also, a new
  157.   scale factor can be specified (default 1).
  158.  
  159.  **********************************************************/
  160.  
  161. OBJ_PTR Get_Instance_Of()
  162. {
  163.   char str[SLEN], *name;
  164.   int end, f, found;
  165.   VECTOR offset, mult;
  166.   OBJ_PTR source, dest;
  167.  
  168.   end=f=0;
  169.   mult.x = mult.y = mult.z = 1.00;
  170.  
  171.   GetLeftParen();
  172.  
  173.   while (!end && !feof(stdin)) {
  174.     GetToken(str);
  175.  
  176.     found = FALSE;
  177.     if (strcmp(str,"NAME")==0) {
  178.       name = Get_Next_Name();
  179.       f|=1; found = TRUE;
  180.     }
  181.  
  182.     if ((strcmp(str,"POS")==0)      ||
  183.         (strcmp(str,"LOC")==0)      ||
  184.         (strcmp(str,"POSITION")==0) ||
  185.         (strcmp(str,"LOCATION")==0)) {
  186.  
  187.       GetVector(&offset);
  188.       f|=2; found = TRUE;
  189.     }
  190.  
  191.     if (strcmp(str,"SCALE")==0) {
  192.       GetVector(&mult);
  193.       found = TRUE;
  194.     }
  195.  
  196.     if (strcmp(str,")")==0) { end=1; found = TRUE; }
  197.  
  198.     if (!found) Error(UNDEFINED_PARAM,1203);
  199.  
  200.   }
  201.  
  202.   if (f!=3) Error(TOO_FEW_PARMS,1204);
  203.  
  204. # ifdef INSTANCEDEBUG
  205.     printf("GET_INSTANCE: offset = %f %f %f\n",
  206.            offset.x,
  207.            offset.y,
  208.            offset.z);
  209. # endif
  210.  
  211.   if ((source = Name_Find(THEWORLD.instances,name))==NULL)
  212.     Error(UNDEFINED_NAME,1205);
  213.  
  214.   if ((dest = Subtree_Copy(source,TRUE))==NULL)
  215.     Error(INTERNAL_ERROR,1206);
  216.  
  217.   /* scale the subtree */
  218.  
  219. # ifdef INSTANCEDEBUG
  220.     printf("scaling...\n");
  221. # endif
  222.  
  223.   Subtree_Scale(dest,&mult,TRUE);
  224.  
  225. # ifdef INSTANCEDEBUG
  226.     printf("Offsetting...\n");
  227. # endif
  228.  
  229.   /* move the subtree */
  230.  
  231.   Subtree_Offset(dest,&offset,TRUE);
  232.  
  233. # ifdef INSTANCEDEBUG
  234.     printf("returning\n");
  235. # endif
  236.  
  237.   return(dest);
  238. }
  239.  
  240.  
  241.