!   TITLE:  pocket_cut.mac (SM_TOOL)
!
!
!
!   This sub-macro is used to create a pocket cut into a volume, where
!   the pocket shape is inscribed within the selected area profile on the
!   volume, and whose lines are parallel to the selected area lines. The
!   distance between the parallel lines is 'wall_thk', which is the thick-
!   ness of the remaining wall after the operation is completed. This
!   results in a "hollwed-out" volume of constant wall thickness. The
!   lines must be straight lines, i.e., no arc or splined lines.
!
!   For automatic extrusion, the program will choose the correct direc-
!   tion of extrusion if ALL REMAINING keypoints (all keypoints exclud-
!   ing the keypoints of the selected area) in the volume lie on one
!   side of the z axis.  For the case of a complex volume where key-
!   points in the volume lie on both the positive and negative side,
!   the over-ride direction option should be used. This is done by spec-
!   ifying a KP number for 'p1od'.  If 'p1od' is specified, then the pro-
!   gram will relinquish direction control to the user.
!
!   NOTE:   The centroid of the selected area profile is assumed to be
!           at or near the center of the selected area, and therefore
!           within the confines of the area line loop. There can be an
!           ill-formed area profile that WILL violate the intended ex-
!           ecution of this macro. If the centroid is located outside
!           of the loop, or any such location that will cause the dir-
!           ection of any of the KP c.s.'s to be reversed, the boolean
!           operation will fail to execute properly or at all.
!
!           A general 'rule-of-thumb' is to choose areas that are close
!           to a symmetric form around the centroid of area such that
!           the centroid lies within the line loop.
!
!   Input data necessary to run this macro:
!
!       A selected area
!
!       wall_thk = desired wall thickness
!
!       dcut_n = depth of cut into volume (distance along a path
!                normal to the surface)
!
!       offset = boolean variable to choose either normal extrude
!                or skewed extrude. Valid arguments:
!
!                offset='normal'
!                offset='skew'
!
!   The following arguments are valid only when offset='skew'. If
!   offset='normal', they need not be specified:
!
!       dcut_s = depth of cut into volume (distance along the skew
!                path)
!
!            *NOTE: If dcut_s is left blank or 0, dcut_n will be
!                   used to calculate the skew path length.
!
!       phi_xz = skew angle as measured from the -z axis, in the
!                xz plane:
!
!                phixz < 0: skew toward - x axis direction
!                phixz > 0: skew toward + x axis direction
!
!       phi_elev = skew angle as measured from xz plane to a line
!                  that connects the origin of p1cs to a point in
!                  space (y coordinate of point is not 0):
!
!                  phi_elev < 0: skew toward - y direction
!                  phi_elev > 0: skew toward + y direction
!
!           The skew line direction is measured from p1cs. This
!           is the active c.s. that is used to measure phi_xz
!           and phi_elev from. Therefore, phi_xz is measured
!           from the p1cs -z axis, and phi_elev is measured from
!           the p1cs xz plane.  Note that p1cs has its origin
!           located at the minimum keypoint number of the selected
!           area keypoints, kset1.
!
!   A case for complex shaped volumes may exist where the user may
!   want to over-ride the extrude direction. For this case, set the
!   parameters:
!
!           p1od = origin keypoint of 1st c.s.
!           p2od = x axis keypoint, which establishes
!                  the extrude direction
!
!   If these parameters are not specified, then the program will
!   will choose the direction of extrusion, which may be incorrect.
!
!
!
!                (1)      (2)   (3)   (4)     (5)      (6)       (7)
!  POCKET_CUT, wall_thk, p1od, p2od, offset, phi_xz, phi_elev, dcut_n,
!
!              dcut_s
!               (8)
!
!
*get,prkey_,active,0,prkey
/nopr

wall_thk=arg1
p1od=arg2
p2od=arg3
offset=arg4
phi_xz=arg5
phi_elev=arg6
dcut_n=arg7
dcut_s=arg8
!
!- A. - Create Volume, Area, Line, and Keypoint Sets for Operations ------
!
get_max_entity
!
a2bcut=am                   ! area surface to be (2b) cut into (selected)
!
csys,0
!
asum,default
!
*get,pcx,area,,cent,x       ! x, y and z location of area centroid
*get,pcy,area,,cent,y
*get,pcz,area,,cent,z
!
k,,pcx,pcy,pcz              ! place keypoint at centroid
!
*get,pc,kp,,num,max         ! assign parameter to centroid KP number
!
lsla,selv   `               ! select lines associated with a2bcut
cm,lset1,line
!
ksll,selv                   ! select keypoints associated with lines of a2bcut
ksel,a,kp,,pc               ! plus area centroid KP.
cm,kset1,kp
!
vsla,selv,0                 ! select volume associated with a2bcut
cm,vset1,volu
!
aslv,s                      ! select all areas of volume excluding a2bcut
asel,u,area,,a2bcut
!
vsel,s,volu,,vset1
aslv,s
lsla,s                      ! select all keypoints of volume excluding the
ksll,s                      ! keypoints of a2bcut
ksel,u,kp,,kset1
cm,kset2,kp
!
!-- B. --- Check Path Direction for Correct Extrude Direction ---------
!
*if,p1od,eq,0,then
    !
    init_entity_num
    !
    asel,selv,area,,a2bcut      ! select all entities of a2bcut
    lsel,selv,line,,lset1
    ksel,selv,kp,,kset1
    !
    *get,kmin,kp,,num,min       ! retrieve MIN keypoint number in a2bcut
    !
    ksel,r,kp,,kmin             ! select first kp to set up c.s. on
    lslk,r,0                    ! select lines attached to kmin
    *get,ln1,line,,num,min      ! retieve lines ln1 and ln2
    *get,ln2,line,,num,max
    !
    *get,k1,line,ln1,kp,1       ! check that 2nd KP of line 1 is not kmin
    *if,k1,eq,kmin,then         ! and assign k1 that KP number
        *get,k1,line,ln1,kp,2
    *endif
    !
    *get,k2,line,ln2,kp,1       ! check that 2nd KP of line 2 is not kmin
    *if,k2,eq,kmin,then         ! and assign k2 that KP number
        *get,k2,line,ln2,kp,2
    *endif
    !
    ksel,selv,kp,,kset1
    !
    create_cs,1,'p1cs',0,kmin,k1,pc ! create 1st c.s. using k1 for x direction
    !
    ksel,s,kp,,kset2            ! select KP's of kset2
    *get,k2max,kp,,num,max      ! retrieve MAX KP number in kset2
    ksel,a,kp,,k1               ! reselect k1 and k2
    ksel,a,kp,,k2
    !
    ksel,selv,kp,,kset1
    !
    *if,kz(k2max),gt,0,then             ! if z position of k2max is positive, then
        create_cs,1,'p1cs',0,kmin,k2,pc ! recreate c.s. using k2 for x direction
    *endif
*else
    init_entity_num
    !
    asel,selv,area,,a2bcut      ! select all entities of a2bcut
    lsel,selv,line,,lset1
    ksel,selv,kp,,kset1
    !
    create_cs,1,'p1cs',0,p1od,p2od,pc
*endif
!
!-- C. ------------------- Create Keypoint C.S.'s ---------------------
!
init_entity_num
!
asel,selv,area,,a2bcut          ! select all entities of a2bcut
lsel,selv,line,,lset1
ksel,selv,kp,,kset1
!
*get,kcount,kp,,count           ! number of keypoints in a2bcut
!
max_enty_dim,'l'                ! retrieve MAX line length
!
*do,i,1,kcount,1
    !
    j=i+1
    m=i+2
    !
    csys,p%i%cs
    !
    ksel,r,loc,x,0              ! retrieve KP at c.s. origin
    ksel,r,loc,y,0
    ksel,r,loc,z,0
    *get,k%i%,kp,,num,max
    !
    ksel,s,kp,,kset1            ! reselect KP's of kset1
    !
    lsel,r,loc,x,0,1.2*max_leng ! select line along x axis of p%i%cs
    lsel,r,loc,y,0
    !
    *get,lnum,line,,num,max
    !
    lsel,s,line,,lset1          ! reselect lines of lset1
    !
    *get,k%j%,line,lnum,kp,1        ! check that 2nd KP of line 2 is
    *if,k%j%,eq,k%i%,then           ! not kmin and assign k2 that KP
        *get,k%j%,line,lnum,kp,2    ! number
    *endif
    !
    ksel,r,kp,,k%j%             ! select 2nd kp to set up c.s. on
    lslk,r,0                    ! select lines attached to kmin
    *get,ln1,line,,num,min      ! retieve lines ln1 and ln2
    *get,ln2,line,,num,max
    !
    *if,ln1,ne,lnum,then        ! assign to 'lnum' the line 'ln1' or 'ln2'
        lnum=ln1                ! that is not equal to 'lnum'
    *else
        lnum=ln2
    *endif
    !
    ksel,selv,kp,,kset1         ! reselect KP's of kset1
    !
    lsel,r,line,,lnum           ! select keypoints associated with 'lnum
    ksll,r
    *get,k1lnum,kp,,num,min
    *get,k2lnum,kp,,num,max
    !
    *if,k1lnum,ne,k%j%,then     ! assign to 'k%m%' the KP 'k1lnum'
        k%m%=k1lnum             ! or 'k2lnum' that is not equal to 'k%j%'
    *else
        k%m%=k2lnum
    *endif
    !
    ksel,selv,kp,,kset1         ! reselect KP's of kset1
    !
    create_cs,1,'p%j%cs',0,k%j%,k%m%,pc ! create next c.s.
    !
    asel,selv,area,,a2bcut      ! select all entities of a2bcut
    lsel,selv,line,,lset1
    ksel,selv,kp,,kset1
    !
*enddo
!
asel,selv,area,,a2bcut          ! select all entities of a2bcut
lsel,selv,line,,lset1
ksel,selv,kp,,kset1
!
!-- D. --------------------- Create Area Profile ----------------------
!
*do,i,1,kcount,1
    !
    j=i+1
    m=i-1
    !
    csys,p%i%cs
    !
    k,,-0.5*max_leng,wall_thk,0
    k,,1.5*max_leng,wall_thk,0
    !
    *get,km,kp,,num,max
    !
    lstr,km,km-1
    !
    csys,p%j%cs
    !
    k,,-0.5*max_leng,wall_thk,0
    k,,1.5*max_leng,wall_thk,0
    !
    *get,km,kp,,num,max
    !
    lstr,km,km-1
    !
    init_entity_num
    !
    lsbl,lm-1,lm,,delete,delete
    !
    init_entity_num
    !
    p%i%=km
    !
    ldele,lm-1,lm,1
    !
    init_entity_num
    !
    *if,i,gt,1,then
        lstr,p%m%,p%i%
    *endif
    !
*enddo
!
pdrgl=%p1%              ! point of origin for the drag line
!
init_entity_num
!
lsel,selv,line,,lm-(kcount-2),lm
ksll,selv
!
nummrg,kp,.001,.001
!
al,all
!
init_entity_num
!
!-- E. ------------------ Perform Boolean Operation -------------------
!
*if,offset,eq,'normal',then
    !
    voffst,am,-dcut_n
    !
    init_entity_num
    !
    vsbv,vset1,vm,,delete,delete
    !
    init_entity_num
    !
    lplot
    !
*elseif,offset,eq,'skew',then
    !
    *if,dcut_s,eq,0,then
        !
        x=dcut_n*tan(phi_xz*rconv)
        c=sqrt((dcut_n**2)+(x**2))
        y=c*tan(phi_elev*rconv)
        z=dcut_n
        !
        csys,p1cs
        !
        create_cs,0,,0,kx(pdrgl),ky(pdrgl),kz(pdrgl),0,0,0
        !
        k,,x,y,-z
        !
        init_entity_num
        !
        lstr,pdrgl,km
        !
        init_entity_num
        !
        vdrag,am,,,,,,lm
        ldele,lm
        !
        init_entity_num
        !
        vsbv,vset1,vm,,delete,delete
        !
        init_entity_num
        !
        lplot
    *else
        y=dcut_s*sin(phi_elev*rconv)
        c=dcut_s*cos(phi_elev*rconv)
        x=c*sin(phi_xz*rconv)
        z=c*cos(phi_xz*rconv)
        !
        csys,p1cs
        !
        create_cs,0,,0,kx(pdrgl),ky(pdrgl),kz(pdrgl),0,0,0
        !
        k,,x,y,-z
        !
        init_entity_num
        !
        lstr,pdrgl,km
        !
        init_entity_num
        !
        vdrag,am,,,,,,lm
        ldele,lm
        !
        init_entity_num
        !
        vsbv,vset1,vm,,delete,delete
        !
        init_entity_num
        !
        lplot
    *endif
*endif
!
!-- E. ---------------------- Undefine Parameters ---------------------
!
init_entity_num
!
*do,i,2,(kcount+1),1
    csdele,p%i%cs
    *set,p%i%,
    *set,p%i%cs,
*enddo
!
*set,wall_thk,
*set,offset,        ! undefine parameters that may be used in
*set,dcut_s,        ! future macro calls
*set,dcut_n,
*set,phi_xz,
*set,phi_elev,
*set,ovr_dir,
*set,pdrgl,
*set,p1od,
*set,p2od,
*set,kcount,

*if,prkey_,eq,1,then
    /go
*endif