home *** CD-ROM | disk | FTP | other *** search
- /* Next available MSG number is 42 */
-
- /************************************************************************
- Name: asm.c. AME2_APLIB_SAMP_asm.c
-
- Description: AME/API sample program for objects transformation.
-
- Author: AME Group
- Autodesk, Inc.
-
-
-
-
- Copyright (C) 1992 by Autodesk, Inc.
- **************************************************************************
- * *
- * Permission to use, copy, modify, and distribute this software *
- * for any purpose and without fee is hereby granted, provided *
- * that the above copyright notice appears in all copies and that *
- * both that copyright notice and this permission notice appear in *
- * all supporting documentation. *
- * *
- * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED *
- * WARRANTY. ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR *
- * PURPOSE AND OF MERCHANTABILITY ARE HEREBY DISCLAIMED. *
- * *
- * *
- * This program allows the user to move and assemble objects *
- * by specifying mating features such as alignment or contact. *
- * Motion coordinate icon is used as the visualization aid for *
- * the transformation. Two commands "SOLALIGN" and "SOLCONTACT" *
- * are available in this implementation. *
- * *
- * "SOLCONTACT" allows the users to move a set of objects (component, *
- * subassembly or assembly) such that one face of the selected object *
- * is in contact but against with another face of the specified *
- * object. The base point on the first (moving) selected face will *
- * move and match to that on the second (destination) selected face. *
- * The reference point on the first selected face defines the feature *
- * axis (from base point to reference point) which will align to *
- * that on the second selected face. In the case that the *
- * selected objects (cylinder for example) are axial symmetric, the *
- * reference point is determined automatically by the program using *
- * arbitrary axis algorithm. Only AME objects are eligible for move *
- * and both moving and destination faces must be plane. *
- * The command syntax for "SOLCONTACT" is shown as follows: *
- * *
- * Command: solcontact *
- * Select objects: Pick objects *
- * *
- * Select a face: Pick a face *
- * Old base point <0,0,0>: Pick a point *
- * Old reference point <Axial Symmetry>: Pick a point or RETURN *
- * *
- * Select a face: Pick a face *
- * New base point <0,0,0>: Pick a point *
- * New reference point <Axial Symmetry>: Pick a point or RETURN *
- * *
- * Ok to move the objects, No/<Yes>: y *
- * *
- * *
- * "SOLALIGN" allows the users to move a set of objects (component, *
- * subassembly or assembly) such that old axis of the selected object *
- * is in alignment with the specified new axis. The first (old) *
- * selected base and end points define the feature axis which will *
- * align to that of the second (destination) selected set. *
- * The reference point together with feature axis define a feature *
- * plane which will lock the selected objects from free orientation *
- * about the selected axis. In the case that the selected objects *
- * (cylinder for example) are axial symmetric, the reference point is *
- * determined automatically by the program using arbitrary axis *
- * algorithm. Only AME objects are eligible for move. *
- * The command syntax for "SOLALIGN" is shown as follows: *
- * *
- * Command: solalign *
- * Select objects: Pick objects *
- * *
- * Old base point <0,0,0>: Pick a point *
- * Old end point <0,0,1>: Pick a point *
- * Old reference point <Axial Symmetry>: Pick a point or RETURN *
- * *
- * New base point <0,0,0>: Pick a point *
- * New end point <0,0,1>: Pick a point *
- * New reference point <Axial Symmetry>: Pick a point or RETURN *
- * *
- * Ok to move the objects, No/<Yes>: y *
- * *
- **************************************************************************
-
-
- Modification history:
- Refer to the RCS section at the end of this file.
-
- Bugs and restrictions on use:
-
- Notes:
-
- **************************************************************************/
-
-
- /*************************************************************************/
- /* Includes */
- /*************************************************************************/
-
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #include <adslib.h>
- #include <aplib.h>
-
- /*************************************************************************/
- /* Defines */
- /*************************************************************************/
-
- #define PI 3.14159265358927
- #define EPSILON 1.0e-8
- #define PMAX 20
- #define OFF 0
- #define ON 1
- #define ORIGIN 2
- #define NO 0
- #define YES 1
- #define CANCEL -1
- #define YELLOW 2
- #define X_AXIS 1
- #define Y_AXIS 2
- #define Z_AXIS 3
- #define GC_STRING 0
- #define GC_LAYER 8
- #define GC_LTYPE 6
- #define GC_COLOR 62
- #define GC_THICK 39
- #define GC_RREAL 40
- #define GC_XCOORD 10
- #define GC_XPOS 11
- #define GC_NORMAL 210
-
- #ifndef ELEMENTS
- #define ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
- #endif
-
- /*************************************************************************/
- /* Typedefs */
- /*************************************************************************/
-
-
- /*************************************************************************/
- /* Global variables */
- /*************************************************************************/
-
- /* Function type declaration */
-
- int funcload();
- void print_new_command_set();
- void command_echo_off();
- void command_echo_on();
- void align_objects_func();
- ap_Bool select_objects();
- ap_Bool get_align_data();
- ap_Bool get_reference_data();
- void contact_objects_func();
- ap_Bool get_contact_layer();
- ap_Bool get_norm_from_face();
- void turn_ucsicon();
- void copy_point();
- ap_Bool verify_2pts_equal();
- ap_Bool get_current_layer();
- ap_Bool get_current_ucs();
- ap_Bool set_current_ucs();
- void trans_wc2uc();
- void trans_uc2wc();
- void trans_wc2ec();
- void add_vector();
- void sub_vector();
- void cross_vector();
- ads_real dot_vector();
- ap_Bool normalize_vector();
- int get_yesno_from_user();
- ap_Bool verify_and_reset_ucs();
- ap_Bool get_xdir_from_zdir();
- ap_Bool create_axis();
- ap_Bool create_arrowhead();
- ap_Bool create_line();
- ap_Bool create_circle();
-
-
- struct resbuf Echo1, Echo2;
-
- /* Command definition and dispatch table. */
-
- struct ads_comm {
- char *cmdname;
- void (*cmdfunc) ();
- };
-
- struct ads_comm cmdtab[] = {
-
- {/*MSG1*/"C:SOLALIGN", align_objects_func},
- {/*MSG2*/"C:SOLCONTACT", contact_objects_func},
- };
-
-
- /*************************************************************************/
- /* .doc main() */
- /*+
- -*/
- /*************************************************************************/
-
- void
- /*FCN*/main(argc, argv)
- int argc;
- char *argv[];
- {
- int stat, cindex;
- short scode = 1;
-
- ads_init(argc, argv);
-
- while (TRUE) {
- if ((stat = ads_link(scode)) < 0) {
- printf(/*MSG3*/"ASM: bad status from ads_link() = %d\n",
- stat);
- fflush(stdout);
- ads_exit(1);
- }
- scode = -RSRSLT;
-
- switch (stat) {
-
- case RQXLOAD: /* Load & register functions */
- scode = -(funcload() ? RSRSLT : RSERR);
- scode = -RSRSLT;
- print_new_command_set();
- break;
-
- case RQSUBR: /* Evaluate external lisp function */
- cindex = ads_getfuncode();
- (*cmdtab[cindex].cmdfunc) ();
- break;
-
- case RQXUNLD: /* Unloading */
- ads_printf (/*MSG4*/"Unloading: ");
- break;
-
- case RQSAVE: /* AutoCAD SAVE notification */
- break;
-
- case RQQUIT: /* AutoCAD QUIT notification */
- break;
-
- case RQEND: /* AutoCAD END notification */
- break;
-
- default:
- break;
-
- }
-
- }
- }
-
- /*************************************************************************/
- /* .doc funcload() */
- /*+
- Load external functions into AutoCAD system
- -*/
- /*************************************************************************/
-
- static int
- /*FCN*/funcload()
-
- {
- int i;
-
- for (i = 0; i < ELEMENTS(cmdtab); i++) {
- if(! ads_defun (cmdtab[i].cmdname , i))
- return RTERROR;
- }
- return RTNORM;
- }
-
- /*************************************************************************/
- /* .doc print_new_command_set() */
- /*+
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/print_new_command_set()
- {
- ads_printf(/*MSG5*/"\nNew loaded commands: SOLALIGN, SOLCONTACT\n");
- }
-
- /*************************************************************************/
- /* .doc command_echo_off() */
- /*+
- Suppress command echo
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/command_echo_off()
- {
- ads_getvar (/*MSG0*/"CMDECHO", &Echo1);
- Echo2.restype = RTSHORT;
- Echo2.resval.rint = FALSE;
- ads_setvar (/*MSG0*/"CMDECHO", &Echo2);
- }
-
- /*************************************************************************/
- /* .doc command_echo_on() */
- /*+
- Resume command echo
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/command_echo_on()
- {
- ads_setvar (/*MSG0*/"CMDECHO", &Echo1);
- }
-
- /*************************************************************************/
- /* .doc align_objects_func() */
- /*+
- This routine performs the following tasks:
-
- 1. Prompt the user to select the objects to be aligned.
- 2. Highlight the selected solids.
- 3. Prompt the user to select two points for old alignment axis.
- 4. Display X_AXIS icon for visual aid.
- 5. Prompt the user to select reference point.
- 6. Display Y_AXIS icon for visual aid.
- 7. Compute the transformation matrix m1.
- 8. Repeat step 3 to step 7 for new base, end & reference points.
- 9. Compute the transformation matrix m2.
- 10. Compose matrix m1 with m2.
- 11. Move the selected objects to the desired location by matrix m.
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/align_objects_func()
- {
- ap_Objid *solset;
- ap_Trans3d m, m1, m2, temp;
- ads_point px, py, py1, py2, pts[3];
- ads_point poorg, pb1, ps1, pe1, pb2, ps2, pe2;
- ads_point xodir, yodir, zodir;
- ads_point xdir1, ydir1, zdir1, xdir2, ydir2, zdir2;
- ads_name sset, sset_axes, chosen;
- long number_obj, i;
- int stat, choice;
- int reset_ucs1 = FALSE, reset_ucs2 = FALSE;
- char layer[32], ltype[32];
- long nent;
-
- /* Initialization */
-
- stat = ap_init();
- if (stat != AP_NORMAL)
- goto Error;
-
- get_current_layer(layer);
- strcpy(ltype, /*MSG6*/"CONTINUOUS");
- ads_ssadd(NULL, NULL, sset_axes);
- get_current_ucs (poorg, xodir, yodir);
- cross_vector(xodir, yodir, zodir);
-
- /* Prompt the user to select the objects to be moved */
-
- stat = select_objects(&solset, sset, &number_obj);
- if(stat == FALSE)
- goto Error1;
-
- /* Highlight all selected solids */
-
- for (i = 0; i < number_obj; i++) {
- ads_ssname (sset, i, chosen);
- ads_redraw(chosen, 3);
- }
-
- /* Prompt user to select two points for old axis */
-
- stat = get_align_data(1, pb1, pe1);
- if(stat == FALSE)
- goto Error2;
-
- /* Display X_AXIS icon (with one arrowhead) */
-
- create_axis(X_AXIS, pb1, pe1, layer, ltype, YELLOW, sset_axes);
-
- /* Set new ucs plane normal to coincide with alignment
- axis and through the old base point pb1 */
-
- sub_vector(pe1, pb1, zdir1);
- reset_ucs1 = verify_and_reset_ucs(poorg, zodir, pb1, zdir1);
-
- /* Prompt the user to select a reference point on current
- ucs plane to lock the selected objects from
- free rotation about the alignment axis */
-
- stat = get_reference_data(1, pb1, ps1);
- if(stat == FALSE)
- goto Error2;
-
- /* Display reference axis icon (with two arrowheads) */
-
- create_axis(Y_AXIS, pb1, ps1, layer, ltype, YELLOW, sset_axes);
-
- /* Compute the transformation matrix m1 which transforms old
- base point to the origin, old alignment axis to coincide
- with Z-axis, and old reference axis to X-axis in WCS */
-
- sub_vector(ps1, pb1, xdir1);
- cross_vector(zdir1, xdir1, ydir1);
- add_vector(pb1, ydir1, py1);
- copy_point(pb1, pts[0]);
- copy_point(ps1, pts[1]);
- copy_point(py1, pts[2]);
- ap_pts2xfm(pts, 3, temp);
- ap_invert(temp, m1);
-
- /* Prompt user to select two points for new axis */
-
- stat = get_align_data(2, pb2, pe2);
- if(stat == FALSE)
- goto Error2;
-
- /* Display alignment axis icon (with one arrowhead) */
-
- create_axis(X_AXIS, pb2, pe2, layer, ltype, YELLOW, sset_axes);
-
- /* Set new ucs plane normal to coincide with alignment
- axis and through the new base point pb2 */
-
- sub_vector(pe2, pb2, zdir2);
- reset_ucs2 = verify_and_reset_ucs(pb1, zdir1, pb2, zdir2);
-
- /* Prompt the user to select a reference point on current
- ucs plane to lock the selected objects from
- free rotation about the alignment axis */
-
- stat = get_reference_data(2, pb2, ps2);
- if(stat == FALSE)
- goto Error2;
-
- /* Display reference axis icon (with two arrowheads) */
-
- create_axis(Y_AXIS, pb2, ps2, layer, ltype, YELLOW, sset_axes);
-
- /* Compute the second transformation matrix m2
- which transforms the origin to new base point,
- Z-axis to coincide with new alignment axis, and
- X-axis to coincide with new reference axis */
-
- sub_vector(ps2, pb2, xdir2);
- cross_vector(zdir2, xdir2, ydir2);
- add_vector(pb2, ydir2, py2);
- copy_point(pb2, pts[0]);
- copy_point(ps2, pts[1]);
- copy_point(py2, pts[2]);
- ap_pts2xfm(pts, 3, m2);
-
- /* Combine matries m1 with m2 */
-
- ap_compose(m2, m1, m);
-
- /* Prompt the user to confirm the move */
-
- ads_printf(/*MSG7*/"\nOk to move the objects, No/<Yes>: ");
- choice = get_yesno_from_user(YES);
- if((choice == NO) || (choice == CANCEL))
- goto Error2;
-
- /* Move the objects to new location and update the display */
-
- for (i=0; i<number_obj; i++) {
- ap_move_obj(solset[i], m, FALSE);
- }
-
- Error2: /* Restore the original ucs */
- if((reset_ucs1 == TRUE) || (reset_ucs2 == TRUE)) {
- add_vector(poorg, xodir, px);
- add_vector(poorg, yodir, py);
- set_current_ucs (poorg, px, py);
- turn_ucsicon(ON);
- }
-
- Error1: /* Clean the memory */
- ads_sslength(sset_axes, &nent);
- for(i=0;i<nent;i++) {
- ads_ssname(sset_axes, i, chosen);
- ads_entdel (chosen);
- }
- ads_ssfree (sset);
- ads_ssfree (sset_axes);
- if (solset != (ap_Objid *)NULL)
- free(solset);
- ads_redraw(NULL, 1);
- Error:
- ads_retvoid ();
- return;
- }
-
- /*************************************************************************/
- /* .doc select_objects() */
- /*+
- This routine prompts user to select a set of objects.
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/select_objects (sols, sset, ns)
- ap_Objid **sols;
- ads_name sset;
- long *ns;
- {
- long ne, i, count = 0L;
- ads_name chosen;
- ap_Objid object;
- int stat;
-
- /* Initialization */
-
- *sols = (ap_Objid)NULL;
- *ns = 0L;
-
- if(ads_ssget (NULL, NULL, NULL, NULL, sset) != RTNORM)
- return FALSE;
- if (ads_sslength (sset, &ne) != RTNORM)
- return FALSE;
-
- /* Verify whether the selected objects are solid.
- Delete non-solids from the selection set.
- Count the total number of solids in the selection set. */
-
- for (i=0; i<ne; i++) {
- ads_ssname (sset, i, chosen);
- stat = ap_name2obj(chosen, &object);
- if (stat == AP_NORMAL) {
- count = count + 1;
- } else
- ads_ssdel(chosen, sset);
- }
- if (count <= 0) {
- ads_printf (/*MSG8*/"\nNo solids found.\n");
- return FALSE;
- }
- if((*sols = (ap_Objid *)malloc(count * sizeof(ap_Objid)))
- == (ap_Objid *)NULL) {
- ads_printf (/*MSG9*/"\nCan't allocate memory for solids array.\n");
- return FALSE;
- }
-
- for (i=0; i<count; i++) {
- ads_ssname (sset, i, chosen);
- stat = ap_name2obj(chosen, &object);
- (*sols)[i] = object;
- }
-
- *ns = count;
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc get_align_data() */
- /*+
- This routine prompts the user to enter two points that
- define the axis to be aligned.
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/get_align_data (choice, p1, p2)
- int choice;
- ads_point p1, p2;
- {
- int stat;
- ads_point pt1, pt2;
-
- /* Initialization of data for default input */
-
- p1[X] = pt1[X] = 0.0;
- p1[Y] = pt1[Y] = 0.0;
- p1[Z] = pt1[Z] = 0.0;
- p2[X] = pt2[X] = 0.0;
- p2[Y] = pt2[Y] = 0.0;
- p2[Z] = pt2[Z] = 1.0;
-
- /* Prompt the user to select the base point of the axis */
-
- if (choice == 1)
- stat = ads_getpoint (NULL,
- /*MSG10*/"\nBase point of old axis <0,0,0>: ", pt1);
- else if (choice == 2)
- stat = ads_getpoint (NULL,
- /*MSG11*/"\nBase point of new axis <0,0,0>: ", pt1);
- else
- return FALSE;
-
- if ((stat == RTCAN) || (stat == RTERROR))
- return FALSE;
-
- /* Prompt the user to select the end point of the axis */
-
- if (choice == 1)
- stat = ads_getpoint (pt1, /*MSG12*/"\nEnd point of old axis <0,0,1>: ", pt2);
- else if (choice == 2)
- stat = ads_getpoint (pt1, /*MSG13*/"\nEnd point of new axis <0,0,1>: ", pt2);
- else
- return FALSE;
-
- if ((stat == RTCAN) || (stat == RTERROR))
- return FALSE;
-
- /* Make sure that base and end points are not coincident */
-
- stat = verify_2pts_equal(pt1, pt2);
- if(stat == TRUE) {
- ads_printf (/*MSG14*/"\nTwo points are coincident.\n");
- return FALSE;
- }
-
- /* Transform base and end points from ucs to wcs */
-
- trans_uc2wc(pt1, FALSE, p1);
- trans_uc2wc(pt2, FALSE, p2);
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc get_reference_data() */
- /*+
- This routine prompts the user to enter a point that
- define the reference axis.
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/get_reference_data (choice, p1, p2)
- int choice;
- ads_point p1, p2;
- {
- int stat;
- ads_point pt1, pt2;
-
- /* Initialization of data for default input */
-
- p2[X] = pt2[X] = 0.0;
- p2[Y] = pt2[Y] = 1.0;
- p2[Z] = pt2[Z] = 0.0;
-
- /* Transform base point from wcs to ucs */
-
- trans_wc2uc(p1, FALSE, pt1);
-
- /* Prompt the user to select the reference point */
-
- if (choice == 1)
- stat = ads_getpoint(pt1,
- /*MSG15*/"\nOld reference point <Axial Symmetry>:", pt2);
- else if (choice == 2)
- stat = ads_getpoint(pt1,
- /*MSG16*/"\nNew reference point <Axial Symmetry>:", pt2);
- else
- return FALSE;
-
- if ((stat == RTCAN) || (stat == RTERROR))
- return FALSE;
- else if(stat == RTNONE) {
- pt2[X] = pt1[X] + 1.0;
- pt2[Y] = pt1[Y];
- }
- pt2[Z] = 0.0;
-
- /* Make sure that base and reference points are not coincident */
-
- stat = verify_2pts_equal(pt1, pt2);
- if(stat == TRUE) {
- ads_printf (/*MSG17*/"\nInvalid reference point.\n");
- return FALSE;
- }
-
- /* Transform reference point from ucs to wcs */
-
- trans_uc2wc(pt2, FALSE, p2);
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc contact_objects_func() */
- /*+
- This routine performs the following tasks:
-
- 1. Prompt the user to select the objects.
- 2. Highlight the selected solids.
- 3. Prompt the user to select a face, a base and a reference point.
- 4. Display motion coordinate icon for visual aid.
- 5. Compute the transformation matrix m1.
- 6. Repeat step 3 to 5 for destination face, base and reference point.
- 7. Compute the transformation matrix m2.
- 8. Compose matrix m1 with m2.
- 9. Move the objects to new location by matrix m.
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/contact_objects_func()
- {
- ap_Objid object, *solset;
- ap_Featid face;
- ap_Trans3d m, m1, m2, temp;
- ads_point pc1, pc2, pf1, ps1, py1, pf2, ps2, py2;
- ads_point xdir1, ydir1, zdir1, xdir2, ydir2, zdir2;
- ads_point poorg, xodir, yodir, zodir, px, py, pts[3];
- ads_name sset, chosen, sset_axes;
- int choice, stat, reset_ucs1 = FALSE, reset_ucs2 = FALSE;
- long i, number_obj, nent;
- char layer[32], ltype[32];
-
- /* Initialization */
-
- stat = ap_init();
- if (stat != AP_NORMAL)
- goto Error;
-
- get_current_layer(layer);
- strcpy(ltype, /*MSG18*/"CONTINUOUS");
- ads_ssadd(NULL, NULL, sset_axes);
- get_current_ucs (poorg, xodir, yodir);
- cross_vector(xodir, yodir, zodir);
-
- /* Prompt user to select the objects to be moved */
-
- stat = select_objects(&solset, sset, &number_obj);
- if(stat == FALSE)
- goto Error1;
-
- /* Prompt user to select the desired contact face */
-
- stat = ap_sel_face (/*MSG19*/"\nSelect old contact face:\n", &object, &face);
- if (stat != AP_NORMAL)
- goto Error1;
-
- /* Highlight selected solids */
-
- for (i = 0; i < number_obj; i++) {
- ads_ssname (sset, i, chosen);
- ads_redraw(chosen, 3);
- }
-
- /* Retrieve a point on and a normal to the face */
-
- stat = get_norm_from_face(object, face, pc1, zdir1);
- if (stat == FALSE)
- goto Error2;
-
- /* Verify whether the selected face lies in current ucs plane.
- If not, set new ucs to lie in the selected face
- and move the ucsicon to new origin */
-
- reset_ucs1 = verify_and_reset_ucs(poorg, zodir, pc1, zdir1);
-
- /* Prompt user to select old base and reference points */
-
- stat = get_contact_data(1, pf1, ps1);
- if(stat == FALSE)
- goto Error2;
-
- /* Display motion coordinate icon on the selected face.
- The first axis goes from base to reference point.
- The second axis starts from base point and goes to
- a direction perpendicular to the first axis */
-
- sub_vector(ps1, pf1, xdir1);
- cross_vector(zdir1, xdir1, ydir1);
- add_vector(pf1, ydir1, py1);
- create_axis(X_AXIS, pf1, ps1, layer, ltype, YELLOW, sset_axes);
- create_axis(Y_AXIS, pf1, py1, layer, ltype, YELLOW, sset_axes);
-
- /* Compute the matrix m1 which transforms face normal direction
- to Z-axis, reference direction to X-axis in wcs */
-
- copy_point(pf1, pts[0]);
- copy_point(ps1, pts[1]);
- copy_point(py1, pts[2]);
- ap_pts2xfm(pts, 3, temp);
- ap_invert(temp, m1);
-
- /* Prompt user to select destination face of an object */
-
- stat = ap_sel_face (/*MSG20*/"\nSelect new contact face:\n", &object, &face);
- if (stat != AP_NORMAL) {
- goto Error2;
- }
-
- /* retrieve a point on the face and inward normal to the face */
-
- stat = get_norm_from_face(object, face, pc2, zdir2);
- if (stat != TRUE)
- goto Error2;
-
- /* Verify whether the second selected face lies in
- current ucs plane */
-
- reset_ucs2 = verify_and_reset_ucs(pc1, zdir1, pc2, zdir2);
-
- /* Prompt user to select new base and reference points */
-
- stat = get_contact_data(2, pf2, ps2);
- if(stat == FALSE)
- goto Error2;
-
- /* Display motion coordinate icon on the selected face */
-
- zdir2[X] = -zdir2[X];
- zdir2[Y] = -zdir2[Y];
- zdir2[Z] = -zdir2[Z];
- sub_vector(ps2, pf2, xdir2);
- cross_vector(zdir2, xdir2, ydir2);
- add_vector(pf2, ydir2, py2);
- create_axis(X_AXIS, pf2, ps2, layer, ltype, YELLOW, sset_axes);
- create_axis(Y_AXIS, pf2, py2, layer, ltype, YELLOW, sset_axes);
-
- /* Compute the matrix m2 */
-
- copy_point(pf2, pts[0]);
- copy_point(ps2, pts[1]);
- copy_point(py2, pts[2]);
- ap_pts2xfm(pts, 3, m2);
- ap_compose(m2, m1, m);
-
- /* Prompt the user to confirm the move of objects */
-
- ads_printf(/*MSG21*/"\nOk to move the objects, No/<Yes>: ");
- choice = get_yesno_from_user(YES);
- if((choice == NO) || (choice == CANCEL)) {
- goto Error2;
- }
-
- /* Move the objects and update the display */
-
- for (i=0; i<number_obj; i++)
- ap_move_obj(solset[i], m, FALSE);
-
- Error2: /* Restore the original ucs */
- if((reset_ucs1 == TRUE) || (reset_ucs2 == TRUE)) {
- add_vector(poorg, xodir, px);
- add_vector(poorg, yodir, py);
- set_current_ucs (poorg, px, py);
- turn_ucsicon(ON);
- }
-
- Error1: /* Clean the memory */
- ads_sslength(sset_axes, &nent);
- for(i=0;i<nent;i++) {
- ads_ssname(sset_axes, i, chosen);
- ads_entdel (chosen);
- }
- ads_ssfree (sset);
- ads_ssfree (sset_axes);
- if (solset != (ap_Objid *)NULL)
- free(solset);
- ads_redraw(NULL, 1);
- Error:
- ads_retvoid ();
- return;
- }
-
- /*************************************************************************/
- /* .doc get_contact_data() */
- /*+
- This routine prompts the user to select base and
- reference points.
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/get_contact_data (choice, p1, p2)
- int choice;
- ads_point p1, p2;
- {
- int stat;
- ads_point pt1, pt2;
-
- /* Initialization */
-
- p1[X] = pt1[X] = 0.0;
- p1[Y] = pt1[Y] = 0.0;
- p1[Z] = pt1[Z] = 0.0;
-
- /* Select the contact base point */
-
- if (choice == 1)
- stat = ads_getpoint (NULL, /*MSG22*/"\nOld base point <0,0,0>: ", pt1);
- else if (choice == 2)
- stat = ads_getpoint (NULL, /*MSG23*/"\nNew base point <0,0,0>: ", pt1);
- else
- return FALSE;
-
- if ((stat == RTCAN) || (stat == RTERROR))
- return FALSE;
-
- /* Project base point onto the selected face */
-
- pt1[Z] = 0.0;
-
- if (choice == 1)
- stat = ads_getpoint (pt1,
- /*MSG24*/"\nOld reference point <Axial Symmetry>: ", pt2);
- else if (choice == 2)
- stat = ads_getpoint (pt1,
- /*MSG25*/"\nNew reference point <Axial Symmetry>: ", pt2);
- else
- return FALSE;
-
- if ((stat == RTCAN) || (stat == RTERROR))
- return FALSE;
- else if (stat == RTNONE) {
- pt2[X] = pt1[X] + 1.0;
- pt2[Y] = pt1[Y];
- }
-
- pt2[Z] = 0.0;
-
- /* Make sure that base and reference points are not coincident */
-
- stat = verify_2pts_equal(pt1, pt2);
- if(stat == TRUE) {
- ads_printf (/*MSG26*/"\nInvalid reference point.\n");
- return FALSE;
- }
-
- trans_uc2wc(pt1, FALSE, p1);
- trans_uc2wc(pt2, FALSE, p2);
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc get_norm_from_face() */
- /*+
- This routine performs the following tasks:
-
- 1. Verify that the selected face is a plane face.
- 2. Retrieve a point pc on the face.
- 3. Retrieve the inward face normal direction.
- -*/
- /*************************************************************************/
-
- static ap_Bool
- /*FCN*/get_norm_from_face(object, face, pc, norm)
- ap_Objid object;
- ap_Featid face;
- ads_point pc, norm;
- {
- ap_Faceinfo *finfo;
- int stat;
-
- /* Retrieve face type and verify whether it is plane */
-
- stat = ap_get_faceinfo(object, face, &finfo);
- if (stat != AP_NORMAL) {
- ads_printf (/*MSG27*/"\nUnable to retrieve face information");
- ads_retvoid();
- return FALSE;
- }
- if (finfo->stype != AP_PLANAR) {
- ads_printf (/*MSG28*/"\nThe selected face must be plane.");
- ads_retvoid();
- return FALSE;
- }
-
- /* Retrieve inward face normal direction,
- and a point pc on the face */
-
- pc[X] = finfo->face_rm[0][3];
- pc[Y] = finfo->face_rm[1][3];
- pc[Z] = finfo->face_rm[2][3];
- copy_point(finfo->surf.pla.norm, norm);
- norm[X] = - norm[X];
- norm[Y] = - norm[Y];
- norm[Z] = - norm[Z];
- ap_free_faceinfo(finfo);
- return TRUE;
- }
-
-
- /*************************************************************************/
- /* .doc turn_ucsicon() */
- /*+
- This routine will turn ucsicon on, off or move it to new origin
- -*/
- /*************************************************************************/
-
- static void
- /* FCN */turn_ucsicon(action)
- int action;
- {
- command_echo_off ();
- if (action == ON)
- ads_command (RTSTR, /*MSG29*/"_.UCSICON", RTSTR, /*MSG30*/"_ON", NULL);
- else if(action == ORIGIN)
- ads_command (RTSTR, /*MSG31*/"_.UCSICON", RTSTR, /*MSG32*/"_ORIGIN", NULL);
- else
- ads_command (RTSTR, /*MSG33*/"_.UCSICON", RTSTR, /*MSG34*/"_OFF", NULL);
-
- command_echo_on ();
- }
-
- /*************************************************************************/
- /* .doc copy_point() */
- /*+
- Duplicate a point, that is pt2 = pt1
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/copy_point (pt1, pt2)
- ads_point pt1, pt2;
- {
- pt2[X] = pt1[X];
- pt2[Y] = pt1[Y];
- pt2[Z] = pt1[Z];
- }
-
- /*************************************************************************/
- /* .doc verify_2pts_equal() */
- /*+
- Verify whether two points p1 & p2 are equal
- that is, within tolerance EPSILON
- -*/
- /*************************************************************************/
-
- static ap_Bool
- /* FCN */verify_2pts_equal (p1, p2)
- ads_point p1, p2;
- {
- ads_real dx, dy, dz;
-
- dx = fabs (p2[X] - p1[X]);
- dy = fabs (p2[Y] - p1[Y]);
- dz = fabs (p2[Z] - p1[Z]);
-
-
- if ((dx < EPSILON) && (dy < EPSILON) && (dz < EPSILON))
- return TRUE;
- else
- return FALSE;
- }
-
- /************************************************************************/
- /*.doc get_current_layer() */
- /*+
- This routine retrieves the name of current layer from
- AutoCAD database.
- -*/
- /************************************************************************/
-
- static ap_Bool
- /*FCN*/get_current_layer (layer)
- char layer[32];
- {
- int stat;
- struct resbuf Cla;
-
- stat = ads_getvar (/*MSG0*/"CLAYER", &Cla);
- if (stat == RTNORM) {
- strcpy(layer, Cla.resval.rstring);
- return TRUE;
- } else
- return FALSE;
- }
-
- /*************************************************************************/
- /* .doc get_current_ucs() */
- /*+
- Retrieve current ucs's origin, x-direction & y-direction.
- Return them through arguments po, px & py respectively.
- -*/
- /*************************************************************************/
-
- static ap_Bool
- /*FCN*/get_current_ucs(po, px, py)
- ads_point po, px, py;
-
- {
- struct resbuf ucso, ucsx, ucsy;
- int stat;
-
- stat = ads_getvar (/*MSG0*/"UCSORG", &ucso);
- if (stat != RTNORM)
- return FALSE;
- stat = ads_getvar (/*MSG0*/"UCSXDIR", &ucsx);
- if (stat != RTNORM)
- return FALSE;
- stat = ads_getvar (/*MSG0*/"UCSYDIR", &ucsy);
- if (stat != RTNORM)
- return FALSE;
-
- copy_point(ucso.resval.rpoint, po);
- copy_point(ucsx.resval.rpoint, px);
- copy_point(ucsy.resval.rpoint, py);
- return TRUE;
- }
- /*************************************************************************/
- /* .doc set_current_ucs() */
- /*+
- Reset current ucs by using three points p1, p2 & p3, where
- p1 = new origin
- p1p2 = new x-direction
- p1p2 x p1p3 = new z-direction
- -*/
- /*************************************************************************/
-
- static ap_Bool
- /*FCN*/set_current_ucs(p1, p2, p3)
- ads_point p1, p2, p3;
- {
- ads_point pt1, pt2, pt3;
- int stat1, stat2, stat3, stat;
-
- stat1 = verify_2pts_equal (p1, p2);
- stat2 = verify_2pts_equal (p2, p3);
- stat3 = verify_2pts_equal (p3, p1);
- if ((stat1 == TRUE) || (stat2 == TRUE) || (stat3 == TRUE))
- return FALSE;
-
- trans_wc2uc(p1, FALSE, pt1);
- trans_wc2uc(p2, FALSE, pt2);
- trans_wc2uc(p3, FALSE, pt3);
-
- command_echo_off ();
- stat = ads_command(RTSTR, /*MSG35*/"_.ucs", RTSTR, /*MSG36*/"_3", RT3DPOINT,
- pt1, RT3DPOINT, pt2, RT3DPOINT, pt3, NULL);
-
- if (stat != RTNORM)
- {
- command_echo_on ();
- return FALSE;
- }
- command_echo_on ();
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc trans_wc2uc() */
- /*+
- Transform a point p in wcs into point q in ucs
- If vec = TRUE, then p is a vector
- If vec = FALSE, then p is a point
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/trans_wc2uc(p,vec,q)
- ads_point p, q;
- ap_Bool vec;
- {
- struct resbuf rbfrom, rbto;
-
- rbfrom.restype = RTSHORT;
- rbto.restype = RTSHORT;
- rbfrom.resval.rint = 0; /* from world */
- rbto.resval.rint = 1; /* to ucs */
- ads_trans(p, &rbfrom, &rbto, vec, q);
- }
-
- /*************************************************************************/
- /* .doc trans_uc2wc() */
- /*+
- Transform a point p in ucs into point q in wcs
- If vec = TRUE, then p is a vector
- If vec = FALSE, then p is a point
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/trans_uc2wc(p,vec,q)
- ads_point p, q;
- ap_Bool vec;
- {
- struct resbuf rbfrom, rbto;
-
- rbfrom.restype = RTSHORT;
- rbto.restype = RTSHORT;
- rbfrom.resval.rint = 1; /* from ucs */
- rbto.resval.rint = 0; /* to world */
- ads_trans(p, &rbfrom, &rbto, vec, q);
- }
-
- /*************************************************************************/
- /*.doc trans_wc2ec(external) */
- /*+
- Transform a point p in wcs into point q in ecs
- If vec = TRUE, then p is a vector
- If vec = FALSE, then p is a point
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/trans_wc2ec(p, norm, vec, q)
- ads_point p, norm, q;
- ap_Bool vec;
- {
- struct resbuf rbfrom, rbto;
-
- normalize_vector(norm, norm);
- rbfrom.restype = RTSHORT;
- rbfrom.resval.rint = 0; /* from world */
- rbto.restype = RT3DPOINT;
- rbto.resval.rpoint[X] = norm[X]; /* to ecs */
- rbto.resval.rpoint[Y] = norm[Y];
- rbto.resval.rpoint[Z] = norm[Z];
- ads_trans(p, &rbfrom, &rbto, vec, q);
- }
-
- /*************************************************************************/
- /* .doc add_vector() */
- /*+
- Add two vectors cp = ap + bp
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/add_vector( ap, bp, cp)
- ads_point ap, bp, cp;
- {
- cp[X] = ap[X] + bp[X];
- cp[Y] = ap[Y] + bp[Y];
- cp[Z] = ap[Z] + bp[Z];
- }
-
- /*************************************************************************/
- /* .doc sub_vector() */
- /*+
- Subtract vector bp from vector ap with result cp = ap - bp
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/sub_vector(ap, bp, cp)
- ads_point ap, bp, cp;
- {
- cp[X] = ap[X] - bp[X];
- cp[Y] = ap[Y] - bp[Y];
- cp[Z] = ap[Z] - bp[Z];
- }
-
- /*************************************************************************/
- /* .doc cross_vector() */
- /*+
- Cross product of two vectors, cp = ap X bp.
- -*/
- /*************************************************************************/
-
- static void
- /*FCN*/cross_vector(ap, bp, cp)
- ads_point ap, bp, cp;
- {
- ads_point result;
-
- result[X] = ap[Y] * bp[Z] - ap[Z] * bp[Y];
- result[Y] = ap[Z] * bp[X] - ap[X] * bp[Z];
- result[Z] = ap[X] * bp[Y] - ap[Y] * bp[X];
- copy_point (result, cp);
- }
-
- /*************************************************************************/
- /* .doc dot_vector() */
- /*+
- Dot product of two vectors, The result = ap.bp
- -*/
- /*************************************************************************/
-
- static ads_real
- /*FCN*/dot_vector(ap, bp)
- ads_point ap, bp;
- {
- ads_real result;
-
- result = ap[X] * bp[X] + ap[Y] * bp[Y] + ap[Z] * bp[Z];
- return result;
- }
-
- /*************************************************************************/
- /* .doc normalize_vector() */
- /*+
- Normalize a vector, that is q = p/||p||
- -*/
- /*************************************************************************/
-
- static ap_Bool
- /*FCN*/normalize_vector (p, q)
- ads_point p, q;
- {
- ap_Real temp, dis;
-
- temp = p[X]*p[X] + p[Y]*p[Y] + p[Z]*p[Z];
- if (temp < EPSILON * EPSILON)
- return FALSE;
-
- dis = sqrt (temp);
- q[X] = p[X] / dis;
- q[Y] = p[Y] / dis;
- q[Z] = p[Z] / dis;
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc get_yesno_from_user() */
- /*+
- Prompt user to choice "Yes" or "No".
- The function return "YES", "NO" or "CANCEL" depending on
- user's action and the setup for default_choice.
- -*/
- /*************************************************************************/
- static int
- /*FCN*/get_yesno_from_user (default_choice)
- ap_Bool default_choice;
- {
- char inbuf[132];
- int status;
-
- ads_initget(0, /*MSG37*/"Yes No");
- strcpy(inbuf, "");
-
- status = ads_getkword (NULL, inbuf);
-
- if (status == RTCAN) {
- ads_retvoid ();
- return CANCEL;
- } else if ((default_choice == YES) && (status == RTNONE)) {
- ads_retvoid ();
- return YES;
- } else if ((default_choice == NO) && (status == RTNONE)) {
- ads_retvoid ();
- return NO;
- } else if (status == RTNORM) {
- if (strcmp (/*MSG38*/"Yes", inbuf) == 0) {
- ads_retvoid ();
- return YES;
- } else if (strcmp (/*MSG39*/"No", inbuf) == 0) {
- ads_retvoid ();
- return NO;
- } else {
- ads_retvoid ();
- return CANCEL;
- }
- } else
- return CANCEL;
- }
-
- /*************************************************************************/
- /* .doc verify_and_reset_ucs() */
- /*+
- This routine verify whether two planes are coincident.
- The plane is defined by its normal and a through point.
- If they are not coincident, set new ucs plane to coincide
- with second plane defined by origin org2 and normal norm2.
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/verify_and_reset_ucs (org1, norm1, org2, norm2)
- ads_point org1, norm1, org2, norm2;
- {
- ads_point dir, pd1, pd2, xdir, ydir, px, py;
- ads_real dx, dy, dz, du, dv;
-
- if (((fabs (norm1[X]) < EPSILON) &&
- (fabs (norm1[Y]) < EPSILON) &&
- (fabs (norm1[Z]) < EPSILON)) ||
- ((fabs (norm2[X]) < EPSILON) &&
- (fabs (norm2[Y]) < EPSILON) &&
- (fabs (norm2[Z]) < EPSILON)))
- return FALSE;
-
- normalize_vector(norm1, pd1);
- normalize_vector(norm2, pd2);
- dx = pd1[Y]*pd2[Z] - pd1[Z]*pd2[Y];
- dy = pd1[Z]*pd2[X] - pd1[X]*pd2[Z];
- dz = pd1[X]*pd2[Y] - pd1[Y]*pd2[X];
-
- sub_vector(org2, org1, dir);
- du = dot_vector (dir, pd1);
- dv = dot_vector (dir, pd2);
-
- if ((fabs (dx) < EPSILON) && (fabs (dy) < EPSILON) &&
- (fabs (dz) < EPSILON) && (fabs (du) < EPSILON) &&
- (fabs (dv) < EPSILON))
- return FALSE;
-
- /* Set ucs plane to new location */
-
- get_xdir_from_zdir(pd2, xdir);
- cross_vector(pd2, xdir, ydir);
- add_vector(org2, xdir, px);
- add_vector(org2, ydir, py);
- turn_ucsicon(OFF);
- set_current_ucs (org2, px, py);
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc get_xdir_from_zdir() */
- /*+
- This routine compute the x-axis direction from given
- z-axis direction based on arbitrary axis algorithm.
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/get_xdir_from_zdir (zdir, xdir)
- ads_point zdir, xdir;
- {
- ads_point u, v, wydir, wzdir;
-
- wydir[X] = 0.0;
- wydir[Y] = 1.0;
- wydir[Z] = 0.0;
-
- wzdir[X] = 0.0;
- wzdir[Y] = 0.0;
- wzdir[Z] = 1.0;
-
- if ((fabs (zdir[X]) < EPSILON) &&
- (fabs (zdir[Y]) < EPSILON) &&
- (fabs (zdir[Z]) < EPSILON))
- return FALSE;
-
- else
- {
- normalize_vector(zdir, u);
-
- if ((fabs(u[X]) < 1.0/64.0) && (fabs (u[Y]) < 1.0/64.0))
- cross_vector (wydir, u, v);
-
- else
- cross_vector (wzdir, u, v);
-
- normalize_vector(v, xdir);
- return (TRUE);
- }
- }
-
- /*************************************************************************/
- /* .doc create_axis() */
- /*+
- This routine creates axis icon consisting of center line
- and arrowheads. The center line starts from pt1 and goes
- to pt2 direction. The length of the axis is scaled
- automatically to be proportional to (1/5) viewport size.
- The number of arrowheads is determined by argument axis_type.
- If axis_type = X_AXIS - One arrowhead.
- If axis_type = Y_AXIS - Two arrowheads.
- If axis_type = Z_AXIS - Three arrowheads.
-
- If the creation is successful, sset contains the collection
- of entity names.
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/create_axis(axis_type, pt1, pt2, lay, ltp, color, sset)
- ads_point pt1, pt2;
- int axis_type, color;
- char *lay, *ltp;
- ads_name sset;
- {
- ads_point pc1, pc2, pc3, pd, norm;
- ads_real length, len, rad, vsize;
- struct resbuf vrb;
- ads_name ent;
- int stat;
-
- length = ads_distance(pt1, pt2);
- if (length < EPSILON)
- return FALSE;
- stat = ads_getvar(/*MSG0*/"VIEWSIZE", &vrb);
- if (stat != RTNORM)
- return FALSE;
- vsize = vrb.resval.rreal;
- len = 0.2 * vsize;
- rad = 0.05 * len;
- sub_vector(pt2, pt1, pd);
- normalize_vector(pd, norm);
- pt2[X] = pt1[X] + len * norm[X];
- pt2[Y] = pt1[Y] + len * norm[Y];
- pt2[Z] = pt1[Z] + len * norm[Z];
-
- pc1[X] = pt1[X] + 0.9 * len * norm[X];
- pc1[Y] = pt1[Y] + 0.9 * len * norm[Y];
- pc1[Z] = pt1[Z] + 0.9 * len * norm[Z];
-
- pc2[X] = pt1[X] + 0.8 * len * norm[X];
- pc2[Y] = pt1[Y] + 0.8 * len * norm[Y];
- pc2[Z] = pt1[Z] + 0.8 * len * norm[Z];
-
- pc3[X] = pt1[X] + 0.7 * len * norm[X];
- pc3[Y] = pt1[Y] + 0.7 * len * norm[Y];
- pc3[Z] = pt1[Z] + 0.7 * len * norm[Z];
-
- switch(axis_type) {
- case 3:
- stat = create_line(pt1, pt2, lay, ltp, color, ent);
- if (stat == TRUE)
- ads_ssadd(ent, sset, sset);
- create_arrowhead(pc1, pt2, rad, lay, ltp, color, sset);
- create_arrowhead(pc2, pc1, rad, lay, ltp, color, sset);
- create_arrowhead(pc3, pc2, rad, lay, ltp, color, sset);
- break;
-
- case 2:
-
- stat = create_line(pt1, pt2, lay, ltp, color, ent);
- if (stat == TRUE)
- ads_ssadd(ent, sset, sset);
- create_arrowhead(pc1, pt2, rad, lay, ltp, color, sset);
- create_arrowhead(pc2, pc1, rad, lay, ltp, color, sset);
- break;
-
- case 1:
- default:
-
- stat = create_line(pt1, pt2, lay, ltp, color, ent);
- if (stat == TRUE)
- ads_ssadd(ent, sset, sset);
- create_arrowhead(pc1, pt2, rad, lay, ltp, color, sset);
- break;
- }
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc create_arrowhead() */
- /*+
- This routine creates an arrowhead icon consisting of
- a circle and 4 lines segments. The circle of specified
- radius is centered at point pt1 and is normal to the
- direction from pt1 to pt2.
- The four line segments are created by connecting
- pt2 to four quadrant points of the circle respectively.
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/create_arrowhead(pt1, pt2, radius, layer, ltype, color, sset)
- ads_point pt1, pt2;
- ads_real radius;
- char *layer, *ltype;
- int color;
- ads_name sset;
- {
- ads_point pd, pe, pw, ps, pn, xdir, ydir, norm;
- ads_name ent;
- int stat;
-
- sub_vector(pt2, pt1, pd);
- normalize_vector(pd, norm);
- get_xdir_from_zdir(norm, pd);
- normalize_vector(pd, xdir);
- cross_vector(norm, xdir, pd);
- normalize_vector(pd, ydir);
-
- pe[X] = pt1[X] + radius * xdir[X];
- pe[Y] = pt1[Y] + radius * xdir[Y];
- pe[Z] = pt1[Z] + radius * xdir[Z];
-
- pw[X] = pt1[X] - radius * xdir[X];
- pw[Y] = pt1[Y] - radius * xdir[Y];
- pw[Z] = pt1[Z] - radius * xdir[Z];
-
- pn[X] = pt1[X] + radius * ydir[X];
- pn[Y] = pt1[Y] + radius * ydir[Y];
- pn[Z] = pt1[Z] + radius * ydir[Z];
-
- ps[X] = pt1[X] - radius * ydir[X];
- ps[Y] = pt1[Y] - radius * ydir[Y];
- ps[Z] = pt1[Z] - radius * ydir[Z];
-
- stat = create_circle(pt1, radius, norm, layer, ltype, color, ent);
- if (stat == TRUE)
- ads_ssadd(ent, sset, sset);
- stat = create_line(pt2, pe, layer, ltype, color, ent);
- if (stat == TRUE)
- ads_ssadd(ent, sset, sset);
- stat = create_line(pt2, pn, layer, ltype, color, ent);
- if (stat == TRUE)
- ads_ssadd(ent, sset, sset);
- stat = create_line(pt2, ps, layer, ltype, color, ent);
- if (stat == TRUE)
- ads_ssadd(ent, sset, sset);
- stat = create_line(pt2, pw, layer, ltype, color, ent);
- if (stat == TRUE)
- ads_ssadd(ent, sset, sset);
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc create_line() */
- /*+
- This routine creates a line from point p1 to p2 in wcs
- with specified layer, ltype and color attribute.
- The line is inserted into AutoCAD database by ads_entmake().
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/create_line( p1, p2, layer, ltype, color, ename)
- ads_point p1, p2;
- char *layer, *ltype;
- int color;
- ads_name ename;
- {
- int stat;
- struct resbuf pth,
- layh, /* layer */
- ltph, /* line type */
- pcol, /* color */
- ptk, /* thickness */
- p1h,
- p2h;
-
- pth.rbnext = &layh;
- layh.rbnext = <ph;
- ltph.rbnext = &pcol;
- pcol.rbnext = &ptk;
- ptk.rbnext = &p1h;
- p1h.rbnext = &p2h;
- p2h.rbnext = NULL;
-
- pth.restype = GC_STRING;
- pth.resval.rstring = /*MSG0*/"LINE";
- layh.restype = GC_LAYER;
- layh.resval.rstring = layer;
- ltph.restype = GC_LTYPE;
- ltph.resval.rstring = ltype;
- pcol.restype = GC_COLOR;
- pcol.resval.rint = color;
- ptk.restype = GC_THICK;
- ptk.resval.rreal = 0.0;
- pth.restype = GC_STRING;
- pth.resval.rstring = /*MSG0*/"LINE";
-
- p1h.restype = GC_XCOORD;
- p1h.resval.rpoint[X] = p1[X];
- p1h.resval.rpoint[Y] = p1[Y];
- p1h.resval.rpoint[Z] = p1[Z];
-
- p2h.restype = GC_XPOS;
- p2h.resval.rpoint[X] = p2[X];
- p2h.resval.rpoint[Y] = p2[Y];
- p2h.resval.rpoint[Z] = p2[Z];
-
- stat = ads_entmake(&pth);
- if (stat != RTNORM) {
- ads_printf (/*MSG40*/"\nCan't make a line.\n");
- return FALSE;
- }
- ads_entlast(ename);
- return TRUE;
- }
-
- /*************************************************************************/
- /* .doc create_circle() */
- /*+
- This routine creates a circle of a given radius at
- specified center and normal direction. The circle
- has specified layer, ltype and color attribute.
- The circle is inserted into AutoCAD database by ads_entmake().
- -*/
- /*************************************************************************/
- static ap_Bool
- /*FCN*/create_circle(cen, r, norm, layer, ltype, color, ename)
- ads_point cen;
- ads_real r;
- ads_point norm;
- char *layer, *ltype;
- int color;
- ads_name ename;
- {
- int stat;
- ads_point ecs_cen;
- struct resbuf circh,
- layh, /* layer */
- ltph, /* line type */
- pcol, /* color */
- ptk, /* thickness */
- cenh,
- radh,
- normh;
-
- circh.rbnext = &layh;
- layh.rbnext = <ph;
- ltph.rbnext = &pcol;
- pcol.rbnext = &ptk;
- ptk.rbnext = &cenh;
- cenh.rbnext = &radh;
- radh.rbnext = &normh;
- normh.rbnext = NULL;
-
- circh.restype = GC_STRING;
- circh.resval.rstring = /*MSG0*/"CIRCLE";
- layh.restype = GC_LAYER;
- layh.resval.rstring = layer;
- ltph.restype = GC_LTYPE;
- ltph.resval.rstring = ltype;
- pcol.restype = GC_COLOR;
- pcol.resval.rint = color;
- ptk.restype = GC_THICK;
- ptk.resval.rreal = 0.0;
-
- cenh.restype = GC_XCOORD;
- trans_wc2ec(cen, norm, FALSE, ecs_cen);
- cenh.resval.rpoint[X] = ecs_cen[X];
- cenh.resval.rpoint[Y] = ecs_cen[Y];
- cenh.resval.rpoint[Z] = ecs_cen[Z];
-
- radh.restype = GC_RREAL;
- radh.resval.rreal = r;
-
- normh.restype = GC_NORMAL;
- normh.resval.rpoint[X] = norm[X];
- normh.resval.rpoint[Y] = norm[Y];
- normh.resval.rpoint[Z] = norm[Z];
-
- stat = ads_entmake(&circh);
- if (stat != RTNORM) {
- ads_printf (/*MSG41*/"\nCan't make a circle.\n");
- return FALSE;
- }
- ads_entlast(ename);
- return TRUE;
- }
-
-
- /* EOF */
-