!   TITLE:  opposite_side.mac (MESH)
!
!
!   OBJECTIVE:
!
!   This sub-macro tests and finds opposite sides to an area or volume.
!
!
!   COMMAND SYNTAX:
!
!                        (1)     (2)    (3)
!       OPPOSITE_SIDE, ent_typ, area#, vol#
!
!
!   ARGUMENTS:
!
!       (1) ent_typ = entity type:
!
!               a.) 'a' = area. Find opposite sides to area specified in
!                               argument 2. Argument 3 is not applicable.
!                               (area must have 4 sides to have opposite
!                                sides)
!
!               b.) 'v' = volume. Find the area opposite the area specified
!                                 in argument 2 on a specified volume. If
!                                 specified area (argument 2) is attached
!                                 to only 1 volume, then argument 3 may be
!                                 ignored.
!
!       (2) area# = area number:
!
!               a.) ent_typ = 'a' : the opposite sides of the specified area
!                                   are determined. (area must have 4 sides)
!
!               b.) ent_typ = 'v' : the surface (area) opposite this area
!                                   attached to the volume specified in
!                                   argument 3.
!
!       (3) vol# = volume number:
!
!               a.) ent_typ = 'a' : Not applicable. This argument is ignored.
!
!               b.) ent_typ = 'v' : If the area specified in argument 2 is
!                                   attached to more than 1 volume, then this
!                                   argument specifies the volume # in which
!                                   to find the opposite side.
!
!
!   DESCRIPTION:
!
!   If the opposite sides of an area are desired, then the 1st argument must be
!   an 'a'. If the opposite surface (area) of a volume is desired, then the 1st
!   argument must be a 'v'.
!
!   If the opposite sides of an area are desired (ent_typ = 'a'), then the area
!   must have exactly 4 sides. Otherwise, it is ignored.
!
!   If the opposite surface (area) of a volume is desired (ent_typ = 'v'), then
!   the algorithm finds the area opposite the area specified in argument 2. If
!   the area of argument 2 is attached to 2 volumes, then the desired volume in
!   which to determine the opposite surface must be specified in argument 3. If
!   the specified area is only attached to 1 volume, then argument 3 need not be
!   specified.
!
!   If the opposite side (area) of a volume is desired, the volume must have the
!   geometric condition that at least one pair of its sides has keypoints, and
!   therefore edges, that map (or extrude) to each other directly, with no breaks
!   in its mapping (extrude) path. The opposite sides will therefore have the same
!   number of sides, and therefore the same number of points at which the opposite
!   sides are attached with a single line at each pair of corresponding points.
!
!
!
!
*get,prkey_,active,0,prkey
/nopr
!
configuration,0,1
!
enttyp__=arg1
anum__=arg2
vnum__=arg3
!
*if,enttyp__,eq,'a',then
    *set,alnset_(1),
    !
    asel,s,area,,anum__
    lsla,s
    ksll,s
    cm,alset_,line
    !
    ln_cg
    arry_transfer,'lcg_data','alnset_'
    !
    nsides_=num_lns
    !
    *if,num_lns,eq,4,then
        arry_min_val,'alnset_',,,2,2
        arry_max_val,'alnset_',,,2,2
        !
        ln1__=alnset_(min_ir,1)         ! line 1 of 1st opposite pair
        ln1l__=alnset_(min_ir,2)        ! length of line 1 of 1st opposite pair
        !
        alnset_(min_ir,2)=max_val+1
        !
        lsel,r,line,,ln1__
        ksll,s
        cm,kln1__,kp
        !
        cmsel,s,alset_
        cmsel,s,kln1__
        lslk,u,0
        get_max_entity
        !
        lopp1__=lm                      ! line opposite line 1
        !
        arry_search,'alnset_',lopp1__,,,1,1
        row_=hit(1,1)
        !
        lopp1l__=alnset_(row_,2)        ! length of line opposite line 1
        !
        alnset_(row_,2)=max_val+1
        !
        arry_min_val,'alnset_',,,2,2
        !
        ln2__=alnset_(min_ir,1)         ! line 1 of 2nd opposite pair
        ln2l__=alnset_(min_ir,2)        ! length of line 1 of 2nd opposite pair
        !
        cmsel,s,alset_
        lsel,u,line,,ln1__
        lsel,u,line,,lopp1__
        lsel,u,line,,ln2__
        get_max_entity
        !
        lopp2__=lm                      ! line opposite line 2
        !
        arry_search,'alnset_',lopp2__,,,1,1
        row_=hit(1,1)
        !
        lopp2l__=alnset_(row_,2)        ! length of line opposite line 2
        !
        l_shrt1=ln1__               ! line # of short line in pair 1
        l_long1=lopp1__             ! line # of long line in pair 1
        !
        l_shrt2=ln2__               ! line # of short line in pair 2
        l_long2=lopp2__             ! line # of long line in pair 2
        !
        !
        ln_shrt1=ln1l__             ! length of short line in pair 1
        ln_long1=lopp1l__           ! length of long line in pair 1
        !
        ln_shrt2=ln2l__             ! length of short line in pair 2
        ln_long2=lopp2l__           ! length of long line in pair 2
        !
        *set,lopp1__,
        *set,ln2__,
        *set,lopp2__,
        *set,lopp1l__,
        *set,ln2l__,
        *set,lopp2l__,
    *elseif,num_lns,eq,3,then
        arry_min_val,'alnset_',,,2,2
        arry_max_val,'alnset_',,,2,2
        !
        l_shrt1=alnset_(min_ir,1)         ! line # of shortest line
        ln_shrt1=alnset_(min_ir,2)        ! length of shortest line
        !
        l_long1=alnset_(max_ir,1)         ! line # of longest line
        ln_long1=alnset_(max_ir,2)        ! length of longest line
    *else
        mshtyp_='free'
    *endif
    !
    n_sides=nsides_
    !
    cmdele,alset_
    cmdele,kln1__
    *set,alnset_(1),
    *set,hit(1),
    *set,ln1__,
    *set,ln1l__,
    *set,min_ir,
    *set,min_ic,
    *set,min_ip,
    *set,min_val,
    *set,max_ir,
    *set,max_ic,
    *set,max_ip,
    *set,max_val,
    *set,nsides_,
*elseif,enttyp__,eq,'v',then
    a_cg,anum__
    asel,s,area,,anum__
    !
    *if,acg_data(1,3),gt,0,and,acg_data(1,5),gt,0,then
        vsla,s,0
        !
        *if,vnum__,gt,0,then
            vsel,r,volu,,vnum__
            abort__=0
        *else
            abort__=1
            aoppcnt_=0
            a_oppose=-1
        *endif
    *elseif,acg_data(1,3),gt,0,and,acg_data(1,5),eq,0,then
        vsla,s,0
        abort__=0
    *elseif,acg_data(1,3),eq,0,and,acg_data(1,5),eq,0,then
        abort__=1
        aoppcnt_=0
    *endif
    !
    *if,abort__,eq,0,then
        aslv,s
        lsla,s
        ksll,s
        !
        cm,vkset__,kp           ! KP set associated with volume 'vnum__'
        cm,vlset__,line         ! LINE set associated with volume 'vnum__'
        cm,vaset__,area         ! AREA set associated with volume 'vnum__'
        !
        asel,s,area,,anum__
        lsla,s
        ksll,s
        *get,alcnt__,line,,count
        cm,alset__,line
        cm,akset__,kp           ! KP set associated with area 'anum__'
        !
        cmsel,s,vaset__
        cmsel,s,akset__
        cmsel,s,vlset__
        lslk,r,0
        asll,r,0
        cm,vaset2__,area        ! AREA set not associated with opposite area
        !
        cmsel,s,vaset__
        cmsel,u,vaset2__
        get_max_entity
        !
        *get,aoppcnt_,area,,count
        !
        *if,aoppcnt_,gt,1,then
            a_oppose=-1
        *elseif,aoppcnt_,eq,1,then
            a_oppose=am
        *endif
    *endif
    !
    *if,aoppcnt_,eq,1,then
        asel,s,area,,a_oppose
        lsla,s
        ksll,s
        *get,opplcnt_,line,,count
        !
        cm,aokset__,kp
        cm,aolset__,line
        !
        *if,opplcnt_,eq,alcnt__,then
            test1_=1
        *else
            test1_=0
        *endif
        !
        *if,test1_,eq,1,then
            cmsel,s,vlset__
            cmsel,u,alset__
            cmsel,u,aolset__
            cm,maplset_,line
            !
            ksll,s
            cm,mapkset_,kp
            !
            cmsel,u,akset__
            lslk,s,1
            asll,s,1
            get_max_entity
            !
            *get,achkcnt_,area,,count
            !
            *if,achkcnt_,eq,1,then
                *if,am,eq,a_oppose,then
                    a_oppose=am
                    test2_=1
                *else
                    test2_=0
                *endif
            *else
                test2_=0
            *endif
        *elseif,test1_,eq,0,then
            test2_=0
        *endif
        !
        *if,test1_,eq,1,and,test2_,eq,1,then
            a_oppose=a_oppose
        *else
            a_oppose=-1
        *endif
    *endif
    !
    cmdele,maplset_
    cmdele,mapkset_
    cmdele,kln1__
    cmdele,vkset__
    cmdele,vlset__
    cmdele,vaset__
    cmdele,alset__
    cmdele,akset__
    cmdele,vaset2__
    cmdele,aokset__
    cmdele,aolset__
    *set,test1_,
    *set,test2_,
    *set,achkcnt_,
    *set,opplcnt_,
    *set,alcnt__,
    *set,aoppcnt_,
    *set,abort__,
*endif
!
configuration,1,1
!
aplot
!
*set,enttyp__,
*set,anum__,
*set,vnum__,
!
*if,prkey_,eq,1,then
    /go
*endif