#-----------------------------------------------------------------------
#                   Primitive tsxPython sample script
#                    (part of) Folower of Life ball
# 
# $Id: folball1a.py 37 2019-03-11 19:11:18Z 3DfromNULL $
#-----------------------------------------------------------------------
import ptsxpy as p
import ptsxgp
import math

# radius of the ball
r1 = 5.
# thickness
###t = 0.03 * r1
t = 0.03 * r1
# outer radius of the unit ring
r2 = 0.35 *r1 
# width of the unit ring (outer radius - inner radius)
w = 0.2 * r2
# 2 pi / ( 2 * number of non-overlapped unit circle per circumference )
deg1 = math.pi / 8.5
# fineness (number of longitudes and lattitudes)
f1 = 32
#  boolean idenntity (unit: 1/1000)
bi = 20
# back up boolean options and indentity
boolopt_bk = p.BooleanGetOptions()
boolid_bk = p.BooleanGetIdentity()
# set boolean identity
p.BooleanSetIdentity( bi )
# Origin
org = Vec3f( 0., 0., 0. )
print( "org.p=", org.p )
# init ring pair list
list1 = []
# constants
P2 = math.pi / 2
P3 = math.pi / 3
P6 = math.pi / 6
P8 = math.pi / 8
#
###ob2 = [ 0 ]
###ob3 = [ 0 ]
ob2wk = ptsxgp.alloc_long( 1 )
ob3wk = ptsxgp.alloc_long( 1 )


# Set "keep drill" and other all options off.
# This script doen not use "keep drill" mode because each of boolean
# operation functions re-create the drill when "keep drill" option is on,
# and cannot get the pointer to the new drill easily.
p.BooleanSetOptions( 0 )

# Clear scene
###p.SceneNew()
# Create a big sphere
sp1 = p.CreateSphere( f1, f1, r1 )
p.SceneAddObject( sp1, false )
p.GNodeSetLocation( sp1, org.p )
# Create a smaller sphere to hollow
sp2 = p.CreateSphere( f1, f1, r1 - t )
p.SceneAddObject( sp2, true )
p.GNodeSetLocation( sp2, org.p )
# Do sp1 - sp2
p.SelectSobj( sp1, e_tsxSELECT, false )
retc = p.BooleanSubtractionFromCurrobj( sp2 )
if retc != 0:
  print( "sp1 - sp2 failed. retc=", retc )
  eeeee()
# Create a cylinder (height is slightly greater than the diameter of sp1)
cy1 = p.CreateCylinder( f1, 2, r2, r2, 2.2 * r1 )
p.SceneAddObject( cy1, false )
p.GNodeSetLocation( cy1, org.p )
# Create a thinner cylinder to hollow (slightly tall)
cy2 = p.CreateCylinder( f1, 2, r2 - 0.5 * w, r2 - 0.5 * w, 2.3 * r1 )
p.SceneAddObject( cy2, false )
p.GNodeSetLocation( cy2, org.p )
# Do cy1 - cy2
p.SelectSobj( cy1, e_tsxSELECT, false )
retc = p.BooleanSubtractionFromCurrobj( cy2 )
if retc != 0:
  print( "cy1 - cy2 failed. retc=", retc )
  eeeee()

# This function makes clone, rotates, and magnifies the specified object.
#  
# vx:  x component of the vector of the axis for rotation 
# vy:  y component
# vz:  z component
# deg: degree for rotation (in radian)
# mag: rate of magnification for the unit circle
def rot1( ob1, vx, vy, vz, deg, mag ):
    sp3 = [ 0 ]
    __vec1 = 0
    __vec2 = 0
    # Make a clone of the specified cylinder.
    p.GNodeCopy( ob1, ob2wk )
    ob2 = ptsxgp.loadptr( ob2wk )
    ###p.SceneAddObject( ob2[ 0 ], false )
    p.SceneAddObject( ob2, false )
    # Magnify it. 
    __vec1 = Vec3f( mag, mag, 1. )
    ###p.GNodeScale( ob2[ 0 ], __vec1.p, e_tsxWorldFrame )
    p.GNodeScale( ob2, __vec1.p, e_tsxWorldFrame )
    # Rotate it.
    __vec2 = Vec3f( vx, vy, vz )
    ###p.GNodeRotate( ob2[ 0 ], org.p, __vec2.p, deg, e_tsxWorldFrame )
    p.GNodeRotate( ob2, org.p, __vec2.p, deg, e_tsxWorldFrame )
    # Do ob2 (a pipe) AND sp1
    # Make a clone of the sphere
    p.GNodeCopy( sp1, ob3wk )
    ob3 = ptsxgp.loadptr( ob3wk )
    ###p.SelectSobj( ob2[ 0 ], e_tsxSELECT, false )
    p.SelectSobj( ob2, e_tsxSELECT, false )
    ###retc = p.BooleanIntersectionWithCurrobj( ob3[ 0 ] )
    retc = p.BooleanIntersectionWithCurrobj( ob3 )
    #print( "(1) retc=", retc )
    ###list1.append( ob2[ 0 ] )
    list1.append( ob2 )
    del __vec1
    del __vec2

for i in range( 6 ):
    rot1( cy1, math.sin(i*P3),      math.cos(i*P3),      0,     deg1, 1.05)
    rot1( cy1, math.sin(i*P3),      math.cos(i*P3),      0, 1.9*deg1, 1.0)
    rot1( cy1, math.sin(i*P3+0.52), math.cos(i*P3+0.52), 0, 2.7*deg1, 1.2)

# Get the intersection of the first cylinder and the original sphere
# without making any clone of the sphere.
p.SelectSobj( cy1, e_tsxSELECT, false )
retc = p.BooleanIntersectionWithCurrobj( sp1 )
print( "(2) retc=", retc )
list1.append( cy1 )

p.SelectSobj( cy1, e_tsxSELECT, false )
for i in range(0,len(list1)-1):
    p.GroupAtCurrobj( list1[ i ] )

p.SceneDraw()

# restore boolean options and indentity
p.BooleanSetOptions( boolopt_bk )
p.BooleanSetIdentity( boolid_bk )

del org

