####################################################################################################
#
# Invoking X3D model self-test:
#
#   $ python PointSetExample.py
#
# Python package x3d.py package is available on PyPI for import.
#   This approach simplifies Python X3D deployment and use.
#   https://pypi.org/project/x3d
#
# Installation:
#       pip install x3d
# or
#       python -m pip install x3d
#
# Developer options for loading x3d package in other Python programs:
#
#    from x3d import *  # preferred approach, terser source that avoids x3d.* class prefixes
#
# or
#    import x3d         # traditional way to subclass x3d package, all classes require x3d.* prefix,
#                       # but python source is very verbose, for example x3d.Material x3d.Shape etc.
#                       # X3dToPython.xslt stylesheet insertPackagePrefix=true supports this option.
#
# Project home page:    # X3D Python Scene Access Interface Library (X3DPSAIL)
#                       # https://www.web3d.org/x3d/stylesheets/python/python.html
# Conversion generator: # https://www.web3d.org/x3d/stylesheets/X3dToPython.xslt
#
####################################################################################################

from x3d import *

newModel=X3D(profile='Immersive',version='3.3',
  head=head(
    children=[
    meta(content='PointSetExample.x3d',name='title'),
    meta(content='Way points for the animated shark Lucy traversing the tank.',name='description'),
    meta(content='Tim McLean',name='creator'),
    meta(content='Don Brutzman',name='translator'),
    meta(content='14 June 2020',name='created'),
    meta(content='14 June 2020',name='translated'),
    meta(content='14 July 2025',name='modified'),
    meta(content='http://faculty.nps.edu/brutzman/kelp',name='reference'),
    meta(content='https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/SharkLucyLocale.x3d',name='reference'),
    meta(content='https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter06GeometryPointsLinesPolygons/PointSetExample.x3d',name='identifier'),
    meta(content='X3D-Edit 4.0, https://www.web3d.org/x3d/tools/X3D-Edit',name='generator'),
    meta(content='../license.html',name='license')]),
  Scene=Scene(
    children=[
    WorldInfo(title='PointSetExample.x3d'),
    Background(),
    Viewpoint(description='Book View',orientation=(0.939,0.335,0.075,-0.57),position=(-0.89,1.91,9.26)),
    Transform(DEF='_0',translation=(0.0,-8.0,-1.0),
      children=[
      Inline(url=["../KelpForestExhibit/SharkLucy.x3d","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/SharkLucy.x3d","../KelpForestExhibit/SharkLucy.wrl","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/SharkLucy.wrl"]),
      Group(
        children=[
        TimeSensor(DEF='SHARK1_CLOCK',cycleInterval=220.0,loop=True),
        PositionInterpolator(DEF='SHARK1_POSITION',key=[0.0,0.048,0.112,0.155,0.184,0.263,0.3,0.342,0.375,0.404,0.457,0.497,0.57,0.65,0.702,0.796,0.888,0.938,1.0],keyValue=[(0.0,-7.0,-1.0),(-1.75,-7.0,-0.5),(-4.0,-7.0,0.5),(-5.0,-6.5,1.5),(-5.5,-6.25,0.75),(-5.25,-5.5,-2.25),(-4.25,-5.0,-3.25),(-2.75,-4.5,-3.75),(-1.5,-4.5,-4.0),(-0.5,-4.25,-4.5),(1.5,-3.75,-4.75),(3.0,-3.75,-4.5),(5.75,-4.5,-4.5),(8.75,-4.5,-4.0),(9.25,-4.5,-2.25),(7.5,-5.5,0.0),(4.0,-6.5,-0.25),(2.25,-7.0,-0.25),(0.0,-7.0,-1.0)]),
        OrientationInterpolator(DEF='SHARK1_ORIENTATION',key=[0.0,0.048,0.112,0.155,0.184,0.263,0.3,0.342,0.375,0.404,0.457,0.497,0.57,0.65,0.702,0.796,0.888,0.938,1.0],keyValue=[(0.0,1.0,0.0,3.4208),(0.0,1.0,0.0,3.5605),(0.1504,0.986,0.0717,4.0208),(0.1095,0.9918,-0.0658,2.0667),(-0.1207,0.9836,0.134,1.4825),(-0.1565,0.9125,0.3779,0.8522),(-0.1099,0.7118,0.6937,0.4379),(0.0,1.0,0.0,0.192),(-0.0956,0.8656,0.4916,0.4418),(-0.0606,0.4959,0.8663,0.2802),(0.0,1.0,0.0,6.161),(0.0,0.0,-1.0,0.2618),(0.0,1.0,0.0,6.0388),(0.0,1.0,0.0,5.236),(-0.1388,0.9878,-0.0707,4.0742),(-0.1392,0.9903,0.0,3.1416),(-0.1305,0.9911,0.0265,3.0),(0.0,1.0,0.0,2.827),(0.0,1.0,0.0,3.4208)])])]),
    Comment('TODO move PointSet to top'),
    Transform(
      children=[
      Shape(
        appearance=Appearance(
          material=Material(emissiveColor=(1,1,0))),
        geometry=PointSet(
          coord=Coordinate(DEF='TurnPoints',point=[(0.0,-7.0,-1.0),(-1.75,-7.0,-0.5),(-4.0,-7.0,0.5),(-5.0,-6.5,1.5),(-5.5,-6.25,0.75),(-5.25,-5.5,-2.25),(-4.25,-5.0,-3.25),(-2.75,-4.5,-3.75),(-1.5,-4.5,-4.0),(-0.5,-4.25,-4.5),(1.5,-3.75,-4.75),(3.0,-3.75,-4.5),(5.75,-4.5,-4.5),(8.75,-4.5,-4.0),(9.25,-4.5,-2.25),(7.5,-5.5,0.0),(4.0,-6.5,-0.25),(2.25,-7.0,-0.25),(0.0,-7.0,-1.0)])))]),
    TimeSensor(DEF='_4',loop=True),
    Script(DEF='sharkSwimmingInTankTrigger_5',
      field=[
      field(accessType='inputOnly',name='triggerIn',type='SFTime'),
      field(accessType='outputOnly',name='startTime',type='SFTime'),
      field(accessType='outputOnly',name='firstTime',type='SFBool')],

    sourceCode="""
ecmascript:

function triggerIn (value, time)
{
	startTime = value;
	firstTime = false;
}
"""),
    ROUTE(fromField='startTime',fromNode='sharkSwimmingInTankTrigger_5',toField='set_startTime',toNode='SHARK1_CLOCK'),
    ROUTE(fromField='fraction_changed',fromNode='SHARK1_CLOCK',toField='set_fraction',toNode='SHARK1_POSITION'),
    ROUTE(fromField='fraction_changed',fromNode='SHARK1_CLOCK',toField='set_fraction',toNode='SHARK1_ORIENTATION'),
    ROUTE(fromField='value_changed',fromNode='SHARK1_POSITION',toField='set_translation',toNode='_0'),
    ROUTE(fromField='value_changed',fromNode='SHARK1_ORIENTATION',toField='set_rotation',toNode='_0'),
    ROUTE(fromField='firstTime',fromNode='sharkSwimmingInTankTrigger_5',toField='set_enabled',toNode='_4'),
    ROUTE(fromField='time',fromNode='_4',toField='triggerIn',toNode='sharkSwimmingInTankTrigger_5')])
)

### X3D model conversion complete ###

####################################################################################################
# Self-test diagnostics
####################################################################################################

print('Self-test diagnostics for PointSetExample.py:')
if        metaDiagnostics(newModel): # built-in utility method in X3D class
    print(metaDiagnostics(newModel)) # display meta info, hint, warning, error, TODO values in this model
# print('check newModel.XML() serialization...')
newModelXML= newModel.XML() # test export method XML() for exceptions during export
newModel.XMLvalidate()
# print(newModelXML) # diagnostic

try:
#   print('check newModel.VRML() serialization...')
    newModelVRML=newModel.VRML() # test export method VRML() for exceptions during export
    # print(prependLineNumbers(newModelVRML)) # debug
    print("Python-to-VRML export of VRML output successful", flush=True)
except Exception as err: # usually BaseException
    # https://stackoverflow.com/questions/18176602/how-to-get-the-name-of-an-exception-that-was-caught-in-python
    print("*** Python-to-VRML export of VRML output failed:", type(err).__name__, err)
    if newModelVRML: # may have failed to generate
        print(prependLineNumbers(newModelVRML, err.lineno))

try:
#   print('check newModel.JSON() serialization...')
    newModelJSON=newModel.JSON() # test export method JSON() for exceptions during export
#   print(prependLineNumbers(newModelJSON)) # debug
    print("Python-to-JSON export of JSON output successful (under development)")
except Exception as err: # usually SyntaxError
    print("*** Python-to-JSON export of JSON output failed:", type(err).__name__, err)
    if newModelJSON: # may have failed to generate
        print(prependLineNumbers(newModelJSON,err.lineno))

print("python PointSetExample.py load and self-test diagnostics complete.")
