####################################################################################################
#
# Invoking X3D model self-test:
#
#   $ python KelpTank.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='KelpTank.x3d',name='title'),
    meta(content='Kelp Forest Tank at the Monterey Bay Aquarium.',name='description'),
    meta(content='Mark Boyd',name='creator'),
    meta(content='11 June 1998',name='created'),
    meta(content='Jeffrey Weekley, using NIST VRML to X3D Translator, with review and editing in Xeena.',name='translator'),
    meta(content='22 December 2002',name='translated'),
    meta(content='20 October 2019',name='modified'),
    meta(content='https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/KelpTank.x3d',name='identifier'),
    meta(content='Vrml97ToX3dNist, http://ovrt.nist.gov/v2_x3d.html',name='generator'),
    meta(content='X3D-Edit 3.3, https://www.web3d.org/x3d/tools/X3D-Edit',name='generator'),
    meta(content='../license.html',name='license')]),
  Scene=Scene(
    children=[
    WorldInfo(title='KelpTank.x3d'),
    Group(DEF='FogSwitching',
      children=[
      Fog(DEF='FogOffVisibilityRange0'),
      Fog(DEF='InsideTankFog',color=(0.1,0.4,0.4),visibilityRange=25.0),
      ProximitySensor(DEF='CameraInsideTankSensor',center=(0.0,-4.0,-5.0),size=(25.0,10.0,20.0)),
      ROUTE(fromField='isActive',fromNode='CameraInsideTankSensor',toField='set_bind',toNode='InsideTankFog')]),
    Collision(enabled=False,
      children=[
      Transform(
        children=[
        Inline(url=["KelpTankWaterSurface.x3d","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/KelpTankWaterSurface.x3d","KelpTankWaterSurface.wrl","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/KelpTankWaterSurface.wrl"])]),
      Transform(
        children=[
        Inline(url=["KelpTankExternalLights.x3d","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/KelpTankExternalLights.x3d","KelpTankExternalLights.wrl","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/KelpTankExternalLights.wrl"])]),
      Transform(rotation=(0.0,1.0,0.0,1.5785398),translation=(-10.35,1.0,-0.5),
        children=[
        Inline(url=["PumpHouse.x3d","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/PumpHouse.x3d","PumpHouse.wrl","https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/KelpForestExhibit/PumpHouse.wrl"])]),
      Shape(
        appearance=Appearance(DEF='WallAppearance',
          material=Material(diffuseColor=(0.251,0.239,0.212))),
        geometry=IndexedFaceSet(coordIndex=[0,1,2,3,-1,4,5,6,7,-1,8,9,10,11,-1,16,17,18,19,-1,11,10,3,2,-1,5,4,17,16,-1,20,0,3,21,-1,22,4,7,23,-1,9,24,25,10,-1,17,28,29,18,-1,10,25,21,3,-1,4,22,28,17,-1,30,20,21,31,-1,32,22,23,33,-1,24,34,35,25,-1,28,38,39,29,-1,25,35,31,21,-1,22,32,38,28,-1,40,30,31,41,-1,42,32,33,43,-1,34,44,45,35,-1,38,48,49,39,-1,35,45,41,31,-1,32,42,48,38,-1],
          coord=Coordinate(DEF='WindowCoordinates',point=[(-2.5,-8.5344,0.7),(-4.5,-8.5344,2.7),(-4.5,-7.21,2.7),(-2.5,-7.21,0.7),(-2.5,-0.5,0.7),(-4.5,-0.5,2.7),(-4.5,0.9144,2.7),(-2.5,0.9144,0.7),(-4.5,-8.5344,3.0),(-2.5,-8.5344,1.0),(-2.5,-7.21,1.0),(-4.5,-7.21,3.0),(-4.5,-7.21,2.8),(-2.5,-7.21,0.8),(-2.5,-0.5,0.8),(-4.5,-0.5,2.8),(-4.5,-0.5,3.0),(-2.5,-0.5,1.0),(-2.5,0.9144,1.0),(-4.5,0.9144,3.0),(0.0,-8.5344,-0.3),(0.0,-7.21,-0.3),(0.0,-0.5,-0.3),(0.0,0.9144,-0.3),(0.0,-8.5344,0.0),(0.0,-7.21,0.0),(0.0,-7.21,-0.2),(0.0,-0.5,-0.2),(0.0,-0.5,0.0),(0.0,0.9144,0.0),(2.5,-8.5344,0.7),(2.5,-7.21,0.7),(2.5,-0.5,0.7),(2.5,0.9144,0.7),(2.5,-8.5344,1.0),(2.5,-7.21,1.0),(2.5,-7.21,0.8),(2.5,-0.5,0.8),(2.5,-0.5,1.0),(2.5,0.9144,1.0),(4.5,-8.5344,2.7),(4.5,-7.21,2.7),(4.5,-0.5,2.7),(4.5,0.9144,2.7),(4.5,-8.5344,3.0),(4.5,-7.21,3.0),(4.5,-7.21,2.8),(4.5,-0.5,2.8),(4.5,-0.5,3.0),(4.5,0.9144,3.0)]))),
      Transform(
        children=[
        Shape(
          appearance=Appearance(DEF='Glass',
            material=Material(diffuseColor=(0.275,0.655,0.62),transparency=0.63)),
          geometry=IndexedFaceSet(coordIndex=[3,2,5,4,-1,12,13,14,15,-1,21,3,4,22,-1,13,26,27,14,-1,31,21,22,32,-1,26,36,37,27,-1,41,31,32,42,-1,36,46,47,37,-1],
            coord=Coordinate(USE='WindowCoordinates')))]),
      Shape(
        appearance=Appearance(USE='WallAppearance'),
        geometry=IndexedFaceSet(coordIndex=[0,88,114,115,99,-1,88,89,113,114,-1,89,1,90,112,113,-1,90,91,111,112,-1,91,92,104,105,110,111,-1,92,93,103,104,-1,93,2,94,102,103,-1,94,95,101,102,-1,95,3,96,100,101,-1,96,97,107,100,-1,97,98,108,109,106,107,-1,98,99,115,108,-1,106,109,110,105,-1,118,37,117,141,140,-1,117,116,142,141,-1,116,36,127,143,142,-1,127,126,136,143,-1,126,125,135,134,137,136,-1,125,124,128,135,-1,124,39,123,129,128,-1,123,122,130,129,-1,122,38,121,131,130,-1,121,120,132,131,-1,120,119,139,138,133,132,-1,119,118,140,139,-1,133,138,137,134,-1,0,3,39,36,-1,106,105,133,134,-1,105,104,132,133,-1,104,103,131,132,-1,103,102,130,131,-1,102,101,129,130,-1,101,100,128,129,-1,100,107,135,128,-1,107,106,134,135,-1,115,114,142,143,-1,114,113,141,142,-1,113,112,140,141,-1,112,111,139,140,-1,111,110,138,139,-1,110,109,137,138,-1,109,108,136,137,-1,108,115,143,136,-1,1,4,12,13,-1,4,5,7,12,-1,5,2,6,7,-1,1,13,6,2,-1,8,9,10,11,-1,40,37,49,48,-1,37,38,42,49,-1,38,41,43,42,-1,40,48,43,41,-1,47,46,45,44,-1,9,8,44,45,-1,8,7,43,44,-1,7,6,42,43,-1,6,9,45,42,-1,13,12,48,49,-1,12,11,47,48,-1,11,10,46,47,-1,10,13,49,46,-1,4,14,22,23,-1,14,15,17,22,-1,15,5,16,17,-1,4,23,16,5,-1,18,19,20,21,-1,50,40,59,58,-1,40,41,52,59,-1,51,53,52,41,-1,50,58,53,51,-1,54,57,56,55,-1,19,18,54,55,-1,18,17,53,54,-1,17,16,52,53,-1,16,19,55,52,-1,23,22,58,59,-1,22,21,57,58,-1,21,20,56,57,-1,20,23,59,56,-1,14,24,25,15,-1,60,50,51,61,-1,24,26,27,25,-1,62,60,61,63,-1,26,28,29,27,-1,64,62,63,65,-1,28,30,31,29,-1,66,64,65,67,-1,30,32,33,31,-1,68,66,67,69,-1,32,34,35,33,-1,70,68,69,71,-1,35,34,70,71,-1],
          coord=Coordinate(DEF='WallCoordinates',point=[(4.5,-8.5344,3.0),(7.625,-8.5344,3.0),(7.625,0.9144,3.0),(4.5,0.9144,3.0),(10.25,-8.5344,0.375),(10.25,0.9144,0.375),(7.9834,-0.1024,2.6421),(9.8989,-0.1024,0.7328),(9.8989,-3.0484,0.7328),(7.9834,-3.0484,2.6421),(7.9834,-4.3684,2.6421),(9.8989,-4.3684,0.7328),(9.8989,-6.7054,0.7328),(7.9834,-6.7054,2.6421),(10.25,-8.5344,-4.375),(10.25,0.9144,-4.375),(10.25,0.0,-0.425),(10.25,0.0,-3.575),(10.25,-2.7432,-3.575),(10.25,-2.7432,-0.425),(10.25,-4.5752,-0.425),(10.25,-4.5752,-3.575),(10.25,-7.3152,-3.575),(10.25,-7.3152,-0.425),(6.375,-8.5344,-8.0),(6.375,0.9144,-8.0),(-5.5,-8.5344,-8.0),(-5.5,0.9144,-8.0),(-10.5,-8.5344,-2.875),(-10.5,0.9144,-2.875),(-10.5,-8.5344,0.25),(-10.5,0.9144,0.25),(-7.625,-8.5344,3.0),(-7.625,0.9144,3.0),(-4.5,-8.5344,3.0),(-4.5,0.9144,3.0),(4.5,-8.5344,2.7),(7.625,-8.5344,2.7),(7.625,0.9144,2.7),(4.5,0.9144,2.7),(9.95,-8.5344,0.375),(9.95,0.9144,0.375),(7.942,-0.1024,2.383),(9.633,-0.1024,0.692),(9.633,-3.0484,0.692),(7.942,-3.0484,2.383),(7.942,-4.3684,2.383),(9.633,-4.3684,0.692),(9.633,-6.7054,0.692),(7.942,-6.7054,2.383),(9.95,-8.5344,-4.375),(9.95,0.9144,-4.375),(9.95,0.0,-0.425),(9.95,0.0,-3.575),(9.95,-2.7432,-3.575),(9.95,-2.7432,-0.425),(9.95,-4.5752,-0.425),(9.95,-4.5752,-3.575),(9.95,-7.3152,-3.575),(9.95,-7.3152,-0.425),(6.375,-8.5344,-7.7),(6.375,0.9144,-7.7),(-5.5,-8.5344,-7.7),(-5.5,0.9144,-7.7),(-10.2,-8.5344,-2.875),(-10.2,0.9144,-2.875),(-10.2,-8.5344,0.25),(-10.2,0.9144,0.25),(-7.625,-8.5344,2.7),(-7.625,0.9144,2.7),(-4.5,-8.5344,2.7),(-4.5,0.9144,2.7),(7.9556,-0.1024,2.4694),(9.7194,-0.1024,0.70562),(9.7194,-3.0484,0.70562),(7.9556,-3.048,2.4694),(7.9556,-4.3684,2.4694),(9.7194,-4.3684,0.70562),(9.7194,-6.7054,0.70562),(7.9556,-6.7054,2.4694),(10.05,0.0,-0.425),(10.05,0.0,-3.575),(10.05,-2.7432,-3.575),(10.05,-2.7432,-0.425),(10.05,-4.5752,-0.425),(10.05,-4.5752,-3.575),(10.05,-7.3152,-3.575),(10.05,-7.3152,-0.425),(5.3025,-8.5344,3.0),(6.8225,-8.5344,3.0),(7.625,-6.5939,3.0),(7.625,-5.9639,3.0),(7.625,-2.2977,3.0),(7.625,-1.6677,3.0),(6.8225,0.9144,3.0),(5.3025,0.9144,3.0),(4.5,-1.6677,3.0),(4.5,-2.2977,3.0),(4.5,-5.9639,3.0),(4.5,-6.5939,3.0),(5.3025,-1.6677,3.0),(5.7484,-1.2222,3.0),(6.378,-1.2222,3.0),(6.8225,-1.6677,3.0),(6.8225,-2.2977,3.0),(6.378,-2.7432,3.0),(5.7484,-2.7432,3.0),(5.3025,-2.2977,3.0),(5.3025,-5.9639,3.0),(5.748,-5.5184,3.0),(6.378,-5.5184,3.0),(6.8225,-5.9639,3.0),(6.8225,-6.5939,3.0),(6.378,-7.0394,3.0),(5.748,-7.0394,3.0),(5.3025,-6.5939,3.0),(5.3025,-8.5344,2.7),(6.8225,-8.5344,2.7),(7.625,-6.5939,2.7),(7.625,-5.9639,2.7),(7.625,-2.2977,2.7),(7.625,-1.6677,2.7),(6.8225,0.9144,2.7),(5.3025,0.9144,2.7),(4.5,-1.6677,2.7),(4.5,-2.2977,2.7),(4.5,-5.9639,2.7),(4.5,-6.5939,2.7),(5.3025,-1.6677,2.7),(5.7484,-1.2222,2.7),(6.378,-1.2222,2.7),(6.8225,-1.6677,2.7),(6.8225,-2.2977,2.7),(6.378,-2.7432,2.7),(5.7484,-2.7432,2.7),(5.3025,-2.2977,2.7),(5.3025,-5.9639,2.7),(5.748,-5.5184,2.7),(6.378,-5.5184,2.7),(6.8225,-5.9639,2.7),(6.8225,-6.5939,2.7),(6.378,-7.0394,2.7),(5.748,-7.0394,2.7),(5.3025,-6.5939,2.7),(5.3025,-1.6677,2.9),(5.7484,-1.2222,2.9),(6.378,-1.2222,2.9),(6.8225,-1.6677,2.9),(6.8225,-2.2977,2.9),(6.378,-2.7432,2.9),(5.7484,-2.7432,2.9),(5.3025,-2.2977,2.9),(5.3025,-5.9639,2.9),(5.748,-5.5184,2.9),(6.378,-5.5184,2.9),(6.8225,-5.9639,2.9),(6.8225,-6.5939,2.9),(6.378,-7.0394,2.9),(5.748,-7.0394,2.9),(5.3025,-6.5939,2.9)]))),
      Transform(
        children=[
        Shape(
          appearance=Appearance(
            material=Material(diffuseColor=(1.0,0.0,0.0))),
          geometry=IndexedFaceSet(
            coord=Coordinate(USE='WallCoordinates')))]),
      Transform(
        children=[
        Shape(
          appearance=Appearance(USE='Glass'),
          geometry=IndexedFaceSet(coordIndex=[151,150,149,148,147,146,145,144,-1,159,158,157,156,155,154,153,152,-1,128,129,130,131,132,133,134,135,-1,136,137,138,139,140,141,142,143,-1,75,74,73,72,-1,79,78,77,76,-1,42,43,44,45,-1,46,47,48,49,-1,83,82,81,80,-1,87,86,85,84,-1,52,53,54,55,-1,56,57,58,59,-1],
            coord=Coordinate(USE='WallCoordinates')))]),
      Shape(DEF='Beam',
        appearance=Appearance(DEF='BeamAppearance',
          material=Material(ambientIntensity=0.0,diffuseColor=(0.0,0.0,0.0),shininess=0.19)),
        geometry=IndexedFaceSet(coordIndex=[0,1,2,3,-1,7,6,5,4,-1,4,5,1,0,-1,5,6,2,1,-1,6,7,3,2,-1,0,3,7,4,-1],
          coord=Coordinate(point=[(-0.1,0.91,0.1),(0.1,0.91,0.1),(0.1,0.91,-0.1),(-0.1,0.91,-0.1),(-0.1,-7.21,0.1),(0.1,-7.21,0.1),(0.1,-7.21,-0.1),(-0.1,-7.21,-0.1)]))),
      Transform(DEF='RightBeam',rotation=(0.0,1.0,0.0,-0.4),translation=(2.5,0.0,1.0),
        children=[
        Shape(USE='Beam')]),
      Transform(DEF='LeftBeam',rotation=(0.0,1.0,0.0,0.4),translation=(-2.5,0.0,1.0),
        children=[
        Shape(USE='Beam')]),
      Shape(
        appearance=Appearance(USE='BeamAppearance'),
        geometry=IndexedFaceSet(coordIndex=[0,5,6,1,-1,1,6,7,2,-1,2,7,8,3,-1,3,8,9,4,-1,10,0,1,11,-1,11,1,2,12,-1,12,2,3,13,-1,13,3,4,14,-1,14,19,18,13,-1,13,18,17,12,-1,12,17,16,11,-1,11,16,15,10,-1,9,8,18,19,-1,8,7,17,18,-1,7,6,16,17,-1,6,5,15,16,-1],
          coord=Coordinate(point=[(-4.5,-2.8,3.0),(-2.5,-2.8,1.0),(0.0,-2.8,0.0),(2.5,-2.8,1.0),(4.5,-2.8,3.0),(-4.5,-3.0,3.0),(-2.5,-3.0,1.0),(0.0,-3.0,0.0),(2.5,-3.0,1.0),(4.5,-3.0,3.0),(-4.4,-2.8,2.875),(-2.5,-2.8,0.75),(0.0,-2.8,-0.25),(2.5,-2.8,0.75),(4.5,-2.8,2.875),(-4.5,-3.0,2.875),(-2.5,-3.0,0.75),(0.0,-3.0,-0.25),(2.5,-3.0,0.75),(4.5,-3.0,2.875)]))),
      Transform(translation=(0.0,-8.5344,0.0),
        children=[
        Shape(
          appearance=Appearance(
            material=Material(diffuseColor=(0.4,0.2,0.1))),
          geometry=Box(size=(40.0,0.1,40.0)))]),
      Transform(translation=(0,0.015,0),
        children=[
        Shape(
          appearance=Appearance(
            material=Material(diffuseColor=(0.6,0.545,0.502))),
          geometry=IndexedFaceSet(coordIndex=[0,13,1,-1,1,13,2,-1,2,13,3,-1,3,13,14,-1,3,14,4,-1,4,14,15,-1,4,15,5,-1,5,15,16,-1,5,16,6,-1,6,16,17,-1,6,17,7,-1,7,17,18,-1,7,18,8,-1,8,18,19,-1,8,19,9,-1,9,19,20,-1,9,20,10,-1,10,20,11,-1,11,20,13,-1,11,13,12,-1,12,13,0,-1],solid=False,
            coord=Coordinate(point=[(0.0,0.915,-0.3),(2.5,0.915,0.7),(4.5,0.915,2.7),(7.625,0.915,2.7),(9.95,0.915,0.375),(9.95,0.915,-4.375),(6.375,0.915,-7.7),(-5.5,0.915,-7.7),(-10.2,0.915,-2.875),(-10.2,0.915,0.25),(-7.625,0.915,2.7),(-4.5,0.915,2.7),(-2.5,0.915,0.7),(0.0,1.01,10.0),(15.0,1.01,10.0),(15.0,1.01,0.0),(15.0,1.01,-15.0),(0.0,1.01,-15.0),(-15.0,1.01,-15.0),(-15.0,1.01,0.0),(-15.0,1.01,10.0)])))]),
      Transform(translation=(-5.125,0.5,-6.875),
        children=[
        Shape(
          appearance=Appearance(
            material=Material(diffuseColor=(0.5451,0.5333,0.4745),shininess=0.0)),
          geometry=Cylinder(height=3.0))])])])
)

### X3D model conversion complete ###

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

print('Self-test diagnostics for KelpTank.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 KelpTank.py load and self-test diagnostics complete.")
