home *** CD-ROM | disk | FTP | other *** search
- /* Next available MSG number is 21 */
-
- /***************************************************************************
- Module Name: dragger.c
-
- Description:Another Sample ADS application
-
- Author :
- Autodesk, Inc.
- 2320 Marinship Way
- Sausalito, CA. 94965
- (415)332-2344
-
- ¬⌐┼v (C) 1990-1992 Autodesk ñ╜Ñq
-
- Ñ╗│n┼ΘºK╢O¿╤▒z╢iªµÑ⌠ª≤Ñ╬│~╗▌¿D¬║½■¿⌐íB¡╫º∩ñ╬╡oªµ, ª²¼O░╚╜╨┐φ┤`ñU¡z
- ¡∞½h :
-
- 1) ñWªC¬║¬⌐┼v│qºi░╚╗▌ÑX▓{ªb¿Cñ@Ñ≈½■¿⌐∙╪íC
- 2) ¼█├÷¬║╗í⌐·ñσÑ≤ñ]Ñ▓╢╖⌐·╕ⁿ¬⌐┼v│qºiñ╬Ñ╗╢╡│\Ñi│qºiíC
-
- Ñ╗│n┼Θ╢╚┤ú¿╤º@¼░└│Ñ╬ñW¬║░╤ª╥, ª╙Ñ╝┴n⌐·⌐╬┴⌠ºtÑ⌠ª≤½O├╥; ╣∩⌐≤Ñ⌠ª≤»S«φ
- Ñ╬│~ñº╛A║┘⌐╩, ÑHñ╬░╙╖~╛P░Γ⌐╥┴⌠ºtÑX¿π¬║½O├╥, ªbª╣ñ@╖ºñ⌐ÑHº_╗{íC
-
-
-
- Function Entry Points:
- void
- main(argc, argv)
- int argc; [Number of argument passed in cmd line]
- char *argv[]; [Array of pointers to arguments]
-
- Exported ADS Functions
- TESTDRAGGEN [Test the ADS_DRAGGEN function]
-
- Modification History:
- Feb 11 1992 - bcm - original creation
-
- Notes and restrictions on use:
-
-
- ***************************************************************************/
-
- /**************************************************************************/
- /* MODULE NAME */
- /**************************************************************************/
- #define DRAGGER
-
- /****************************************************************************/
- /* DEFINES */
- /****************************************************************************/
- #define ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
-
- /**************************************************************************/
- /* TYPEDEFS */
- /**************************************************************************/
- /* ADS Function Table */
- typedef struct {
- char *name;
- int (*fptr)();
- } ftblent;
-
- typedef struct resbuf rbtype;
-
- /**************************************************************************/
- /* INCLUDES */
- /**************************************************************************/
-
- #include <stdio.h>
- #include <math.h>
- #include <memory.h>
- #include "adslib.h"
- #include "ol_errno.h"
-
- /****************************************************************************/
- /* LOCAL FUNCTION FORWARD DECLARATIONS */
- /****************************************************************************/
- int testdraggen();
- int dragsampler _((ads_point pt, ads_matrix mat));
-
-
- /**************************************************************************/
- /* GLOBAL VARIABLES */
- /**************************************************************************/
- /* Table of ADS functions */
- ftblent exfun[] = {
- {/*MSG0*/"C:TESTDRAGGEN", testdraggen},
- };
-
- /* Table of keyword functions */
- char *kwtab[] = {
- /*MSG0*/"MXYZ",
- /*MSG0*/"SXYZ",
- /*MSG0*/"RX",
- /*MSG0*/"RY",
- /*MSG0*/"RZ",
- /*MSG0*/"NOP",
- /*MSG0*/"EXIT",
- };
-
- #define MXYZ 0
- #define SXYZ 1
- #define RX 2
- #define RY 3
- #define RZ 4
- #define NOP 5
- #define EXIT 6
-
- int KwIndex = NOP; /* Index into kwtab */
- ads_point Base; /* Base point for xform */
-
- ads_matrix CTM; /* Current Transformation Matrix */
- /**************************************************************************/
- /* EXTERNAL FUNCTION DECLARATIONS */
- /**************************************************************************/
- extern char *strcat();
- extern int strcmp();
-
- /**************************************************************************/
- /* EXTERNAL VARIABLE DECLARATIONS */
- /**************************************************************************/
-
- /****************************************************************************/
- /* LOCAL FUNCTION DECLARATIONS */
- /****************************************************************************/
-
- /******************************************************************************/
- /*.doc geterrno(internal) */
- /*+
- This function is called to obtain the value of the AutoCAD system
- variable ERRNO and return it as a result.
- -*/
- /******************************************************************************/
- int
- /*FCN*/geterrno()
- {
- rbtype errval;
-
- ads_getvar(/*MSG0*/"ERRNO", &errval);
-
- return errval.resval.rint;
- }
-
- /******************************************************************************/
- /*.doc funcload(internal) */
- /*+
- This function is called to define all function names in the ADS
- function table. Each named function will be callable from lisp or
- invokable from another ADS application.
- -*/
- /******************************************************************************/
- int
- /*FCN*/funcload()
- {
- int i;
-
- for (i = 0; i < ELEMENTS(exfun); i++) {
- if (!ads_defun(exfun[i].name, i))
- return RTERROR;
- }
-
- return RTNORM;
- }
-
- /******************************************************************************/
- /*.doc funclunoad(internal) */
- /*+
- This function is called to undefine all function names in the ADS
- function table. Each named function will be removed from the
- AutoLISP hash table.
- -*/
- /******************************************************************************/
- int
- /*FCN*/funcunload()
- {
- int i;
-
- /* Undefine each function we defined */
-
- for (i = 0; i < ELEMENTS(exfun); i++) {
- ads_undef(exfun[i].name,i);
- }
-
- return RTNORM;
- }
- /******************************************************************************/
- /*.doc dofun(internal) */
- /*+
- This function is called to invoke the function which has the
- registerd function code that is obtained from ads_getfuncode. The
- function will return RTERROR if the function code is invalid, or
- RSERR if the invoked function fails to return RTNORM. The value
- RSRSLT will be returned if the function code is valid and the
- invoked subroutine returns RTNORM.
- -*/
- /******************************************************************************/
- int
- /*FCN*/dofun()
- {
- int val;
-
- if ((val = ads_getfuncode()) < 0 || val > ELEMENTS(exfun))
- return RTERROR;
-
- return ((*exfun[val].fptr)() == RTNORM ? RSRSLT:RSERR);
- }
-
- /******************************************************************************/
- /*.doc main(internal) */
- /*+
- This is the main entry point for the ADS application. All ADS
- requests will be dispatched from this function. This is your
- standard ADS dispatch loop.
- -*/
- /******************************************************************************/
- void
- /*FCN*/main(argc,argv)
- int argc;
- char *argv[];
- {
- short scode = RSRSLT; /* Normal result code (default) */
- int stat;
-
- ads_init(argc, argv); /* Initiate communication with AutoLISP */
-
- for ( ;; ) { /* Request/Result loop */
-
- if ((stat = ads_link(scode)) < 0) {
- printf(/*MSG1*/"DRAGGER: Ñ╤ ads_link() ╢╟ª^¬║ñú¿╬¬¼║A = %d\n", stat);
- fflush(stdout);
- exit(1);
- }
-
- scode = RSRSLT; /* Reset result code */
-
- switch (stat) {
-
- case RQXLOAD: /* Load & define functions */
- scode = funcload() ? -RSRSLT : -RSERR;
- break;
-
- case RQXUNLD: /* Unload functions */
- scode = funcunload() ? -RSRSLT : -RSERR;
- ads_printf(/*MSG2*/"─└⌐±íC\n");
- break;
-
- case RQSUBR: /* Handle request for external function */
- dofun();
- break;
-
- default:
- break;
- }
- }
- }
-
- /******************************************************************************/
- /*.doc ads_mat_ident(internal) */
- /*+
- Set up an identity matrix.
- -*/
- /******************************************************************************/
- void
- /*FCN*/ads_mat_ident(matrix)
- ads_matrix matrix;
- {
- extern ads_matrix ads_identmat;
- memcpy(matrix, ads_identmat, sizeof(ads_matrix));
- }
-
- /******************************************************************************/
- /*.doc ads_subvec(internal) */
- /*+
- Subtract two ads_points.
- -*/
- /******************************************************************************/
- void
- /*FCN*/ads_subvec(ap, bp, dp)
- ads_point ap, bp;
- ads_point dp;
- {
- dp[X] = ap[X] - bp[X];
- dp[Y] = ap[Y] - bp[Y];
- dp[Z] = ap[Z] - bp[Z];
- }
-
-
- /******************************************************************************/
- /*.doc ads_fabsv(internal) */
- /*+
- Get normal of a vector.
- -*/
- /******************************************************************************/
- ads_real
- /*FCN*/ads_fabsv(ap)
- ads_point ap;
- {
- return sqrt(ap[X] * ap[X] + ap[Y] * ap[Y] + ap[Z] * ap[Z]);
- }
-
- /******************************************************************************/
- /*.doc ads_dist(internal) */
- /*+
- Calculate distance between two points.
- -*/
- /******************************************************************************/
- ads_real
- /*FCN*/ads_dist(p1, p2)
- ads_point p1, p2;
- {
- ads_point pd;
-
- ads_subvec(p1, p2, pd);
- return ads_fabsv(pd);
- }
-
-
- /******************************************************************************/
- /*.doc ads_mat_ixlate(internal) */
- /*+
- Set up a translation matrix.
- -*/
- /******************************************************************************/
- void
- /*FCN*/ads_mat_ixlate(vec, result)
- ads_point vec;
- ads_matrix result;
- {
- ads_mat_ident(result);
- result[X][T] = - vec[X];
- result[Y][T] = - vec[Y];
- result[Z][T] = - vec[Z];
- }
-
- /******************************************************************************/
- /*.doc ads_mat_rot(internal) */
- /*+
- Generate a matrix that rotates about a given axis.
- -*/
- /******************************************************************************/
- void
- /*FCN*/ads_mat_rot(angle, axis, m)
- ads_real angle;
- int axis;
- ads_matrix m;
- {
- int axp1, axp2;
-
- axp1 = (axis + 1) % 3;
- axp2 = (axis + 2) % 3;
- ads_mat_ident(m);
- m[axp1][axp1] = m[axp2][axp2] = cos(angle);
- m[axp1][axp2] = -(m[axp2][axp1] = sin(angle));
- }
-
- /******************************************************************************/
- /*.doc ads_mat_scale(internal) */
- /*+
- Generate a matrix that scales the 3 axes by given amounts.
- -*/
- /******************************************************************************/
- void
- /*FCN*/ads_mat_scale(xscale, yscale, zscale, m)
- ads_real xscale, yscale, zscale;
- ads_matrix m;
- {
- ads_mat_ident(m);
- m[X][X] = xscale;
- m[Y][Y] = yscale;
- m[Z][Z] = zscale;
- }
-
- /******************************************************************************/
- /*.doc ads_mat_x_pt(internal) */
- /*+
- Multiply matrix by a given point. Note that it does translation.
- -*/
- /******************************************************************************/
- void
- /*FCN*/ads_mat_x_pt(mat, pin, pout)
- ads_matrix mat;
- ads_point pin;
- ads_point pout;
- {
- int i;
- ads_point temp;
-
- for (i = X; i <= Z; i++)
- temp[i] = mat[i][X] * pin[X] +
- mat[i][Y] * pin[Y] +
- mat[i][Z] * pin[Z] +
- mat[i][T];
- memcpy(pout, temp, sizeof(ads_point));
- }
-
- /******************************************************************************/
- /*.doc ads_mat_x_vec(internal) */
- /*+
- Multiply matrix by a given vector. Note that it does NO translation.
- -*/
- /******************************************************************************/
- void
- /*FCN*/ads_mat_x_vec(mat, pin, pout)
- ads_matrix mat;
- ads_point pin;
- ads_point pout;
- {
- int i;
- ads_point temp;
-
- for (i = X; i <= Z; i++)
- temp[i] = mat[i][X] * pin[X] +
- mat[i][Y] * pin[Y] +
- mat[i][Z] * pin[Z];
- memcpy(pout, temp, sizeof(ads_point));
- }
-
- /******************************************************************************/
- /*.doc ads_mat_x_mat(internal) */
- /*+
- Multiply two matrices. Any or all arguments may point to the same array.
- -*/
- /******************************************************************************/
- void
- /*FCN*/ads_mat_x_mat(mata, matb, matout)
- ads_matrix mata;
- ads_matrix matb;
- ads_matrix matout;
- {
- ads_matrix t;
- int i, j, k;
- ads_real sum;
-
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++) {
- sum = 0.0;
- for (k=0; k<4; k++)
- sum += mata[i][k] * matb[k][j];
- t[i][j] = sum;
- }
- memcpy(matout, t, sizeof(ads_matrix));
- }
-
-
- /******************************************************************************/
- /*.doc dragsampler(internal) */
- /*+
- ADS_DRAGGEN sampler function. This function is called every time the
- digitizer is moved. It receives two arguments, the first is pt, and
- the second is mat. The argument pt is the current digitizer location,
- and the arguemnt mat is the transformation matrix which is being used
- by AutoCAD to display the current selection set of objects.
-
- The global KwIndex is an integer variable which contains a code
- representing the current drag mode. The possible values are MXYZ,
- SXYZ, RX, RY, RZ, NOP, and EXIT. This variable is set in the function
- testdraggen.
-
- The global CTM is set to the value of the argument mat before
- returning from the dragsampler. This variable is used by testdraggen
- when performing an ADS_XFORSS call.
- -*/
- /******************************************************************************/
- int
- /*FCN*/dragsampler(pt, mat)
- ads_point pt;
- ads_matrix mat;
- {
-
- ads_real D;
- ads_real angle;
- ads_point tp;
- int axis;
-
- switch(KwIndex) {
- case MXYZ:
- /* generate translation matrix */
- ads_subvec(pt, Base, tp);
- ads_mat_x_vec(mat, tp, tp);
- mat[X][T] = tp[X];
- mat[Y][T] = tp[Y];
- mat[Z][T] = tp[Z];
-
- break;
-
- case SXYZ:
- /* generate uniformly scaled matrix */
- D = ads_dist(pt, Base);
- if (D < .0001)
- D = .0001;
- ads_mat_scale(D,D, D, mat);
-
- /* calculate new translation point */
- ads_mat_x_vec(mat, Base, tp);
- ads_subvec(Base, tp, tp);
- mat[X][T] = tp[X];
- mat[Y][T] = tp[Y];
- mat[Z][T] = tp[Z];
-
- break;
-
- case RX:
- case RY:
- case RZ:
- switch (KwIndex) {
- case RX:
- axis = X;
- break;
- case RY:
- axis = Y;
- break;
- case RZ:
- axis = Z;
- break;
- }
-
-
- /* calculate angle of line between LastPoint and tp */
- ads_subvec(pt, Base, tp);
- angle = ads_angle(Base, pt);
-
- /* generate rotation matrix about axis */
- ads_mat_rot(angle, axis, mat);
-
- /* calculate new translation point */
- ads_mat_x_vec(mat, Base, tp);
- ads_subvec(Base, tp, tp);
- mat[X][T] = tp[X];
- mat[Y][T] = tp[Y];
- mat[Z][T] = tp[Z];
-
- break;
- case EXIT:
- return RTCAN;
- case NOP:
- default:
- return RTNONE;
- }
-
- memcpy(CTM, mat, sizeof(ads_matrix));
- return RTNORM;
- }
-
- /******************************************************************************/
- /*.doc testdraggen(internal) */
- /*+
- This function is called from dofun as a result of an RQSUBR
- request being sent to the main dispatch loop.
-
- It instructs the user to select the set of entitis that will be
- dragged by the ads_draggen function. The selection is obtained by
- performing an ads_ssget Crossing. If a selection set contains one
- or more entities, then the user will be instructed to move the
- mouse for dragging the object(s), or enter a keyword to modify the
- behavior of the dragging operation.
-
- The list of keywords is obtained from the keytable, and each
- keyword in the table has a different affect on the sampler function.
- The sampler will perform the transformation indicated by the value of
- KwIndex.
-
- Once a valid point has been selected, this test function will
- attempt to transform the selection set of entities in the database.
- The transformation will not work if the transformation matrix
- contains a non uniform scale.
-
- The return value for this function is the last value in rc.
- -*/
- /******************************************************************************/
- int
- /*FCN*/testdraggen()
- {
- int x;
- int rc;
- long slen;
- ads_point pt1;
- ads_point pt2;
- ads_point pt3;
- ads_name ssname;
- rbtype *args;
- char tstr[512];
- char kwlist[128];
- char draggenprompt[512];
- int cur;
-
- args = ads_getargs();
- ads_mat_ident(CTM);
- cur = 0;
- /* Build the key word list from the key word table */
- kwlist[0] = '\0';
- for (x = 0; x < ELEMENTS(kwtab); x++) {
- if (x != 0)
- strcat(kwlist, /*MSG0*/" ");
- strcat(kwlist, kwtab[x]);
- }
-
- /* Select entities for DRAGGEN test */
- ads_printf(/*MSG3*/"\n░⌡ªµíuads_draggenív┤·╕╒\n");
- if (args != NULL) {
- ads_printf(/*MSG4*/"ñú╗▌¡níuñ▐╝╞ívíC\n");
- ads_retlist(args);
- }
- KwIndex = NOP;
- ads_printf(/*MSG5*/"┐∩╛▄╣w│╞⌐∞ñ▐¬║¬½┼Θ\n");
- if (ads_getpoint(NULL, /*MSG6*/"\n▓─ñ@¿ñ┬I:", pt1) == RTNORM) {
- if (ads_getcorner(pt1, /*MSG7*/"\nÑtñ@¿ñ┬I:", pt2) == RTNORM) {
- ads_ssget(/*MSG0*/"C", pt1, pt2, NULL, ssname);
- rc = ads_sslength(ssname, &slen);
- if (rc != RTNORM || slen == 0L)
- return RTNORM;
- ads_getpoint(NULL, /*MSG8*/"\n░≥╖╟┬I", Base);
- sprintf(draggenprompt, /*MSG9*/"\n▓╛░╩íu╖╞╣½ív⌐╬┐ΘñJ :(%s)", kwlist);
- do {
- ads_initget(RSG_NONULL|RSG_OTHER, kwlist);
- rc = ads_draggen(ssname,
- draggenprompt,
- cur,
- dragsampler,
- pt3);
- switch (rc) {
- case RTKWORD:
- ads_getinput(tstr);
- rc = RTNORM;
- for (x = 0; x < ELEMENTS(kwtab); x++) {
- if (strcmp(tstr, kwtab[x]) == 0) {
- KwIndex = x;
- ads_mat_ident(CTM);
- break;
- }
- }
- if (x >= ELEMENTS(kwtab))
- ads_printf(/*MSG10*/"\níu%sív¼░╡L«─¬║íu├÷┴ΣªrívíC", tstr);
- break;
- case RTSTR:
- ads_getinput(tstr);
- rc = RTNORM;
- ads_printf(/*MSG11*/"Ñ╬ñß┐ΘñJ :%s\n", tstr);
- break;
- case RTNORM:
- rc = ads_xformss(ssname, CTM);
- if (rc != RTNORM)
- switch(geterrno()) {
- case OL_ESSVALID:
- ads_printf(/*MSG12*/"\n┐∩╢░╡L«─íC\n");
- break;
- case OL_EDELENT:
- ads_printf(/*MSG13*/"\níu┐∩╢░ívºtª│ñwíuºR░úív¬║╣╧ñ╕íC\n");
- break;
- case OL_EMODSEQ:
- ads_printf(/*MSG14*/"\n╡L¬k┬α╕míuSEQENDív╣╧ñ╕íC\n");
- break;
- case OL_ERGBUSY:
- ads_printf(/*MSG15*/"\n╢iªµ╜╞┬°¬║íu¡½Ñ═ívíC\n");
- break;
- case OL_EMMVPORT:
- ads_printf(/*MSG16*/"\n╡L¬k┬α╕míu╡°╡íív╣╧ñ╕íC\n");
- break;
- case OL_EMMLL:
- ads_printf(/*MSG17*/"\n╡L¬k┬α╕míu┬Ω┼@╣╧╝hívñW¬║╣╧ñ╕íC\n");
- break;
- case OL_EXFMVALID:
- ads_printf(/*MSG18*/"\níu┬α╕m»x░}ív╡L«─íC\n");
- break;
- }
-
- ads_mat_x_pt(CTM, Base, Base);
- ads_mat_ident(CTM);
- break;
- case RTCAN:
- ads_printf(/*MSG19*/"\níu⌐∞ñ▐ívñwñññε\n");
- break;
- case RTERROR:
- default:
- ads_printf(/*MSG20*/"\níu⌐∞ñ▐ívº@╖~Ñó▒╤\n");
- break;
- }
- } while (rc == RTNORM);
- /* release the selection set */
- ads_ssfree(ssname);
- }
- }
-
-
- return RTNORM;
- }
-