!*****************************************************************
! LGS_0517A   / 2015-03-12 / Vertex Systems                      *
!                                                                *
! Light Gauge Steel Track-Stud joint.                            *
!*****************************************************************

#UPDATE_JOINT#

!debug ./LGS_0517A_upd.dbg

! Get connecting objects

I= new_iterator("",0,"ROLED","THIS")
This = next_item(I)
if !This then exit

init_iterator(I) "",This,"CONNECTION_ROLEPARTS","PCE"
Piece = next_item(I)
if !Piece then exit

init_iterator(I) "",This,"CONNECTION_ROLEPARTS","END"
End = next_item(I)
if !End then exit
Pce= get_actual_piece(End)
if !Pce then exit

init_iterator(I) "",This,"CONNECTION_ROLEPARTS","OPTPCE"
OptPce = next_item(I)

Type$ = get_obj_param(This,"TYPE")
Type = Type$
End_Gap$ = get_obj_param(This,"ENDGAP")
End_Gap = End_Gap$
Full$ = get_obj_param(This,"FULLDIMPLE")
Full = Full$
Eshp$= get_obj_param(This,"ESHP")
Cd= get_obj_param(This,"RCD")
EshpLim= get_obj_param(This,"ESHP_LA")
EndMode = get_obj_param(This,"ENDMODE") 
MinEndDist= get_obj_param(This,"ENDDIST")
if (EndMode == 1) then End_gap= 0.0
!
! Truss tool and Notch diags are just to support customized libraries for a while
TrussTool$ = get_obj_param(This,"TRUSSTOOL")
TrussToolSize = get_obj_param(This,"TRUSSTOOLSIZE")
NotchDiags = get_obj_param(This,"NOTCHDIAGS")
!
! Check base piece validity
Shape$= get_material_param(Piece,"SHAPE")
if (!Type && !cmp(Shape$,"C") && !cmp(Shape$,"U")) then exit
if (Type == 1 && (!cmp(Shape$,"C"))) then exit
if (Type == 2 && (!cmp(Shape$,"U"))) then exit

Shape$= get_material_param(Pce,"SHAPE")
if !cmp(Shape$,"C") then exit
!
Hgt= get_section_param(Piece,"HEIGHT")
Hgt$ = Hgt
if findstr(TrussTool$,Hgt$) then
  TrussTool = 1
else
  TrussTool = 0
endif

Width= get_section_param(Piece,"WIDTH")
Width2= get_section_param(Piece,"WIDTH2",1)
AsymetricC = 0
if Width2 > 0 then AsymetricC = 1
Thick= get_section_param(Piece,"THICK")
!
WidthDiff= abs(Width-Width2)
!
SDP= 1; SDE= 2
P= 3; X= 4; Y= 5; Z= 6
PP= 7; PT= 8; PN= 9; PE= 10
PEP= 11; PEX= 12; PEY= 13; PEZ= 14
LPP= 15; LPE= 16; CPP= 17; CPE= 18
D= 19
PP= 20; PX= 21; PY= 22; PZ= 23
P2= 24; P3= 25
S= 26; E= 27; TP= 28
PP2= 29; PX2= 30; PY2= 31; PZ2= 32
X1= 33; X2= 34
Pnt1= 35; Pnt2 = 36
OP= 37
!
GeomP= 1
GeomE= 2
!
Ndepth= mm_to_dwg(Thick*2.0)
!
! Check piece cross section directions
get_piece_dir(SDP) Piece
get_piece_dir(SDE) Pce
Dot= vec_dot_prod(SDP,SDE)
Dot= abs(Dot)
if Dot < 0.999999 then exit
!
! Check connecting side and angle
get_origin_pos(End) P,X,Y,Z
get_origin_pos(Pce) PP2,PX2,PY2,PZ2
get_vxgeom(GeomP) Piece
point_to_vxgeom(PP) GeomP,P
get_vxgeom_tan(PT) GeomP,PP
vec_cross_prod(PN) PT,SDP
vec_cross_prod(OP) SDP,PT
Dot= vec_dot_prod(Z,PN)
Reversed = 0
if Dot < 0.10 then Reversed = 1
PerpJnt= 0
if Dot > 0.999999 then PerpJnt= 1
!
! Check if pieces meet each others
vec_sub(D) PP,P
Dot= vec_dot_prod(D,SDP)
if Dot < mm_to_dwg(-5) || Dot > mm_to_dwg(5) then
  exit
endif

get_origin_pos(Piece) PP,PX,PY,PZ
Dot= vec_dot_prod(PZ,Z)
Dot= abs(Dot)
Ang= acos(Dot)
!
! Check end shape based on limiting angle and end shape type
!
EndShape= 0
if !TrussTool then
  if cmp(Eshp$,"RND") then
    if Cd > 0.01 then
      EndShape= 2
    else
      EndShape= 1
    endif
  endif
  if (EndShape && EshpLim > 0.01 && EshpLim < 89.99 && Ang>EshpLim) then EndShape= 0
  if EndShape then NotchDiags= 0
endif
!
! Check critical point on connecting piece
get_vxgeom(GeomE) Pce
get_vxgeom_tan(PE) GeomE,P
if Reversed then
  Ip= 2
  Dot= vec_dot_prod(PX2,PN)
  if Dot < 0 then Ip= 8
else
  Ip= 8
  Dot= vec_dot_prod(PX2,PN)
  if Dot < 0 then Ip= 2
endif

if (EndShape == 1) then
  set_obj_param(This) "ESHP_F","1"

  ! Radius for rounding
  get_piece_localp(P) Pce,"IP",2
  Rad= -vec_get_x(P)

  ! Reference line
  if Reversed then
    get_piece_localp(P) Piece,"IP",8
    vec_to(PN) Thick+Rad+(AsymetricC*WidthDiff),0,0
    vec_rev(PN) PN
  else
    get_piece_localp(P) Piece,"IP",2
    vec_to(PN) Thick+Rad,0,0
  endif
  vec_add(P) P,PN
  get_piece_vxgeom(GeomP) Piece,P

  ! Line to trim
  get_vxgeom(GeomE) Pce
  if vxgeom_cross_pnts(GeomP,P,GeomE,PE) == 0 then exit

  ! End point
  vec_times_scalar(D) Z,Rad
  vec_add(PE) PE,D
  vec_copy(TP) PE
endif

if (EndShape == 2) then
  set_obj_param(This) "ESHP_F","2"

  ! Reference line
  if Reversed then
    get_piece_localp(P) Piece,"IP",8
    vec_to(PN) Thick+(AsymetricC*WidthDiff),0,0
    vec_rev(PN) PN
  else
    get_piece_localp(P) Piece,"IP",2
    vec_to(PN) Thick,0,0
  endif
  vec_add(P) P,PN
  get_piece_vxgeom(GeomP) Piece,P

  ! Line to trim
  get_piece_localp(P) Pce,"IP",2
  W2= abs(vec_get_x(P))
  if Cd > W2 then Cd= W2-mm_to_dwg(1)
  Ext= 0
  if abs(Ang > 45) then
    if Cd > W2 then Cd= W2
    Off= W2-Cd
  else
    Ext= Cd
    Off= W2
  endif
  if Ip == 2 then Off= -Off
  vec_to(P) Off,0,0

  get_piece_vxgeom(GeomE) Pce,P
  if vxgeom_cross_pnts(GeomP,P,GeomE,PE) == 0 then exit
  vec_times_scalar(D) Z,Ext
  vec_add(PE) P,D
  vec_copy(TP) PE
endif

if (EndShape == 0) then
  set_obj_param(This) "ESHP_F","0"

  ! Reference line
  if Reversed then
    get_piece_localp(P) Piece,"IP",8
    vec_to(PN) Thick+(AsymetricC*WidthDiff),0,0
    vec_rev(PN) PN
  else
    get_piece_localp(P) Piece,"IP",2
    vec_to(PN) Thick,0,0
  endif
  vec_add(P) P,PN
  get_piece_vxgeom(GeomP) Piece,P

  ! Line to trim
  get_piece_localp(P) Pce,"IP",Ip
  if TrussTool && Ang < 80 then
    vec_to(PN) TrussToolSize,0,0
    if Ip == 2 then
      vec_add(P) P,PN
    else
      vec_sub(P) P,PN
    endif
  endif

  if NotchDiags then
    vec_to(PN) Ndepth,0,0
    if Ip == 2 then
      vec_add(P) P,PN
    else
      vec_sub(P) P,PN
    endif
  endif

  get_piece_vxgeom(GeomE) Pce,P
  if vxgeom_cross_pnts(GeomP,P,GeomE,PE) == 0 then exit
  vec_copy(TP) P

  if TrussTool && Ang < 45 then
    if Ip == 2 then
      vec_rev(D) PX2
    else
      vec_copy(D) PX2
    endif

    vec_times_scalar(D) D,TrussToolSize
    vec_add(X1) P,D
    vec_rev(D) Z
    vec_times_scalar(D) D,TrussToolSize
    vec_add(X1) X1,D

    get_piece_localp(P) Piece,"IP",2

    vec_to(PN) Thick,0,0
    vec_add(P) P,PN
    get_piece_vxgeom(GeomP) Piece,P
    get_piece_localp(P) Pce,"IP",Ip
    get_piece_vxgeom(GeomE) Pce,P
    if vxgeom_cross_pnts(GeomP,X2,GeomE,X2) == 0 then exit

    vec_sub(D) X1,X2
    gap = vec_len(D)
    End_Gap = End_Gap + gap
  endif
endif

! Fully trimmed end point for piece
get_vxgeom(GeomE) Pce
point_to_vxgeom(P) GeomE,PE

! Calculate max length of piece that crosses track if not perpendicular
! Calculate left point
if Reversed then
  get_piece_localp(P2) Piece,"IP",8
else
  get_piece_localp(P2) Piece,"IP",2
endif
vec_to(PN) Width,0,0
vec_add(P2) P2,PN
get_piece_vxgeom(GeomP) Piece,P2
get_piece_localp(P2) Pce,"IP",Ip
get_piece_vxgeom(GeomE) Pce,P2
if vxgeom_cross_pnts(GeomP,P2,GeomE,PE) == 0 then exit

! Calculate right point
if Ip == 8 then
  Ip = 2
else
  if Ip == 2 then
    Ip = 8
  endif
endif

vec_copy(TP) P
Dot= vec_dot_prod(PX,Z)
EndGap= End_Gap/abs(Dot)
vec_times_scalar(D) Z,EndGap
vec_sub(P) P,D

if (piece_move_end(End,P,1) != 1) then exit

GeomPiece = 1
GeomPce = 2

get_vxgeom(GeomPiece) Piece
get_vxgeom(GeomPce) Pce

if vxgeom_cross_pnts(GeomPiece,Pnt1,GeomPce,Pnt2) == 0 then exit

set_joint_pos(This) Pnt1,X,Y,Z
vec_to(D) 0,0,0
set_piece_rotpnt(This) End,D

if (EndMode == 1) then 
  End_Gap= get_joint_param(This,"ENDGAP")
  vec_sub(D) Pnt1,TP
  CurrDist = vec_len(D)
  if (MinEndDist > CurrDist - End_Gap) then MinEndDist= CurrDist - End_Gap
  vec_times_scalar(D) Z,MinEndDist
  vec_add(P) Pnt1,D
  if (piece_move_end(End,P,1) != 1) then exit
endif

! Check optional piece position
if (OptPce) then
  GeomA = 3
  get_vxgeom(GeomA) OptPce
  point_to_vxgeom(Pnt1) GeomA,P
  get_vxgeom_tan(D) GeomA,Pnt1
  vec_copy(PZ) D
  get_piece_dir(SDE) OptPce
  vec_cross_prod(D) SDE,D

  Ok = 1
  ! Check parallel
  Dot = vec_dot_prod(PT,PZ)
  if (abs(Dot) < 0.999) then Ok = 0

  ! Check opening dir
  Dot = vec_dot_prod(OP,D)
  if (Dot > -0.999) then Ok = 0

  ! Check joint pos on adapted piece
  Ok2 = is_in_vxgeom(GeomA,Pnt1,0,mm_to_dwg(1.0))
  if (!Ok2) then Ok = 0

  ! Check pieces are close
  point_to_vxgeom(Pnt2) GeomP,Pnt1
  vec_sub(D) Pnt2,Pnt1
  Len = vec_len(D)
  if (Len > mm_to_dwg(5.0)) then Ok = 0

  if (!Ok) then disconnect_c(This) OptPce
endif

set RETURN "1"

#UPDATE_JOINT#

#JOINT_TEST#

!debug ./LGS_0517A_tst_dbg

I = new_iterator("",0,"ROLED","THIS")
This = next_item(I)
if (!This) then exit
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","PCE"
Pce= next_item(I)
if (!Pce) then exit

get_joint_pnt(1) This
get_vxgeom(1) Pce
point_to_vxgeom(1) 1,1
if (is_in_vxgeom(1,1,0,mm_to_dwg(9.99)) = 0) then exit

set RETURN "1"

#JOINT_TEST#

#JOINT_DETAILING#

!debug ./LGS_0517A_det_dbg

I= new_iterator("",0,"ROLED","THIS")
This = next_item(I)
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","PCE"
Pce = next_item(I)
if !Pce then exit
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","END"
End= next_item(I)
if !End then exit
Pce2= get_actual_piece(End)
if !Pce2 then exit
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","OPTPCE"
OptPce = next_item(I)

COMMONNOTCH$=    "120"
COMMONLIPNOTCH$= "121"

Cd= get_obj_param(This,"RCD")
Type$ = get_obj_param(This,"TYPE")
Type = Type$
LipCutLen$ = get_obj_param(This,"LIPCUTLEN")
LipCutLen = LipCutLen$
NotchLen = get_obj_param(This,"NOTCHLEN")
NotchLen$ = NotchLen
SwageLen$ = get_obj_param(This,"SWAGELEN")
SwageLen = SwageLen$
NoSwage = get_obj_param(This,"NOSWAGE")
TrussTool$ = get_joint_param(This,"TRUSSTOOL")
TrussToolSize = get_joint_param(This,"TRUSSTOOLSIZE")
NotchDiags = get_obj_param(This,"NOTCHDIAGS")
DOffset = get_obj_param(This,"DOFFSET")

! Get parameters from piece material
if (LipCutLen < mm_to_dwg(0.001)) then
  LipCutLen$= get_material_param(Pce,"NC.LIPCUTLEN")
  LipCutLen = LipCutLen$
endif
if (NotchLen < mm_to_dwg(0.001)) then
  NotchLen$= get_material_param(Pce,"NC.NOTCHLEN")
  NotchLen = NotchLen$
endif
if (SwageLen < mm_to_dwg(0.001)) then
  SwageLen$= get_material_param(Pce,"NC.SWAGELEN")
  SwageLen = SwageLen$
endif
if (DOffset < mm_to_dwg(0.001)) then
  DOffset$= get_material_param(Pce,"NC.DIMPLE_OFFSET")
  DOffset = DOffset$
endif

StudLipcutGap = get_obj_param(This,"EXTRALIPLEN")
TrackSwageGap = mm_to_dwg(3.0)

JP= 1
JX= 2
JY= 3
JZ= 4
PP= 5
PX= 6
PY= 7
PZ= 8
EP= 9
EX= 10
EY= 11
EZ= 12
P= 13
X= 14
Y= 15
Z= 16
D= 17
PP2= 18
PX2= 19
PY2= 20
PZ2= 21
PE = 22
PT = 23
D2 = 24
NP1 = 25
NP2 = 26
OP = 27
OP2 = 28
SP = 29
PP3= 30
DP = 31
DP2 = 32
PN = 33

GeomE = 1
GeomP = 2

reversed = 0
TrackReversed = 0
!
get_origin_pos(This) JP,JX,JY,JZ
get_origin_pos(Pce) PP,PX,PY,PZ
get_origin_pos(End) EP,EX,EY,EZ
get_origin_pos(Pce2) PP2,PX2,PY2,PZ2
!
get_piece_localp(P) Pce,"IP",2
vec_to(PN) DOffset,0,0
vec_add(P) P,PN
get_piece_vxgeom(GeomP) Pce,P

get_piece_localp(P) Pce2,"IP",2
vec_to(PN) DOffset,0,0
vec_add(P) P,PN
get_piece_vxgeom(GeomE) Pce2,P
if vxgeom_cross_pnts(GeomP,DP,GeomE,DP2) == 0 then exit
!
DimP= get_section_param(Pce,"HEIGHT")
DimP$ = DimP
Shape$= get_material_param(Pce,"SHAPE")

if findstr(TrussTool$,DimP$) then
  TrussTool = 1
else
  TrussTool = 0
endif

EshpFeat = 0;
if (!TrussTool) then
  EshpFeat= get_obj_param(This,"ESHP_F")
endif

Width= get_section_param(Pce,"WIDTH")
Width2= get_section_param(Pce2,"WIDTH") * 2.0
Thck = get_section_param(Pce,"THICK")
Thck2 = get_section_param(Pce2,"THICK")
SwDim= Thck/2
if (cmp(Shape$,"U")) then SwDim= Thck
Ndepth= mm_to_dwg(Thck*2.0)
!
! Check connecting angle
Dot= vec_dot_prod(PZ,EZ)
if Dot < 0 then Dot= -Dot
Ang= acos(Dot)

Dot = vec_dot_prod(PX,PZ2)

if Dot < 0 then
  vec_copy(D) PZ2
  vec_rev(D) D
else
  vec_copy(D) PZ2
endif

! Check critical point on connecting piece
get_vxgeom(GeomP) Pce
point_to_vxgeom(PP) GeomP,P
get_vxgeom_tan(PT) GeomP,PP
get_piece_dir(D) Pce
vec_cross_prod(OP) D,PT

get_vxgeom(GeomE) Pce2
get_vxgeom_tan(PE) GeomE,EP
Dot= vec_dot_prod(PE,PT)

if Dot < 0 then
  ReverseScrewDir = 1
endif

Dot= vec_dot_prod(PX,EZ)
if Dot > 0 then
  TrackReversed = 1
endif

! Set rounded end
Rnd= 0
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","RND"
Rnd= next_item(I)
if !EshpFeat then
  if (Rnd) then
   disconnect(Rnd)
   del_object(Rnd)
  endif
else
  if (!Rnd) then
    if EshpFeat == 2 then
      Rnd= new_feature("PCEND_RND",0,0,"RndEndT2","2","2")
      set_obj_param(Rnd) "CD",Cd,1+2
    else
      Rnd= new_feature("PCEND_RND",0,0,"RndEndT1_V1","2","1")
    endif
    if (!Rnd) then exit
    connect(This) Rnd,"RND"
    add_sobj(Pce2) Rnd
  endif
  set_origin_pos(Rnd) EP,EX,EY,EZ
endif

! Set male counterforms
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","M"
Count1= 0
Count2= 0
vec_copy(Z) PY
ToCopy= 0
loop
  Hole= next_item(I)
  exitif !Hole
  if (!ToCopy) then ToCopy= Hole
  if DOffset then
    vec_copy(P) DP
  else
  vec_copy(P) JP
  endif
  if !proj_to_piece(P,X,P,Z,Pce,0.0,0) then exit
  vec_copy(X) PZ
  vec_cross_prod(Y) Z,X
  set_origin_pos(Hole) P,X,Y,Z
  vec_rev(Z) Z
  Count1= Count1+1
endloop

Count3= 0
vec_copy(Z) PY
if (OptPce) then
  init_iterator(I) "",This,"CONNECTION_ROLEPARTS","OPTM"
  loop
    Hole= next_item(I)
    if (!Hole && ToCopy && Count3 < 2) then
      Hole= copy_object(ToCopy)
      connect(This) Hole,"OPTM",1
      add_sobj(OptPce) Hole
    endif
    exitif (!Hole || Count3 > 1)
    if DOffset then
      vec_copy(P) DP
    else
    vec_copy(P) JP
    endif
    if !proj_to_piece(P,X,P,Z,OptPce,0.0,0) then exit
    vec_copy(X) PZ
    vec_cross_prod(Y) Z,X
    set_origin_pos(Hole) P,X,Y,Z
    vec_rev(Z) Z
    Count3= Count3+1
  endloop
else
  init_iterator(I) "",This,"CONNECTION_ROLEPARTS","OPTM"
  loop
    Hole= next_item(I)
    exitif (!Hole)
    disconnect(Hole)
    del_object(Hole)
  endloop
endif

! Set female counterforms
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","F"
vec_copy(Z) PY
loop
  Hole= next_item(I)
  exitif !Hole
  if DOffset then
    vec_copy(P) DP
  else
  vec_copy(P) JP
  endif
  vec_copy(X) PZ
  vec_cross_prod(Y) Z,X
  ! Dimple slot
  Type$ = get_obj_param(Hole,"TYPE")
  if (cmp(Type$,"4")) then
    vec_copy(P) EP
    vec_copy(Y) EZ
    vec_cross_prod(X) Z,Y
    DimY = get_obj_param(Hole,"DIMY")
    vec_times_scalar(D) EZ,-DimY/2.0
    vec_add(P) P,D
  endif
  if !proj_to_piece(P,D,P,Z,Pce2,0.0,0) then exit
  set_origin_pos(Hole) P,X,Y,Z
  vec_rev(Z) Z
  Count2= Count2+1
endloop
if Count1 != Count2 then exit

! Set female counterforms
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","F2"
vec_copy(Z) PY
loop
  Hole= next_item(I)
  exitif !Hole
  if DOffset then
    vec_copy(P) DP
  else
  vec_copy(P) JP
  endif
  vec_copy(X) PZ
  vec_cross_prod(Y) Z,X
  ! Dimple slot
  Type$ = get_obj_param(Hole,"TYPE")
  if (cmp(Type$,"4")) then
    vec_copy(P) EP
    vec_copy(Y) EZ
    vec_cross_prod(X) Z,Y
    DimY = get_obj_param(Hole,"DIMY")
    vec_times_scalar(D) EZ,-DimY/2.0
    vec_add(P) P,D
  endif
  if !proj_to_piece(P,D,P,Z,Pce2,0.0,0) then exit
  set_origin_pos(Hole) P,X,Y,Z
  vec_rev(Z) Z
  Count3= Count3+1
endloop
if Count2 != Count3 then exit

! Lipcut length
get_piece_dir(D) Pce2
vec_cross_prod(OP2) D,PE
Dot= vec_dot_prod(OP,PE)
if !TrackReversed then
  if (Dot < 0.0) then vec_rev(PE) PE
else
  Dot= vec_dot_prod(PX2,EX)
  if (Dot > 0.0) then vec_rev(PE) PE
endif
Loop0= 0
loop 2
  Offset= 0
  Dot= vec_dot_prod(OP,OP2)
  if (Dot > 0.0) then Offset= Thck
  Ok= proj_to_piece(PP,D2,EP,OP2,Pce2,0,1)
  Ok= proj_to_piece(PP,D2,PP,PE,Pce,-Offset,1)
  if TrackReversed then
    if (Dot > 0.0) then
      ! Swage point
      point_to_piece(SP) Pce2,PP
    else
      vec_times_scalar(D) OP,Thck
      vec_add(PP) PP,D
    endif
  else
    if (Dot > 0.0) then
      vec_times_scalar(D) OP,Thck
      vec_add(PP) PP,D
    else
      ! Swage point
      point_to_piece(SP) Pce2,PP
    endif
  endif

  if (!Loop0) then
    vec_copy(NP1) PP
  else
    vec_copy(NP2) PP
  endif

  vec_rev(OP2) OP2
  Loop0= 1
endloop

vec_sub(D) NP2,NP1
Len= vec_len(D)
if (Len > LipCutLen) then LipCutLen= Len + StudLipcutGap
LipCutLen$= LipCutLen:N?.2
if (Len > NotchLen) then NotchLen= Len + StudLipcutGap
NotchLen$= NotchLen:N?.2

! Set lipcut place
vec_times_scalar(D) D,0.5
vec_add(PP) NP1,D
vec_times_scalar(D) OP,-Thck*2
if TrackReversed then
  vec_sub(P) PP,D
else
  vec_add(P) PP,D
endif

! Lipcut
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","N"
Notch= next_item(I)
if (cmp(Shape$,"U") && Notch) then
  disconnect(Notch)
  del_object(Notch)
  Notch= 0
endif
if (cmp(Shape$,"C") && !Notch) then
  Notch= new_feature("LNOTCH","0")
  if (!Notch) then exit
  add_sobj(Pce) Notch
  connect(This) Notch,"N",1
endif
if (Notch) then
  if TrackReversed then
    set_obj_param(Notch) "CUSTOM_TYPE",COMMONNOTCH$
  else
    set_obj_param(Notch) "CUSTOM_TYPE",COMMONLIPNOTCH$
  endif

  vec_rev(D) JZ
  if vec_dot_prod(D,JZ) < 0 then vec_rev(D) D
  vec_copy(Z) PX
  if vec_dot_prod(Z,JZ) > 0 then vec_rev(Z) Z
  vec_copy(Y) PZ
  vec_cross_prod(X) Y,Z
  set_origin_pos(Notch) P,X,Y,Z
  set_obj_param(Notch) "W",LipCutLen$
  Dim$= DimP
  set_obj_param(Notch) "DIM",Dim$
  set_obj_param(This) "IGNORE_FEATURE_DESIGN","1",1,Notch
  set_obj_param(This) "WORKS_IN_DESIGN","1",0,0
endif

! Optional piece notch
if (OptPce) then
  init_iterator(I) "",This,"CONNECTION_ROLEPARTS","OPTN"
  Notch= next_item(I)
  if (!Notch) then
    Notch= new_feature("LNOTCH",COMMONNOTCH$,"0")
    if (!Notch) then exit
    add_sobj(OptPce) Notch
    connect(This) Notch,"OPTN",1
  endif
  set_origin_pos(Notch) P,X,Y,Z
  set_obj_param(Notch) "W",NotchLen$
  Dim$= DimP
  set_obj_param(Notch) "DIM",Dim$
  set_obj_param(This) "IGNORE_FEATURE_DESIGN","1",1,Notch
  set_obj_param(This) "WORKS_IN_DESIGN","1",0,0
else
  init_iterator(I) "",This,"CONNECTION_ROLEPARTS","OPTN"
  Notch= next_item(I)
  if (Notch) then
    disconnect(Notch)
    del_object(Notch)
  endif
endif
!
! Swage length
vec_sub(D) SP,EP
Len= vec_len(D)
if (Len > SwageLen) then SwageLen= Len + TrackSwageGap

Hgt= get_section_param(Pce2,"HEIGHT")
if (DimP - Thck*2 + mm_to_dwg(0.001) > Hgt) then NoSwage= 1

! Set swage place
init_iterator(I) "",This,"CONNECTION_ROLEPARTS","S"
Swage= next_item(I)
if (!NoSwage && !Swage) then
  Swage= new_notch_feature("SWAGE","0","0")
  if (!Swage) then exit
  Dim$= mm_to_dwg(10)
  set_obj_param(Swage) "DIM",Dim$
  add_sobj(Pce2) Swage
  connect(This) Swage,"S",1
endif
if (NoSwage && Swage) then
  disconnect(Swage)
  del_object(Swage)
  Swage= 0
endif
if (Swage) then
  vec_times_scalar(D) EZ,-SwageLen/2
  vec_add(P) EP,D
  set_origin_pos(Swage) P,EX,EY,EZ
  Lz= SwageLen
  Lz$= Lz
  set_obj_param(Swage) "LZ",Lz$
  Ly= DimP-SwDim*2
  Ly$= Ly
  Lx$= Width2
  set_obj_param(Swage) "LY",Ly$
  set_obj_param(Swage) "LX",Lx$
endif

! Set 45 degree notch
if TrussTool then
  init_iterator(I) "",This,"CONNECTION_ROLEPARTS","C"
  Camf= next_item(I)
  if Ang > 80.01 then
    if Camf then
      disconnect(Camf)
      del_object(Camf)
    endif
  else
    if !Camf then
      Camf= new_feature("CUT","0")
      if Camf then
        connect(This) Camf,"C"
        add_sobj(Pce2) Camf
      endif
    endif
    if !Camf then exit
    if vec_dot_prod(EZ,PZ) > 0 then
      vec_rev(D) PZ
    else
      vec_copy(D) PZ
    endif
    if vec_dot_prod(EX,D) > 0 then
      vec_copy(D) EX
    else
      vec_rev(D) EX
    endif
    if !proj_to_piece(P,X,EP,D,Pce2,0,1) then exit
    vec_times_scalar(X) D,TrussToolSize
    vec_sub(P) P,X
    vec_add(Z) D,EZ
    vec_unit(Z) Z
    vec_copy(Y) EY
    vec_cross_prod(X) Y,Z
    set_origin_pos(Camf) P,X,Y,Z
  endif

  Camf= next_item(I)
  if Ang > 80.01 then
    if Camf then
      disconnect(Camf)
      del_object(Camf)
    endif
  else
    if !Camf then
      Camf= new_feature("CUT","0")
      if Camf then
        connect(This) Camf,"C"
        add_sobj(Pce2) Camf
      endif
    endif
    if !Camf then exit
    if vec_dot_prod(EZ,PZ) > 0 then
      vec_copy(D) PZ
    else
      vec_rev(D) PZ
    endif
    if vec_dot_prod(EX,D) > 0 then
      vec_rev(D) EX
    else
      vec_copy(D) EX
    endif
    vec_rev(D) D
    if !proj_to_piece(P,X,EP,D,Pce2,0,1) then exit
    vec_times_scalar(X) D,TrussToolSize
    vec_sub(P) P,X
    vec_add(Z) D,EZ
    vec_unit(Z) Z
    vec_copy(Y) EY
    vec_cross_prod(X) Y,Z
    vec_rev(X) X
    set_origin_pos(Camf) P,X,Y,Z
  endif
endif

if (NotchDiags) then
  LipCutLen= SwageLen

  init_iterator(I) "",This,"CONNECTION_ROLEPARTS","ND"
  Notch= next_item(I)
  if Ang > 80.01 then
    if Notch then
      disconnect(Notch)
      del_object(Notch)
    endif
  else
    if vec_dot_prod(EZ,PZ) > 0 then
      vec_rev(D) PZ
    else
      vec_copy(D) PZ
    endif
    if vec_dot_prod(EX,D) > 0 then
      if vec_same(EX,PX2,mm_to_dwg(0.1)) then
        reversed = 1
      else
        reversed = 0
      endif
      vec_copy(D) EX
    else
      if vec_same(EX,PX2,mm_to_dwg(0.1)) then
        reversed = 0
      else
        reversed = 1
      endif
      vec_rev(D) EX
    endif

    if reversed then
      if (Notch) then
        Type$= get_feat_ctype(Notch)
        if (!cmp(Type$,COMMONLIPNOTCH$)) then
          disconnect(Notch)
          del_object(Notch)
          Notch= 0
        endif
      endif

      if (!Notch) then
        Notch= new_feature("NOTCH",COMMONLIPNOTCH$,"0")
        if (!Notch) then exit
        add_sobj(Pce2) Notch
        connect(This) Notch,"ND"
      endif

      vec_times_scalar(D) EZ,-LipCutLen
      vec_add(P) EP,D
      vec_copy(Y) EZ
      vec_copy(Z) PX2

      if !proj_to_piece(P,X,P,Z,Pce2,0.0,1) then exit
      vec_times_scalar(D) Z,-Ndepth
      vec_add(P) P,D
      vec_cross_prod(X) Y,Z
      set_origin_pos(Notch) P,X,Y,Z
      set_obj_param(Notch) "W",LipCutLen$
    else
      if (Notch) then
        Type$= get_feat_ctype(Notch)
        if (!cmp(Type$,COMMONNOTCH$)) then
          disconnect(Notch)
          del_object(Notch)
          Notch= 0
        endif
      endif

      if (!Notch) then
        Notch= new_feature("NOTCH",COMMONNOTCH$,"0")
        if (!Notch) then exit
        add_sobj(Pce2) Notch
        connect(This) Notch,"ND"
      endif

      NotchLen= LipCutLen
      NotchLen$= NotchLen

      vec_times_scalar(D) EZ,-NotchLen
      vec_add(P) EP,D
      vec_copy(Y) EZ
      vec_copy(Z) PX2

      vec_rev(Z) Z
      if !proj_to_piece(P,X,P,Z,Pce2,0.0,1) then exit
      vec_times_scalar(D) Z,-Ndepth
      vec_add(P) P,D
      vec_cross_prod(X) Y,Z
      set_origin_pos(Notch) P,X,Y,Z
      set_obj_param(Notch) "W",NotchLen$
    endif
  endif
endif

! Set plates and screws
Reinforced = get_joint_param(This,"REIN")

if Reinforced then
  Reinforced = get_joint_param(This,"REIN")
  PlateWidth$ = get_joint_param(This,"PLATE_WIDTH")
  PlateWidth = PlateWidth$
  PlateHeight$ = get_joint_param(This,"PLATE_HEIGHT")
  PlateHeight = PlateHeight$
  PlateThick$ = get_joint_param(This,"PLATE_THICK")
  PlateThick = PlateThick$
  ScrewLib$ = get_joint_param(This,"SCREW_LIB")
  ScrewMacro$ = get_joint_param(This,"SCREW_MAC")
  ScrewDist = get_joint_param(This,"SCREW_DIST")
  Wdt = DimP + PlateThick * 2

  init_iterator(I) "",This,"CONNECTION_ROLEPARTS","SP"
  loop
    Screws= next_item(I)
    if Screws then
      disconnect(Screws)
      del_object(Screws)
    endif
    exitif !Screws
  endloop

  init_iterator(I) "",This,"CONNECTION_ROLEPARTS","PLATE"
  loop
    Plate= next_item(I)
    if Plate then
      disconnect(Plate)
      del_object(Plate)
    endif
    exitif !Plate
  endloop

  Sq = get_joint_param(This,"SQ")
  vec_copy(P) JP
  if Sq % 2 == 0 then
    Num = (Sq / 2) + 1
    loop Num
      Screws= new_macro(ScrewLib$,ScrewMacro$,JP,JX,JY,JZ,1,1,0,0)
      if Screws then
        add_sobj(Pce) Screws
        connect(This) Screws,"SP"
        set_same_tlink(Screws) Pce
        set_same_visib(Screws) Pce   
        set_obj_param(Screws) "WDT",Wdt,1
        set_origin_pos(Screws) P,PZ,PX,PY
        vec_times_scalar(D) EZ,ScrewDist
        vec_rev(D) D
        vec_add(P) P,D
      endif
    endloop
    vec_copy(P) JP

    vec_rev(D) EZ
    if vec_dot_prod(D,PZ) > 0 then
      vec_copy(D) PZ
    else
      vec_rev(D) PZ
    endif
    vec_times_scalar(D) D,ScrewDist
    
    vec_add(P) P,D
    loop Sq - Num
      Screws= new_macro(ScrewLib$,ScrewMacro$,JP,JX,JY,JZ,1,1,0,0)
      if Screws then
        add_sobj(Pce) Screws
        connect(This) Screws,"SP"
        set_same_tlink(Screws) Pce
        set_same_visib(Screws) Pce 
        set_obj_param(Screws) "WDT",Wdt,1
        set_origin_pos(Screws) P,PZ,PX,PY
        vec_add(P) P,D
      endif
    endloop
  else
    Screws= new_macro(ScrewLib$,ScrewMacro$,JP,JX,JY,JZ,1,1,0,0)
    if Screws then
      add_sobj(Pce) Screws
      connect(This) Screws,"SP" 
      set_same_tlink(Screws) Pce
      set_same_visib(Screws) Pce
      set_obj_param(Screws) "WDT",Wdt,1
      set_origin_pos(Screws) P,PZ,PX,PY
    endif
    
    vec_times_scalar(D) EZ,ScrewDist
    vec_rev(D) D
    vec_add(P) P,D    
    
    Sq = Sq - 1
    Num = Sq / 2
    loop Num
      Screws= new_macro(ScrewLib$,ScrewMacro$,JP,JX,JY,JZ,1,1,0,0)
      if Screws then
        add_sobj(Pce) Screws
        connect(This) Screws,"SP"
        set_same_tlink(Screws) Pce
        set_same_visib(Screws) Pce   
        set_obj_param(Screws) "WDT",Wdt,1
        set_origin_pos(Screws) P,PZ,PX,PY
        vec_times_scalar(D) EZ,ScrewDist
        vec_rev(D) D
        vec_add(P) P,D
      endif
    endloop
    
    vec_copy(P) JP
    vec_rev(D) EZ
    if vec_dot_prod(D,PZ) > 0 then
      vec_copy(D) PZ
    else
      vec_rev(D) PZ
    endif
    vec_times_scalar(D) D,ScrewDist
    vec_add(P) P,D
    loop Num
      Screws= new_macro(ScrewLib$,ScrewMacro$,JP,JX,JY,JZ,1,1,0,0)
      if Screws then
        add_sobj(Pce) Screws
        connect(This) Screws,"SP"
        set_same_tlink(Screws) Pce
        set_same_visib(Screws) Pce    
        set_obj_param(Screws) "WDT",Wdt,1
        set_origin_pos(Screws) P,PZ,PX,PY
        vec_add(P) P,D
      endif
    endloop    
  endif

  ! Reinforced Plates
  Plate= new_macro("GUSSET_PLATE","GPLATE",JP,JX,JY,JZ,1,1,0,0)
  if Plate then 
    add_sobj(Pce) Plate
    connect(This) Plate,"PLATE"
    set_same_tlink(Plate) Pce
    set_same_visib(Plate) Pce
    set_obj_param(Plate) "DX",PlateWidth$
    set_obj_param(Plate) "DY",PlateHeight$
    set_obj_param(Plate) "DZ",PlateThick$
    vec_rev(D) EZ
    if vec_dot_prod(D,PZ) > 0 then
      vec_copy(D) PZ
    else
      vec_rev(D) PZ
    endif
    !vec_rev(D) D
    Offset = PlateWidth/2
    if !proj_to_piece(P,X,JP,D,Pce2,0,1) then exit
    vec_times_scalar(D) PX,PlateWidth/2-Width/2
    if TrackReversed then
      vec_rev(D) D
    endif
    vec_add(P) P,D
    vec_times_scalar(D) PY,DimP/2+PlateThick
    vec_rev(D) D
    vec_add(P) P,D
    set_origin_pos(Plate) P,PX,PZ,PY
  endif

  Plate= new_macro("GUSSET_PLATE","GPLATE",JP,JX,JY,JZ,1,1,0,0)
  if Plate then 
    add_sobj(Pce) Plate
    connect(This) Plate,"PLATE"
    set_same_tlink(Plate) Pce
    set_same_visib(Plate) Pce
    set_obj_param(Plate) "DX",PlateWidth$
    set_obj_param(Plate) "DY",PlateHeight$
    set_obj_param(Plate) "DZ",PlateThick$
    vec_rev(D) EZ
    if vec_dot_prod(D,PZ) > 0 then
      vec_copy(D) PZ
    else
      vec_rev(D) PZ
    endif
    !vec_rev(D) D
    Offset = PlateWidth/2
    if !proj_to_piece(P,X,JP,D,Pce2,0,1) then exit
    vec_times_scalar(D) PX,PlateWidth/2-Width/2
    if TrackReversed then
      vec_rev(D) D
    endif
    vec_add(P) P,D
    vec_times_scalar(D) PY,DimP/2
    vec_add(P) P,D
    set_origin_pos(Plate) P,PX,PZ,PY
  endif
else
  init_iterator(I) "",This,"CONNECTION_ROLEPARTS","SP"
  Screws= next_item(I)
  if Screws then
    Wdt= get_obj_param(Screws,"WDT")
    if abs(DimP-Wdt) > mm_to_dwg(0.1) then
      Wdt$= DimP
      set_obj_param(Screws) "WDT",Wdt$,1
    endif
    if DOffset then
      vec_copy(P) DP
    else
      vec_copy(P) JP
    endif
    set_origin_pos(Screws) P,PZ,PX,PY
  endif
endif

set RETURN "1"

#JOINT_DETAILING#

#EDIT_PROPERTIES#

!debug ./edit_properties.dbg

I= new_iterator("",0,"ROLED","THIS")
This = next_item(I)
if !This then exit

IS= new_iterator("",This,"CONNECTION_ROLEPARTS","PLATE")
SP= next_item(IS)
if !SP then exit

FCode$ = get_joint_param(This,"FCODE")
CapLib$ = get_joint_param(This,"LIB")
Cap$ = get_joint_param(This,"CAP")
ForceNotch$ = get_joint_param(This,"FORCE_NOTCH")
DOffset$ = get_joint_param(This,"DOFFSET")
Full$ = get_joint_param(This,"FULLDIMPLE")
Eg$ = get_joint_param(This,"EG")
Sq$ = get_joint_param(This,"SQ")


P = 1
X = 2
Y = 3
Z = 4

vec_to(P) 0,0,0
vec_to(X) 1,0,0
vec_to(Y) 0,1,0
vec_to(Z) 0,0,1

TmpObj= new_macro("","",P,X,Y,Z,1,1,0)
if TmpObj then
  set_obj_param(TmpObj) "FCODE",FCode$
  set_obj_param(TmpObj) "LIB",Lib$
  set_obj_param(TmpObj) "CAP",Cap$
  set_obj_param(TmpObj) "FORCE_NOTCH",ForceNotch$
  set_obj_param(TmpObj) "DOffset",DOffset$
  set_obj_param(TmpObj) "DOFFSET",DOffset
  set_obj_param(TmpObj) "FULLDIMPLE",Full$
  set_obj_param(TmpObj) "EG",Eg$
  set_obj_param(TmpObj) "SQ",Sq$
  
  Ok = edit_obj_data(TmpObj,"LGS_0306A_sq_form",0)

  if Ok then
    FCode$ = get_joint_param(This,"FCODE")
    CapLib$ = get_joint_param(This,"LIB")
    Cap$ = get_joint_param(This,"CAP")
    ForceNotch$ = get_joint_param(This,"FORCE_NOTCH")
    DOffset = get_joint_param(This,"DOFFSET")
    Full$ = get_joint_param(This,"FULLDIMPLE")
    Eg$ = get_joint_param(This,"EG")
    Sq$ = get_joint_param(This,"SQ")

    init_iterator(I) "",0,"ROLED","THIS"
    loop
      Jnt = next_item(I)
      exitif !Jnt

      set_obj_param(Jnt) "FCODE",FCode$
      set_obj_param(Jnt) "LIB",Lib$
      set_obj_param(Jnt) "CAP",Cap$
      set_obj_param(Jnt) "FORCE_NOTCH",ForceNotch$
      set_obj_param(Jnt) "DOffset",DOffset$
      set_obj_param(Jnt) "DOFFSET",DOffset
      set_obj_param(Jnt) "FULLDIMPLE",Full$
      set_obj_param(Jnt) "EG",Eg$
      set_obj_param(Jnt) "SQ",Sq$
    endloop
  set RETURN "1"
endif

del_object(TmpObj)

#EDIT_PROPERTIES#

#JOINT_CAPACITY#
!debug ./joint_capacity.dbg

I= new_iterator("",0,"ROLED","THIS")
This = next_item(I)
if !This then exit

set ROLE_PCE1 "PCE"
set ROLE_PCE2 "END"
set ROLE_SCREWS "SP"

File$ = get_obj_param(This,"CAP")
Lib$ = get_obj_param(This,"CAPLIB")&"/"

DirSystem$ = get($DIR_SYSTEM)&"complibs/"
Path$ = DirSystem$&Lib$&File$
CustomFilePath$ = filepath_custom(Path$)
if (len(CustomFilePath$) && file_exists(CustomFilePath$)) then
  call CustomFilePath$ JOINT_CAPACITY
  exit
endif
if (len(File$) && file_exists(Path$)) then
  call Path$ JOINT_CAPACITY
endif

#JOINT_CAPACITY#
#UPDATE_JOINT_DATA#
!debug ./update_joint_data.dbg

I = new_iterator("",0,"ROLED","THIS")
This = next_item(I)
if !This then exit

set ROLE_SCREWS "SP"

File$ = get_obj_param(This,"CAP")
Lib$ = get_obj_param(This,"CAPLIB")&"/"

DirSystem$ = get($DIR_SYSTEM)&"complibs/"
Path$ = DirSystem$&Lib$&File$
CustomFilePath$ = filepath_custom(Path$)
if (len(CustomFilePath$) && file_exists(CustomFilePath$)) then
  call CustomFilePath$ UPDATE_JOINT_DATA
  exit
endif
if (len(File$) && file_exists(Path$)) then
  call Path$ UPDATE_JOINT_DATA
endif

#UPDATE_JOINT_DATA#

#JOINT_ADAPT#
! Debugging using time stamp, remark also debug call at end
!T2$= get($TIME)
!T$ = T2$[1,2]
!T$ = T$&T2$[4,5]
!T$ = T$&T2$[7,8]
!Path$= "./ LGS_0516A_ADAPT."&T$
!debug Path$
!debug ./LGS_0516A_ADAPT.dbg

I = new_iterator("",0,"ROLED","THIS")
This = next_item(I)
if (!This) then exit

init_iterator(I) "",0,"ROLED","ADAPT"
Adapt = next_item(I)
if (!Adapt) then exit

init_iterator(I) "",This,"CONNECTION_ROLEPARTS","PCE"
Pce = next_item(I)
if (!Pce) then exit

Type$= get_object_type(Pce)
if cmp(Type$,"PROFEND") then
  PceEnd= Pce
  Pce= get_actual_piece(PceEnd)
endif

init_iterator(I) "",This,"CONNECTION_ROLEPARTS","END"
End = next_item(I)
if (!End) then exit

init_iterator(I) "",This,"CONNECTION_ROLEPARTS","OPTPCE"
OptPce = next_item(I)
if (OptPce) then exit

Type$ = get_object_type(Adapt)
PceA = 0
if (cmp(Type$,"PROFOBJ")) then
  PceA = Adapt
else
  exit
endif

P = 1
X = 2
Y = 3
Z = 4
PA  = 5
PAX = 6
PAY = 7
PAZ = 8
D   = 9
SD  = 10
SDA = 11
OP  = 12
OPA = 13
JP = 14
JX = 15
JY = 16
JZ = 17
Pnt = 18
PntP = 19

Geom = 1
GeomA = 2

if (Pce == PceA) then exit

get_origin_pos(This) JP,JX,JY,JZ
get_origin_pos(Pce) P,X,Y,Z
get_origin_pos(PceA) PA,PAX,PAY,PAZ

! Check parallel
Dot = vec_dot_prod(Z,PAZ)
if (abs(Dot) < 0.999) then exit

get_vxgeom(Geom) Pce
get_vxgeom_point(Pnt) Geom,"START"
get_vxgeom_tan(D) Geom,Pnt
get_piece_dir(SD) Pce
vec_cross_prod(OP) SD,D

get_vxgeom(GeomA) PceA
get_vxgeom_point(Pnt) GeomA,"START"
get_vxgeom_tan(D) GeomA,Pnt
get_piece_dir(SDA) PceA
vec_cross_prod(OPA) SDA,D

! Check opening dir
Dot = vec_dot_prod(OP,OPA)
if (Dot > -0.999) then exit

! Check joint pos on adapted piece
point_to_vxgeom(Pnt) GeomA,JP
Ok = is_in_vxgeom(GeomA,Pnt,0,mm_to_dwg(1.0))
if (!Ok) then exit

! Check pieces are close
get_vxgeom_point(Pnt) GeomA,"MID"
point_to_vxgeom(PntP) Geom,Pnt
vec_sub(D) PntP,Pnt
Len = vec_len(D)
if (Len > mm_to_dwg(5.0)) then exit

! Adapt piece
connect(This) PceA,"OPTPCE",2

set RETURN "1"

#JOINT_ADAPT#