// This program, sample.c, is used to illustrate the basic // ingredients of an ADS program. A user can simply add additional // functions to the existing structure to form a new application. #include // Standard C include file #include // Standard C include file #include // Standard C include file #include // Interface to ADS library // Declare functions used in this file static int funcload (void) ; static int dofun (void) ; /* * The following functions can be used by an AutoCAD user. * You need to add your new ADS functions here. */ static int frame_func (void) ; static int polys_func (void) ; static int nut_func (void) ; static int squares_func (void) ; static int test3d_func (void) ; // Definition to get an array's element count (at compile time). #define ELEMENTS(array) (sizeof(array)/sizeof((array)[0])) /* * All user defined functions will be listed in a table, * These functions return an integer value (RTNORM or RTERROR * for good or bad status). * Defination on the structure of the table: * a string that gives the name of the function, * a pointer that leads to a function returning type int. */ struct func_entry { char *func_name; // Name of func as seen by an AutoCAD user int (*func)(void); // func takes no parameters, returns int }; /* * Here function names and handlers are listed in an array. * Add your new ADS functions to the list. */ static struct func_entry func_table[] = { {"C:polys", polys_func}, // User types "polys" {"C:nut", nut_func}, // User types "nut" {"C:frame", frame_func}, // User types "frame" {"C:squares", squares_func}, // User types "squares" {"C:test3d", test3d_func} // User types "test3d" }; //------------------------------------------------------------- // The Main Function //------------------------------------------------------------- void main (int argc, char* argv[]) { short scode = RSRSLT; // Normal result code (default) int stat; ads_init (argc,argv); // Open comms with AutoLISP // For-ever loop for ( ;; ) { // Request/Result loop if ((stat = ads_link(scode)) < 0) { printf ("\nERROR,stat=%d",stat) ; exit(1); // < 0 means error } scode = RSRSLT ; // Reset result code switch (stat) { case RQXLOAD: // Load & define functions scode = funcload() == RTNORM ? RSRSLT : RSERR; break; case RQSUBR: // Handle external function req scode = dofun() == RTNORM ? RSRSLT : RSERR; break; // See text to find out what to do with the // following when your program gets more // complicated. Ignore them in this simple program case RQXUNLD : case RQEND : case RQQUIT : break ; default: break; } } } //------------------------------------------------------------- static int funcload (void) /* PURPOSE: To tell ACAD the names of functions in the app. NOTES: 1) .func_name is what you have to type in at keyboard 2) This is called after EVERY DRAWING LOAD. */ { int i; for (i = 0; i < ELEMENTS(func_table); i++) { if (!ads_defun (func_table[i].func_name, (short)i)) { ads_printf ("\n***funcload failure***\n") ; return (RTERROR); } } return (RTNORM) ; } //------------------------------------------------------------- static int dofun (void) /* * PURPOSE: executes external func (called upon an RQSUBR * request). Return value from the function executed will be * RTNORM or RTERROR. */ { int Func_Code ; // Which function to call int Ret_Val ; // Return value of called function // Get the function code and check that it's in range. if ((Func_Code = ads_getfuncode()) < 0 || Func_Code >= ELEMENTS(func_table)) { ads_fail ("Received nonexistent function code."); return (RTERROR) ; } /* * This is where we actually call the function we have * added to AutoCAD, returning the result of the * function. */ Ret_Val = (*func_table[Func_Code].func)(); return (Ret_Val) ; } //=============================================================== // New ADS functions can be added after this line. //=============================================================== //--------------------------------------------------------------- // The ADS function for creating a series of nested polygons //--------------------------------------------------------------- const ads_real TWO_PI = 6.28 ; static int polys_func (void) { int Res,a ; int N_Sides,N_Polys,r ; ads_point Center,Start,End ; ads_real Radius,Angle ; ads_retvoid() ; // Tell AutoLISP no return value /* * Get all the data required to draw the polygons... */ Res = ads_getint ("\nEnter the number of the sides:",&N_Sides) ; if (Res != RTNORM) { return (RTNORM) ; } Res = ads_getint ("\nEnter the number of polygons:",&N_Polys) ; if (Res != RTNORM) { return (RTNORM) ; } Res = ads_getpoint (NULL,"\nSpecify the center(e.g.8,9):",Center) ; if (Res != RTNORM) { return (RTNORM) ; } Res = ads_getdist (Center,"\nSpecify the Radius(e.g.2):",&Radius) ; if ((Res != RTNORM) || (Radius <= 0)) { return (RTNORM) ; } // The polygon is flat in the Z=0 plane Start[Z] = 0.0 ; End[Z] = 0.0 ; // Draw a sequence of polygons of varying sizes for (r = 0 ; r < N_Polys ; r ++) { Radius = Radius / (r + 1 ) ; // Draw a polygon as a sequence of lines for (a = 0 ; a < N_Sides ; a++) { Angle = a * TWO_PI / N_Sides ; Start[X] = Center[X] + Radius*sin(Angle) ; Start[Y] = Center[Y] + Radius*cos(Angle) ; Angle = ((a+1)% N_Sides) * TWO_PI / N_Sides ; End [X] = Center[X] + Radius*sin(Angle) ; End [Y] = Center[Y] + Radius*cos(Angle) ; Res = ads_command (RTSTR,"_LINE", RT3DPOINT,Start, RT3DPOINT,End, RTSTR,"", // Leave line command RTSTR,"_redraw", RTNONE) ; // Mark end of the list } } return (RTNORM) ; } //-------------------------------------------------------------- // The ADS function for creating the geometric model of a nut //-------------------------------------------------------------- static int nut_func (void) { ads_name hex_en,cyl_en; // int Res,I ; int N_Sides=6 ; ads_point Center,Point[10] ;//Center:the central point of the //entity ads_real Radius1,Radius2,Height,Angle; //Radius1: the radius of the nut //Radius2: the radius of the hole //Height: the height of the nut ads_retvoid() ; // Tell AutoLISP no return value Res = ads_getpoint(NULL,"\nSpecify the center(e.g.18,9):",Center); // Enter the center point in command line, such as // 18, 9 (the x and y coordinates). if (Res != RTNORM) { return (RTNORM) ; } Res = ads_getdist(Center,"\nEnter the radius of the nut(e.g.2):",&Radius1); if ((Res != RTNORM) || (Radius1 <= 0)) { return (RTNORM) ; } Res = ads_getreal ("\nEnter the radius of the nut hole (e.g.1):",&Radius2); if ((Res != RTNORM) || (Radius2 <= 0)) { return (RTNORM) ; } if(Radius1<=Radius2) {ads_fail("Nut radius should be bigger than hole radius."); return(RTNORM); } Res = ads_getreal ("\nEnter the height of the nut(e.g.1):",&Height) ; if ((Res != RTNORM) || (Height<= 0)) { return (RTNORM) ; } for (I = 0 ; I < N_Sides ; I++) { Angle = I * TWO_PI / N_Sides ; Point[I][X] = Center[X] + Radius1*sin(Angle) ; Point[I][Y] = Center[Y] + Radius1*cos(Angle) ; } Res = ads_command (RTSTR,"_pline", RTNONE) ; // Mark end of the list if (Res != RTNORM) { return (RTNORM) ; } for (I = 0; I < N_Sides ; I++) { Res = ads_command (RTPOINT,Point[I], RTNONE) ; // Mark end of the list } if (Res != RTNORM) { return (RTNORM) ; } Res = ads_command (RTSTR,"c", RTSTR,"", RTNONE) ; // Mark end of the list Res = ads_command(RTSTR,"_extrude", RTSTR,"_last", RTSTR,"", RTREAL,Height, RTSTR,"0", RTSTR,"", RTNONE) ; // Mark end of the list Res=ads_entlast(hex_en);//Pass result to the name of the last //(nondeleted) main entity //in the drawing database. Res=ads_command(RTSTR,"_circle", RTPOINT,Center, RTREAL,Radius2, RTSTR,"", // Leave line command RTSTR,"_extrude", RTSTR,"_last", RTSTR,"", RTREAL,Height, RTSTR,"0", RTSTR,"", RTNONE) ; // Mark the end of the list Res=ads_entlast(cyl_en); //Sets result to the name of the last //(nondeleted) main entity //in the drawing database. Res = ads_command (RTSTR,"_subtract",//Subtract the cyclinder //from the hexagonal solid RTENAME,hex_en, RTSTR,"", RTENAME,cyl_en, RTSTR,"", RTSTR,"_redraw", //redraw the AutoCAD //workspace RTNONE); if (Res != RTNORM) { return (RTNORM) ; } return (RTNORM) ; } //------------------------------------------------------------- // The ADS function for drawing the frame with four windows //------------------------------------------------------------- static int frame_func (void) { int Res, ads_retvoid() ; // Tell AutoLISP no return value Res = ads_command ( RTSTR,"_pline", RTSTR,"3,0.5", RTSTR,"23,0.5", RTSTR,"23,12.5", RTSTR,"3,12.5", RTSTR,"close", RTSTR,"_line", RTSTR,"3,6.5", RTSTR,"23,6.5", RTSTR,"", RTSTR,"_line", RTSTR,"13,0.5", RTSTR,"13,12.5", RTSTR,"", RTSTR,"_text", RTSTR,"3.2,12.8", RTSTR,"0.5", RTSTR,"0", RTSTR,"Interactive Graphical Programming Using ADS", RTSTR,"_text", RTSTR,"3.7,12", RTSTR,"0.3", RTSTR,"0", RTSTR,"POLY-An Example for 2D Modeling", RTSTR,"_text", RTSTR,"13.8,12", RTSTR,"0.3", RTSTR,"0", RTSTR,"NUT-An Example for 3D Modeling", RTSTR,"_text", RTSTR,"3.2,6", RTSTR,"0.3", RTSTR,"0", RTSTR,"SQUARES-Practice in 2D Programming", RTSTR,"_text", RTSTR,"13.2,6", RTSTR,"0.3", RTSTR,"0", RTSTR,"TEST3D-Practice for 3D Programming", RTSTR,"_redraw", RTNONE) ; // Mark end of the list if (Res != RTNORM) { return (RTNORM) ; } } //====================================================================== // The Student Assignment Part // You can fill in the following ADS functions to finish the Assignment // 3 (a) and 3 (b). //====================================================================== //--------------------------------------------------------------- // The ADS function used for creating a series of nested squares //--------------------------------------------------------------- static int squares_func (void) { ads_retvoid() ; // Tell AutoLISP no return value // Ask for a point to start the first square, // use ads_getpoint() // Ask for size of the square, use ads_getdist() // Draw squares of decreasing sizes by repeatedly // calling "_LINE" 4 times } //------------------------------------------------------- // The ADS function used for creating a 3D ADS function //------------------------------------------------------- static int test3d_func (void) /* PURPOSE: To create a solid. */ { ads_retvoid() ; // Tell AutoLISP no return value //Desigen a 3D Modeling here. } // -- End of the program --