###############################################

# X3D Package for Python x3d.py

# generator:  X3duomToX3dPythonPackage.xslt
# X3DUOM:     X3dUnifiedObjectModel-4.0.xml
# Python X3D: https://www.web3d.org/x3d/stylesheets/python/python.html
"""
The x3d.py Python X3D Package supports programmers with Python interfaces and objects for standards-based X3D programming, all as open source.

This work is part of the X3D Python Scene Access Interface Library (X3DPSAIL).
"""

_DEBUG = True       # options True False
    
###############################################

# SimpleType Enumerations

ACCESSTYPECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'initializeOnly', # A field with accessType initializeOnly can be initialized, but cannot send or receive events.
    'inputOnly', # A field with accessType inputOnly cannot be initialized or included in a scene file, but can receive input event values via a ROUTE.
    'outputOnly', # A field with accessType outputOnly cannot be initialized or included in a scene file, but can send output event values via a ROUTE.
    'inputOutput' # A field with accessType inputOutput can be initialized, and can also send or receive events.
)
def assertValidAccessType(fieldName, value):
    """
    Utility function to assert type validity of accessTypeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in ACCESSTYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in ACCESSTYPECHOICES=' + str(ACCESSTYPECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in ACCESSTYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in ACCESSTYPECHOICES=' + str(ACCESSTYPECHOICES))

APPLIEDPARAMETERSCHOICES = (
    # note these MFString values use XML syntax
    # strict set of allowed values follow, no other values are valid
    '"BOUNCE"', # The bounce field value is used.
    '"USER_FRICTION"', # The system will normally calculate the friction direction vector that is perpendicular to the contact normal. This setting indicates that the user-supplied value in this contact should be used.
    '"FRICTION_COEFFICIENT2"', # Apply frictionCoefficients values
    '"ERROR_REDUCTION"', # Apply softnessErrorCorrection value
    '"CONSTANT_FORCE"', # Apply softnessConstantForceMix value
    '"SPEED1"', # Apply first component of surfaceSpeed array
    '"SPEED2"', # Apply second component of surfaceSpeed array
    '"SLIP1"', # Apply first component of slipFactors array
    '"SLIP2"' # Apply second component of slipFactors array
)
def assertValidAppliedParameters(fieldName, value):
    """
    Utility function to assert type validity of appliedParametersChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in APPLIEDPARAMETERSCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in APPLIEDPARAMETERSCHOICES=' + str(APPLIEDPARAMETERSCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in APPLIEDPARAMETERSCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in APPLIEDPARAMETERSCHOICES=' + str(APPLIEDPARAMETERSCHOICES))

CLOSURETYPECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'PIE',
    'CHORD'
)
def assertValidClosureType(fieldName, value):
    """
    Utility function to assert type validity of closureTypeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in CLOSURETYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in CLOSURETYPECHOICES=' + str(CLOSURETYPECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in CLOSURETYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in CLOSURETYPECHOICES=' + str(CLOSURETYPECHOICES))

COLORMODECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'POINT_COLOR',
    'TEXTURE_COLOR',
    'TEXTURE_AND_POINT_COLOR'
)
def assertValidColorMode(fieldName, value):
    """
    Utility function to assert type validity of colorModeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in COLORMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in COLORMODECHOICES=' + str(COLORMODECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in COLORMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in COLORMODECHOICES=' + str(COLORMODECHOICES))

COMPONENTNAMECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'Core', # The Core component supplies the base functionality for the X3D run-time system, including the abstract base node type, field types, the event model, and routing.
    'CADGeometry', # The CADGeometry component is provided for Computer-Aided Design (CAD) nodes.
    'CubeMapTexturing', # The Cube Map Environmental Texturing component describes how additional texturing effects are defined to produce environmental effects such as reflections from objects.
    'DIS', # The Distributed Interactive Simulation (DIS) component provides networked interoperability with the IEEE DIS protocol for sharing state and conducting real-time platform-level simulations across multiple host computers.
    'EnvironmentalEffects', # Nodes in the Environmental effects component support the creation of realistic environmental effects such as panoramic backgrounds and fog.
    'EnvironmentalSensor', # The Environment Sensor nodes emit events indicating activity in the scene environment, usually based on interactions between the viewer and the world.
    'EventUtilities', # The Event Utility nodes provide the capability to filter, trigger, convert, or sequence numerous event-types for common interactive applications without the use of a Script node.
    'Followers', # The Follower nodes (Chasers and Dampers) support dynamic creation of smooth parameter transitions at run time.
    'Geometry2D', # The Geometry2D component defines how two-dimensional geometry is specified and what shapes are available.
    'Geometry3D', # The Geometry3D component describes how three-dimensional geometry is specified and defines ElevationGrid, Extrusion, IndexedFaceSet, and most primitive geometry nodes (Box, Cone, Cylinder, Sphere).
    'Geospatial', # The Geospatial component defines how to associate real-world locations in an X3D scene and specifies nodes particularly tuned for geospatial applications.
    'Grouping', # The Grouping component describes how nodes are organized into groups to establish a transformation hierarchy for the X3D scene graph.
    'HAnim', # The Humanoid Animation (HAnim) component for X3D defines node bindings and other details for implementing ISO/IEC 19774, the HAnim International Specification.
    'HAnim', # Legacy enumeration H-Anim for X3Dv3 provides backwards compatibility with Humanoid Animation (HAnim) version 1, preferred form is HAnim.
    'Interpolation', # Interpolator nodes provide keyframe-based animation capability.
    'KeyDeviceSensor', # The Key Device Sensor defines how keyboard keystrokes are inserted into an X3D world.
    'Layering', # The Layering component describes how to layer a set of subscene layers into a composite scene.
    'Layout', # The Layout component defines how to precisely position content in a scene in relation to the rendered results, especially for integrating 2D content with 3D content.
    'Lighting', # The Lighting component specifies how light sources are defined and positioned, as well as how lights effect the rendered image.
    'Navigation', # The Navigation component specifies how a user can effectively and intuitively move through and around a 3D scene.
    'Networking', # The Networking component defines node types and other features used to access file-based and streaming resources on the World Wide Web.
    'NURBS', # The NURBS component describes Non-uniform Rational B-Spline (NURBS) geometry and interpolation nodes.
    'ParticleSystems', # The Particle Systems component specifies how to model particles and their interactions through the application of basic physics principles to affect motion.
    'Picking', # The Picking component provides the ability to test for arbitrary object collision and provide basic capabilities to detecting object intersections and interactions.
    'PointingDeviceSensor', # Pointing device sensor nodes detect pointing events from user-interface devices, defining activities such as a user selecting a piece of geometry.
    'Rendering', # The Rendering component includes fundamental rendering primitives such as TriangleSet and PointSet nodes, as well as geometric properties nodes that define how coordinate indices, colors, normals and texture coordinates are specified.
    'RigidBodyPhysics', # The Rigid Body Physics component describes how to model rigid bodies and their interactions through the application of basic physics principles to effect motion.
    'Scripting', # The Script component describes how Script nodes are used to effect changes in X3D worlds.
    'Shaders', # The programmable shaders component describes how programmable shaders are specified and how they affect the visual appearance of geometry.
    'Shape', # The Shape component defines nodes for associating geometry with their visible properties and the scene environment.
    'Sound', # The Sound component defines how sound is delivered to an X3D world as well as how sounds are accessed.
    'Text', # The Text component defines how text strings are rendered in an X3D scene.
    'Texturing', # The Texturing component specifies how 2D texture images are defined and then positioned on associated geometry.
    'Texturing3D', # The Texturing3D component specifies how 3D volumetric textures describe surface properties as data points in a volume of space, rather than a flat surface.
    'Time', # The Time component defines how time is sensed, computed and associated with events in an X3D scene.
    'VolumeRendering' # The Volume Rendering component provides the ability to specify and render volumetric data sets.
)
def assertValidComponentName(fieldName, value):
    """
    Utility function to assert type validity of componentNameChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in COMPONENTNAMECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in COMPONENTNAMECHOICES=' + str(COMPONENTNAMECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in COMPONENTNAMECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in COMPONENTNAMECHOICES=' + str(COMPONENTNAMECHOICES))

FIELDTYPECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'SFBool',
    'MFBool',
    'SFColor',
    'MFColor',
    'SFColorRGBA',
    'MFColorRGBA',
    'SFDouble',
    'MFDouble',
    'SFFloat',
    'MFFloat',
    'SFImage',
    'MFImage',
    'SFInt32',
    'SFNode',
    'MFNode',
    'MFInt32',
    'SFRotation',
    'MFRotation',
    'SFString',
    'MFString',
    'SFTime',
    'MFTime',
    'SFVec2d',
    'MFVec2d',
    'SFVec2f',
    'MFVec2f',
    'SFVec3d',
    'MFVec3d',
    'SFVec3f',
    'MFVec3f',
    'SFVec4d',
    'MFVec4d',
    'SFVec4f',
    'MFVec4f',
    'SFMatrix3d',
    'MFMatrix3d',
    'SFMatrix3f',
    'MFMatrix3f',
    'SFMatrix4d',
    'MFMatrix4d',
    'SFMatrix4f',
    'MFMatrix4f'
)
def assertValidFieldType(fieldName, value):
    """
    Utility function to assert type validity of fieldTypeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in FIELDTYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in FIELDTYPECHOICES=' + str(FIELDTYPECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in FIELDTYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in FIELDTYPECHOICES=' + str(FIELDTYPECHOICES))

FOGTYPECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'LINEAR',
    'EXPONENTIAL'
)
def assertValidFogType(fieldName, value):
    """
    Utility function to assert type validity of fogTypeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in FOGTYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in FOGTYPECHOICES=' + str(FOGTYPECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in FOGTYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in FOGTYPECHOICES=' + str(FOGTYPECHOICES))

FONTFAMILYVALUES = (
    # specification-defined values follow, other values are also allowed
    '"SANS"',
    '"SERIF"',
    '"TYPEWRITER"'
)

FONTSTYLECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'PLAIN',
    'BOLD',
    'ITALIC',
    'BOLDITALIC'
)
def assertValidFontStyle(fieldName, value):
    """
    Utility function to assert type validity of fontStyleChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in FONTSTYLECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in FONTSTYLECHOICES=' + str(FONTSTYLECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in FONTSTYLECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in FONTSTYLECHOICES=' + str(FONTSTYLECHOICES))

FORCEOUTPUTVALUES = (
    # specification-defined values follow, other values are also allowed
    '"ALL"',
    '"NONE"'
)

GENERATEDCUBEMAPTEXTUREUPDATECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'NONE',
    'NEXT_FRAME_ONLY',
    'ALWAYS'
)
def assertValidGeneratedCubeMapTextureUpdate(fieldName, value):
    """
    Utility function to assert type validity of generatedCubeMapTextureUpdateChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in GENERATEDCUBEMAPTEXTUREUPDATECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in GENERATEDCUBEMAPTEXTUREUPDATECHOICES=' + str(GENERATEDCUBEMAPTEXTUREUPDATECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in GENERATEDCUBEMAPTEXTUREUPDATECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in GENERATEDCUBEMAPTEXTUREUPDATECHOICES=' + str(GENERATEDCUBEMAPTEXTUREUPDATECHOICES))

GEOMETADATAKEYVALUES = (
    # specification-defined values follow, other values are also allowed
    'title',
    'description',
    'coordinateSystem',
    'horizontalDatum',
    'verticalDatum',
    'ellipsoid',
    'extent',
    'resolution',
    'originator',
    'copyright',
    'date',
    'metadataFormat',
    'dataUrl',
    'dataFormat'
)

GEOSYSTEMVALUES = (
    # specification-defined values follow, other values are also allowed
    'GD', # Geodetic spatial reference frame
    'GC', # Geocentric spatial reference frame
    'UTM', # Universal Transverse Mercator
    'AM', # Modified Airy
    'AN', # Australian National
    'BN', # Bessel 1841 (Namibia)
    'BR', # Bessel 1841 (Ethiopia Indonesia ...)
    'CC', # Clarke 1866
    'CD', # Clarke 1880
    'EA', # Everest (India 1830)
    'EB', # Everest (Sabah & Sarawak)
    'EC', # Everest (India 1956)
    'ED', # Everest (W. Malaysia 1969)
    'EE', # Everest (W. Malaysia & Singapore 1948)
    'EF', # Everest (Pakistan)
    'FA', # Modified Fischer 1960
    'HE', # Helmert 1906
    'HO', # Hough 1960
    'ID', # Indonesia 1974
    'IN', # International 1924
    'KA', # Krassovsky 1940
    'RF', # Geodetic Reference System 1980 (GRS 80)
    'SA', # South American 1969
    'WD', # WGS 72
    'WE', # WGS 84
    'WGS84', # WGS84 geoid
    'Zn', # Zone number (1..60) (only used with UTM)
    'S' # Southern hemisphere (only used with UTM)
)

HANIMFEATUREPOINTNAMEVALUES = (
    # specification-defined values follow, other values are also allowed
    'skull_vertex', # CAESAR 2003 skull_vertex matches ISO 7250-1 part 5.22 Vertex (top of head). No corresponding landmark provided in CAESAR 2018.
    'glabella', # glabella is between the eyebrows and above the nose
    'sellion', # osseocartilaginous junction of the nasal dorsum
    'l_infraorbitale', # Left Infraorbitale foramen is opening in maxillary bone of skull located below the infraorbital margin of the orbit.
    'l_tragion', # notch just above the tragus of the ear
    'l_gonion', # Left Gonion is midpoint of mandibular angle of the jaw.
    'r_infraorbitale', # Right Infraorbitale foramen is opening in maxillary bone of skull located below the infraorbital margin of the orbit.
    'r_tragion', # notch just above the tragus of the ear
    'r_gonion', # Right Gonion is midpoint of the mandibular angle of the jaw.
    'supramenton', # center point above tip of chin
    'cervicale',
    'adams_apple',
    'suprasternale', # Suprasternale
    'substernale',
    'l_clavicle',
    'l_acromion',
    'l_axilla_proximal', # Left Axilla Proximal (Anterior)
    'l_axilla_distal', # Left Axilla Distal (Posterior)
    'l_axilla_posterior_folds',
    'r_clavicle',
    'r_acromion',
    'r_axilla_proximal', # Right Axilla Proximal (Anterior)
    'r_axilla_distal', # Right Axilla Distal (Posterior)
    'r_axilla_posterior_folds', # Right Posterior Axillary Folds
    'spine_1_middle_back',
    'spine_2_lower_back',
    'waist_preferred_anterior',
    'waist_preferred_posterior',
    'l_rib10',
    'l_thelion',
    'r_rib10',
    'r_thelion',
    'l_asis',
    'l_iliocristale',
    'l_psis',
    'r_asis',
    'r_iliocristale',
    'r_psis',
    'crotch',
    'l_femoral_lateral_epicondyle',
    'l_femoral_medial_epicondyle',
    'l_suprapatella',
    'l_trochanterion',
    'r_femoral_lateral_epicondyle',
    'r_femoral_medial_epicondyle',
    'r_suprapatella',
    'r_trochanterion',
    'l_tibiale',
    'l_medial_malleolus',
    'l_lateral_malleolus',
    'l_sphyrion',
    'r_tibiale',
    'r_medial_malleolus',
    'r_lateral_malleolus',
    'r_sphyrion',
    'l_metatarsal_phalanx_1',
    'l_metatarsal_phalanx_5',
    'l_dactylion',
    'l_calcaneus_posterior',
    'r_metatarsal_phalanx_1',
    'r_metatarsal_phalanx_5',
    'r_dactylion',
    'r_calcaneus_posterior',
    'l_humeral_lateral_epicondyle',
    'l_humeral_medial_epicondyle',
    'l_olecranon',
    'r_humeral_lateral_epicondyle',
    'r_humeral_medial_epicondyle',
    'r_olecranon',
    'l_radiale',
    'l_ulnar_styloid',
    'l_radial_styloid',
    'r_radiale',
    'r_ulnar_styloid',
    'r_radial_styloid',
    'l_metacarpal_phalanx_2',
    'l_metacarpal_phalanx_3',
    'l_metacarpal_phalanx_5',
    'r_metacarpal_phalanx_2',
    'r_metacarpal_phalanx_3',
    'r_metacarpal_phalanx_5',
    'nuchale',
    'l_neck_base',
    'r_neck_base',
    'navel',
    'l_ectocanthus',
    'r_ectocanthus',
    'menton',
    'mesosternale',
    'opisthocranion',
    'l_knee_crease',
    'r_knee_crease',
    'rear_center_midsagittal_plane',
    'buttocks_standing_wall_contact_point',
    'l_chest_midsagittal_plane',
    'r_chest_midsagittal_plane',
    'l_bideltoid',
    'r_bideltoid',
    'l_carpal_distal_phalanx_1',
    'l_carpal_distal_phalanx_2',
    'l_carpal_distal_phalanx_3',
    'l_carpal_distal_phalanx_4',
    'l_carpal_distal_phalanx_5',
    'r_carpal_distal_phalanx_1',
    'r_carpal_distal_phalanx_2',
    'r_carpal_distal_phalanx_3',
    'r_carpal_distal_phalanx_4',
    'r_carpal_distal_phalanx_5',
    'l_tarsal_distal_phalanx_1',
    'l_tarsal_distal_phalanx_2',
    'l_tarsal_distal_phalanx_3',
    'l_tarsal_distal_phalanx_4',
    'l_tarsal_distal_phalanx_5',
    'r_tarsal_distal_phalanx_1',
    'r_tarsal_distal_phalanx_2',
    'r_tarsal_distal_phalanx_3',
    'r_tarsal_distal_phalanx_4',
    'r_tarsal_distal_phalanx_5'
)

HANIMHUMANOIDINFOKEYVALUES = (
    # specification-defined values follow, other values are also allowed
    'authorName',
    'authorEmail',
    'copyright',
    'creationDate',
    'usageRestrictions',
    'humanoidVersion',
    'age',
    'gender',
    'height',
    'weight'
)

HANIMJOINTNAMEVALUES = (
    # specification-defined values follow, other values are also allowed
    'humanoid_root',
    'sacroiliac',
    'l_hip',
    'l_knee',
    'l_talocrural',
    'l_talocalcaneonavicular',
    'l_cuneonavicular_1',
    'l_tarsometatarsal_1',
    'l_metatarsophalangeal_1',
    'l_tarsal_interphalangeal_1',
    'l_cuneonavicular_2',
    'l_tarsometatarsal_2',
    'l_metatarsophalangeal_2',
    'l_tarsal_proximal_interphalangeal_2',
    'l_tarsal_distal_interphalangeal_2',
    'l_cuneonavicular_3',
    'l_tarsometatarsal_3',
    'l_metatarsophalangeal_3',
    'l_tarsal_proximal_interphalangeal_3',
    'l_tarsal_distal_interphalangeal_3',
    'l_calcaneocuboid',
    'l_transversetarsal',
    'l_tarsometatarsal_4',
    'l_metatarsophalangeal_4',
    'l_tarsal_proximal_interphalangeal_4',
    'l_tarsal_distal_interphalangeal_4',
    'l_tarsometatarsal_5',
    'l_metatarsophalangeal_5',
    'l_tarsal_proximal_interphalangeal_5',
    'l_tarsal_distal_interphalangeal_5',
    'r_hip',
    'r_knee',
    'r_talocrural',
    'r_talocalcaneonavicular',
    'r_cuneonavicular_1',
    'r_tarsometatarsal_1',
    'r_metatarsophalangeal_1',
    'r_tarsal_interphalangeal_1',
    'r_cuneonavicular_2',
    'r_tarsometatarsal_2',
    'r_metatarsophalangeal_2',
    'r_tarsal_proximal_interphalangeal_2',
    'r_tarsal_distal_interphalangeal_2',
    'r_cuneonavicular_3',
    'r_tarsometatarsal_3',
    'r_metatarsophalangeal_3',
    'r_tarsal_proximal_interphalangeal_3',
    'r_tarsal_distal_interphalangeal_3',
    'r_calcaneocuboid',
    'r_transversetarsal',
    'r_tarsometatarsal_4',
    'r_metatarsophalangeal_4',
    'r_tarsal_proximal_interphalangeal_4',
    'r_tarsal_distal_interphalangeal_4',
    'r_tarsometatarsal_5',
    'r_metatarsophalangeal_5',
    'r_tarsal_proximal_interphalangeal_5',
    'r_tarsal_distal_interphalangeal_5',
    'vl5',
    'vl4',
    'vl3',
    'vl2',
    'vl1',
    'vt12',
    'vt11',
    'vt10',
    'vt9',
    'vt8',
    'vt7',
    'vt6',
    'vt5',
    'vt4',
    'vt3',
    'vt2',
    'vt1',
    'vc7',
    'vc6',
    'vc5',
    'vc4',
    'vc3',
    'vc2',
    'vc1',
    'skullbase',
    'l_eyelid_joint',
    'r_eyelid_joint',
    'l_eyeball_joint',
    'r_eyeball_joint',
    'l_eyebrow_joint',
    'r_eyebrow_joint',
    'temporomandibular',
    'l_sternoclavicular',
    'l_acromioclavicular',
    'l_shoulder',
    'l_elbow',
    'l_radiocarpal',
    'l_midcarpal_1',
    'l_carpometacarpal_1',
    'l_metacarpophalangeal_1',
    'l_carpal_interphalangeal_1',
    'l_midcarpal_2',
    'l_carpometacarpal_2',
    'l_metacarpophalangeal_2',
    'l_carpal_proximal_interphalangeal_2',
    'l_carpal_distal_interphalangeal_2',
    'l_midcarpal_3',
    'l_carpometacarpal_3',
    'l_metacarpophalangeal_3',
    'l_carpal_proximal_interphalangeal_3',
    'l_carpal_distal_interphalangeal_3',
    'l_midcarpal_4_5',
    'l_carpometacarpal_4',
    'l_metacarpophalangeal_4',
    'l_carpal_proximal_interphalangeal_4',
    'l_carpal_distal_interphalangeal_4',
    'l_carpometacarpal_5',
    'l_metacarpophalangeal_5',
    'l_carpal_proximal_interphalangeal_5',
    'l_carpal_distal_interphalangeal_5',
    'r_sternoclavicular',
    'r_acromioclavicular',
    'r_shoulder',
    'r_elbow',
    'r_radiocarpal',
    'r_midcarpal_1',
    'r_carpometacarpal_1',
    'r_metacarpophalangeal_1',
    'r_carpal_interphalangeal_1',
    'r_midcarpal_2',
    'r_carpometacarpal_2',
    'r_metacarpophalangeal_2',
    'r_carpal_proximal_interphalangeal_2',
    'r_carpal_distal_interphalangeal_2',
    'r_midcarpal_3',
    'r_carpometacarpal_3',
    'r_metacarpophalangeal_3',
    'r_carpal_proximal_interphalangeal_3',
    'r_carpal_distal_interphalangeal_3',
    'r_midcarpal_4_5',
    'r_carpometacarpal_4',
    'r_metacarpophalangeal_4',
    'r_carpal_proximal_interphalangeal_4',
    'r_carpal_distal_interphalangeal_4',
    'r_carpometacarpal_5',
    'r_metacarpophalangeal_5',
    'r_carpal_proximal_interphalangeal_5',
    'r_carpal_distal_interphalangeal_5'
)

HANIMSEGMENTNAMEVALUES = (
    # specification-defined values follow, other values are also allowed
    'sacrum',
    'pelvis',
    'l_thigh',
    'l_calf',
    'l_talus',
    'l_navicular',
    'l_cuneiform_1',
    'l_metatarsal_1',
    'l_tarsal_proximal_phalanx_1',
    'l_tarsal_distal_phalanx_1',
    'l_cuneiform_2',
    'l_metatarsal_2',
    'l_tarsal_proximal_phalanx_2',
    'l_tarsal_middle_phalanx_2',
    'l_tarsal_distal_phalanx_2',
    'l_cuneiform_3',
    'l_metatarsal_3',
    'l_tarsal_proximal_phalanx_3',
    'l_tarsal_middle_phalanx_3',
    'l_tarsal_distal_phalanx_3',
    'l_calcaneus',
    'l_cuboid',
    'l_metatarsal_4',
    'l_tarsal_proximal_phalanx_4',
    'l_tarsal_middle_phalanx_4',
    'l_tarsal_distal_phalanx_4',
    'l_metatarsal_5',
    'l_tarsal_proximal_phalanx_5',
    'l_tarsal_middle_phalanx_5',
    'l_tarsal_distal_phalanx_5',
    'r_thigh',
    'r_calf',
    'r_talus',
    'r_navicular',
    'r_cuneiform_1',
    'r_metatarsal_1',
    'r_tarsal_proximal_phalanx_1',
    'r_tarsal_distal_phalanx_1',
    'r_cuneiform_2',
    'r_metatarsal_2',
    'r_tarsal_proximal_phalanx_2',
    'r_tarsal_middle_phalanx_2',
    'r_tarsal_distal_phalanx_2',
    'r_cuneiform_3',
    'r_metatarsal_3',
    'r_tarsal_proximal_phalanx_3',
    'r_tarsal_middle_phalanx_3',
    'r_tarsal_distal_phalanx_3',
    'r_calcaneus',
    'r_cuboid',
    'r_metatarsal_4',
    'r_tarsal_proximal_phalanx_4',
    'r_tarsal_middle_phalanx_4',
    'r_tarsal_distal_phalanx_4',
    'r_metatarsal_5',
    'r_tarsal_proximal_phalanx_5',
    'r_tarsal_middle_phalanx_5',
    'r_tarsal_distal_phalanx_5',
    'l5',
    'l4',
    'l3',
    'l2',
    'l1',
    't12',
    't11',
    't10',
    't9',
    't8',
    't7',
    't6',
    't5',
    't4',
    't3',
    't2',
    't1',
    'c7',
    'c6',
    'c5',
    'c4',
    'c3',
    'c2',
    'c1',
    'skull',
    'l_eyelid',
    'r_eyelid',
    'l_eyeball',
    'r_eyeball',
    'l_eyebrow',
    'r_eyebrow',
    'jaw',
    'l_clavicle',
    'l_scapula',
    'l_upperarm',
    'l_forearm',
    'l_carpal',
    'l_trapezium',
    'l_metacarpal_1',
    'l_carpal_proximal_phalanx_1',
    'l_carpal_distal_phalanx_1',
    'l_trapezoid',
    'l_metacarpal_2',
    'l_carpal_proximal_phalanx_2',
    'l_carpal_middle_phalanx_2',
    'l_carpal_distal_phalanx_2',
    'l_capitate',
    'l_metacarpal_3',
    'l_carpal_proximal_phalanx_3',
    'l_carpal_middle_phalanx_3',
    'l_carpal_distal_phalanx_3',
    'l_hamate',
    'l_metacarpal_4',
    'l_carpal_proximal_phalanx_4',
    'l_carpal_middle_phalanx_4',
    'l_carpal_distal_phalanx_4',
    'l_metacarpal_5',
    'l_carpal_proximal_phalanx_5',
    'l_carpal_middle_phalanx_5',
    'l_carpal_distal_phalanx_5',
    'r_clavicle',
    'r_scapula',
    'r_upperarm',
    'r_forearm',
    'r_carpal',
    'r_trapezium',
    'r_metacarpal_1',
    'r_carpal_proximal_phalanx_1',
    'r_carpal_distal_phalanx_1',
    'r_trapezoid',
    'r_metacarpal_2',
    'r_carpal_proximal_phalanx_2',
    'r_carpal_middle_phalanx_2',
    'r_carpal_distal_phalanx_2',
    'r_capitate',
    'r_metacarpal_3',
    'r_carpal_proximal_phalanx_3',
    'r_carpal_middle_phalanx_3',
    'r_carpal_distal_phalanx_3',
    'r_hamate',
    'r_metacarpal_4',
    'r_carpal_proximal_phalanx_4',
    'r_carpal_middle_phalanx_4',
    'r_carpal_distal_phalanx_4',
    'r_metacarpal_5',
    'r_carpal_proximal_phalanx_5',
    'r_carpal_middle_phalanx_5',
    'r_carpal_distal_phalanx_5'
)

HANIMVERSIONCHOICES = (
    # strict set of allowed values follow, no other values are valid
    '1.0', # International standard HAnim 19774 version 1 approved by ISO in 2006.
    '1.1', # International standard HAnim 19774 version 1 amendment.
    '2.0' # Draft revision standard HAnim 19774 version 2 under review by ISO in 2018.
)
def assertValidHanimVersion(fieldName, value):
    """
    Utility function to assert type validity of hanimVersionChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in HANIMVERSIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in HANIMVERSIONCHOICES=' + str(HANIMVERSIONCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in HANIMVERSIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in HANIMVERSIONCHOICES=' + str(HANIMVERSIONCHOICES))

INTERSECTIONTYPEVALUES = (
    # specification-defined values follow, other values are also allowed
    'BOUNDS',
    'GEOMETRY'
)

JUSTIFYCHOICES = (
    # note these MFString values use XML syntax
    # strict set of allowed values follow, no other values are valid
    '"MIDDLE"',
    '"MIDDLE" "BEGIN"',
    '"MIDDLE" "END"',
    '"MIDDLE" "FIRST"',
    '"MIDDLE" "MIDDLE"',
    '"BEGIN"',
    '"BEGIN" "BEGIN"',
    '"BEGIN" "END"',
    '"BEGIN" "FIRST"',
    '"BEGIN" "MIDDLE"',
    '"END"',
    '"END" "BEGIN"',
    '"END" "END"',
    '"END" "FIRST"',
    '"END" "MIDDLE"',
    '"FIRST"',
    '"FIRST" "BEGIN"',
    '"FIRST" "END"',
    '"FIRST" "FIRST"',
    '"FIRST" "MIDDLE"'
)
def assertValidJustify(fieldName, value):
    """
    Utility function to assert type validity of justifyChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in JUSTIFYCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in JUSTIFYCHOICES=' + str(JUSTIFYCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in JUSTIFYCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in JUSTIFYCHOICES=' + str(JUSTIFYCHOICES))

LAYOUTALIGNCHOICES = (
    # note these MFString values use XML syntax
    # strict set of allowed values follow, no other values are valid
    '"LEFT" "BOTTOM"',
    '"LEFT" "CENTER"',
    '"LEFT" "TOP"',
    '"CENTER" "BOTTOM"',
    '"CENTER" "CENTER"',
    '"CENTER" "TOP"',
    '"RIGHT" "BOTTOM"',
    '"RIGHT" "CENTER"',
    '"RIGHT" "TOP"'
)
def assertValidLayoutAlign(fieldName, value):
    """
    Utility function to assert type validity of layoutAlignChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in LAYOUTALIGNCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in LAYOUTALIGNCHOICES=' + str(LAYOUTALIGNCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in LAYOUTALIGNCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in LAYOUTALIGNCHOICES=' + str(LAYOUTALIGNCHOICES))

LAYOUTSCALEMODECHOICES = (
    # note these MFString values use XML syntax
    # strict set of allowed values follow, no other values are valid
    '"NONE" "NONE"',
    '"NONE" "FRACTION"',
    '"NONE" "STRETCH"',
    '"NONE" "PIXEL"',
    '"FRACTION" "NONE"',
    '"FRACTION" "FRACTION"',
    '"FRACTION" "STRETCH"',
    '"FRACTION" "PIXEL"',
    '"STRETCH" "NONE"',
    '"STRETCH" "FRACTION"',
    '"STRETCH" "STRETCH"',
    '"STRETCH" "PIXEL"',
    '"PIXEL" "NONE"',
    '"PIXEL" "FRACTION"',
    '"PIXEL" "STRETCH"',
    '"PIXEL" "PIXEL"'
)
def assertValidLayoutScaleMode(fieldName, value):
    """
    Utility function to assert type validity of layoutScaleModeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in LAYOUTSCALEMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in LAYOUTSCALEMODECHOICES=' + str(LAYOUTSCALEMODECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in LAYOUTSCALEMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in LAYOUTSCALEMODECHOICES=' + str(LAYOUTSCALEMODECHOICES))

LAYOUTUNITSCHOICES = (
    # note these MFString values use XML syntax
    # strict set of allowed values follow, no other values are valid
    '"WORLD" "WORLD"',
    '"WORLD" "FRACTION"',
    '"WORLD" "PIXEL"',
    '"FRACTION" "WORLD"',
    '"FRACTION" "FRACTION"',
    '"FRACTION" "PIXEL"',
    '"PIXEL" "WORLD"',
    '"PIXEL" "FRACTION"',
    '"PIXEL" "PIXEL"'
)
def assertValidLayoutUnits(fieldName, value):
    """
    Utility function to assert type validity of layoutUnitsChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in LAYOUTUNITSCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in LAYOUTUNITSCHOICES=' + str(LAYOUTUNITSCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in LAYOUTUNITSCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in LAYOUTUNITSCHOICES=' + str(LAYOUTUNITSCHOICES))

METADIRECTIONCHOICES = (
    # strict set of allowed values follow, no other values are valid
    'rtl', # right-to-left
    'ltr' # left-to-right
)
def assertValidMetaDirection(fieldName, value):
    """
    Utility function to assert type validity of metaDirectionChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in METADIRECTIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in METADIRECTIONCHOICES=' + str(METADIRECTIONCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in METADIRECTIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in METADIRECTIONCHOICES=' + str(METADIRECTIONCHOICES))

METANAMEVALUES = (
    # specification-defined values follow, other values are also allowed
    'accessRights', # permission required to access resource or security status
    'author', # name of individual author
    'contributor', # name of individual contributing to this resource
    'created', # date of initial version
    'creator', # name of original author
    'description', # summary overview describing this resource
    'disclaimer', # statement of denial or disavowal regarding potential claims or responsiblity
    'drawing', # name or reference link to a supporting drawing or sketch file
    'error', # information about an error (or known problem) that can prevent proper operation
    'generator', # authoring tool or translation tool
    'hint', # user hint about resource features or operation
    'identifier', # url address or unique Uniform Resource Identifier (URI) for resource
    'Image', # name or reference link to supporting image file
    'info', # additional info of interest
    'information', # additional information of interest
    'isVersionOf', # Related resource of which the described resource is a version, edition, or adaptation.
    'keywords', # comma-separated tokens, each of which is a keyword of interest
    'license', # content or software license
    'mediator', # entity that mediates access to resource and for whom resource is intended or useful
    'modified', # date of modified version
    'movie', # name or reference link to supporting movie file (note that Dublin Core term is MovingImage)
    'MovingImage', # name or reference link to supporting movie
    'original', # name or reference link to original file or resource
    'photo', # name or reference link to supporting photo file (note that Dublin Core term is Image)
    'photograph', # name or reference link to supporting photograph file (note that Dublin Core term is Image)
    'publisher', # entity responsible for making the resource available
    'reference', # name or reference link to supporting reference
    'requires', # prerequisites for operation or viewing
    'rights', # intellectual property rights (IPR)
    'robots', # search engine and web-spider guidance value: noindex to block page indexing, nofollow to block following links
    'Sound', # name or reference link to supporting sound file
    'source', # related resource from which the described resource is derived
    'specificationSection', # title of relevant specification section
    'specificationUrl', # url for relevant specification section
    'subject', # search-index subject keywords, key phrases, or classification codes
    'Text', # resource consisting primarily of words for reading
    'title', # file name for this resource
    'TODO', # action item "to do" that still needs to be performed
    'translator', # name of person performing translation from another format or language
    'translated', # date of translation from another format or language
    'version', # current version number or ID of this resource
    'warning' # warning information about a known problem that impedes proper operation
)

MULTITEXTUREFUNCTIONVALUES = (
    # specification-defined values follow, other values are also allowed
    '"COMPLEMENT"',
    '"ALPHAREPLICATE"',
    '""'
)

MULTITEXTUREMODEVALUES = (
    # specification-defined values follow, other values are also allowed
    '"ADD"',
    '"ADDSIGNED"',
    '"ADDSIGNED2X"',
    '"ADDSMOOTH"',
    '"BLENDCURRENTALPHA"',
    '"BLENDDIFFUSEALPHA"',
    '"BLENDFACTORALPHA"',
    '"BLENDTEXTUREALPHA"',
    '"DOTPRODUCT3"',
    '"MODULATE"',
    '"MODULATE2X"',
    '"MODULATE4X"',
    '"MODULATEALPHA_ADDCOLOR"',
    '"MODULATEINVALPHA_ADDCOLOR"',
    '"MODULATEINVCOLOR_ADDALPHA"',
    '"OFF"',
    '"REPLACE"',
    '"SELECTARG1"',
    '"SELECTARG2"',
    '"SUBTRACT"'
)

MULTITEXTURESOURCEVALUES = (
    # specification-defined values follow, other values are also allowed
    '"DIFFUSE"',
    '"FACTOR"',
    '"SPECULAR"',
    '""'
)

NAVIGATIONTRANSITIONTYPEVALUES = (
    # specification-defined values follow, other values are also allowed
    '"TELEPORT"',
    '"LINEAR"',
    '"ANIMATE"'
)

NAVIGATIONTYPEVALUES = (
    # specification-defined values follow, other values are also allowed
    '"ANY"',
    '"WALK"',
    '"EXAMINE"',
    '"FLY"',
    '"LOOKAT"',
    '"NONE"',
    '"EXPLORE"'
)

NETWORKMODECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'standAlone',
    'networkReader',
    'networkWriter'
)
def assertValidNetworkMode(fieldName, value):
    """
    Utility function to assert type validity of networkModeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in NETWORKMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in NETWORKMODECHOICES=' + str(NETWORKMODECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in NETWORKMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in NETWORKMODECHOICES=' + str(NETWORKMODECHOICES))

PARTICLESYSTEMGEOMETRYTYPEVALUES = (
    # specification-defined values follow, other values are also allowed
    'LINE',
    'POINT',
    'QUAD',
    'SPRITE',
    'TRIANGLE',
    'GEOMETRY'
)

PHASEFUNCTIONVALUES = (
    # specification-defined values follow, other values are also allowed
    'HenyeyGreenstein',
    'NONE'
)

PICKABLEOBJECTTYPEVALUES = (
    # specification-defined values follow, other values are also allowed
    '"ALL"',
    '"NONE"',
    '"TERRAIN"'
)

PICKSENSORMATCHCRITERIONCHOICES = (
    # strict set of allowed values follow, no other values are valid
    'MATCH_ANY',
    'MATCH_EVERY',
    'MATCH_ONLY_ONE'
)
def assertValidPickSensorMatchCriterion(fieldName, value):
    """
    Utility function to assert type validity of pickSensorMatchCriterionChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in PICKSENSORMATCHCRITERIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in PICKSENSORMATCHCRITERIONCHOICES=' + str(PICKSENSORMATCHCRITERIONCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in PICKSENSORMATCHCRITERIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in PICKSENSORMATCHCRITERIONCHOICES=' + str(PICKSENSORMATCHCRITERIONCHOICES))

PICKSENSORSORTORDERVALUES = (
    # specification-defined values follow, other values are also allowed
    'ANY',
    'CLOSEST',
    'ALL',
    'ALL_SORTED'
)

PROFILENAMECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'Core', # Core Profile includes no nodes and is provided as the basis for custom componentization. Allowed X3D statements for all profiles are: connect ExternProtoDeclare EXPORT field fieldValue IMPORT IS ProtoBody ProtoDeclare ProtoInterface ProtoInstance ROUTE X3D. Allowed X3D nodes for this profile are: MetadataBoolean MetadataDouble MetadataFloat MetadataInteger MetadataSet MetadataString.
    'Interchange', # Interchange Profile equals the minimum subset of nodes needed to display lightweight compelling content. Allowed X3D nodes for this profile are: Appearance Background Box Color ColorInterpolator ColorRGBA Cone Coordinate CoordinateInterpolator Cylinder DirectionalLight Group ImageTexture IndexedFaceSet IndexedLineSet IndexedTriangleFanSet IndexedTriangleSet IndexedTriangleStripSet LineSet Material MetadataBoolean MetadataDouble MetadataFloat MetadataInteger MetadataSet MetadataString MultiTexture MultiTextureCoordinate MultiTextureTransform NavigationInfo Normal NormalInterpolator OrientationInterpolator PixelTexture PointSet PositionInterpolator ScalarInterpolator Shape Sphere TextureCoordinate TextureCoordinateGenerator TextureTransform TimeSensor Transform TriangleFanSet TriangleSet TriangleStripSet Viewpoint WorldInfo.
    'CADInterchange', # CADInterchange Profile adds support for CADGeometry component nodes to Interchange Profile. Allowed X3D nodes for this profile are: Anchor Appearance CADAssembly CADFace CADLayer CADPart Billboard Collision Color ColorRGBA Coordinate DirectionalLight FragmentShader Group ImageTexture IndexedLineSet IndexedQuadSet IndexedTriangleFanSet IndexedTriangleSet IndexedTriangleStripSet Inline LineProperties LineSet LOD Material MetadataBoolean MetadataDouble MetadataFloat MetadataInteger MetadataSet MetadataString MultiShader MultiTexture MultiTextureCoordinate MultiTextureTransform NavigationInfo Normal PixelTexture PointSet QuadSet Shader ShaderAppearance Shape TextureCoordinate TextureCoordinateGenerator TextureTransform Transform TriangleFanSet TriangleSet TriangleStripSet Viewpoint VertexShader WorldInfo.
    'Interactive', # Interactive Profile adds interaction nodes (Anchor, KeySensor) to the minimum subset of nodes needed to display lightweight compelling content. Allowed X3D nodes for this profile are: Anchor Appearance Background BooleanFilter BooleanSequencer BooleanToggle BooleanTrigger Box Color ColorInterpolator ColorRGBA Cone Coordinate CoordinateInterpolator Cylinder CylinderSensor DirectionalLight ElevationGrid Group ImageTexture IndexedFaceSet IndexedLineSet IndexedTriangleFanSet IndexedTriangleSet IndexedTriangleStripSet Inline IntegerSequencer IntegerTrigger KeySensor LineSet Material MetadataBoolean MetadataDouble MetadataFloat MetadataInteger MetadataSet MetadataString MultiTexture MultiTextureCoordinate MultiTextureTransform NavigationInfo Normal NormalInterpolator OrientationInterpolator IndexedTriangleStripSet Inline IntegerSequencer IntegerTrigger KeySensor LineSet Material MetadataBoolean MetadataDouble MetadataFloat MetadataInteger MetadataSet MetadataString MultiTexture MultiTextureCoordinate MultiTextureTransform NavigationInfo Normal NormalInterpolator OrientationInterpolator PixelTexture PlaneSensor PointLight PointSet PositionInterpolator ProximitySensor ScalarInterpolator Shape Sphere SphereSensor SpotLight StringSensor Switch TextureCoordinate TextureCoordinateGenerator TextureTransform TimeSensor TimeTrigger TouchSensor Transform TriangleFanSet TriangleSet TriangleStripSet Viewpoint VisibilitySensor WorldInfo.
    'Immersive', # Immersive Profile equals all of the nodes in the VRML97 Specification, plus various X3D node additions including KeySensor, StringSensor and Scene. Allowed X3D nodes for this profile are: Anchor Appearance AudioClip Background Billboard BooleanFilter BooleanSequencer BooleanToggle BooleanTrigger Box Collision Color ColorInterpolator ColorRGBA Cone Coordinate CoordinateInterpolator Cylinder CylinderSensor DirectionalLight ElevationGrid Extrusion Fog FontStyle Group ImageTexture IndexedFaceSet IndexedLineSet IndexedTriangleFan IndexedTriangleSet IndexedTriangleStripSet Inline IntegerSequencer IntegerTrigger KeySensor LineProperties LineSet LoadSensor LOD Material MetadataBoolean MetadataDouble MetadataFloat MetadataInteger MetadataSet MetadataString MovieTexture MultiTexture MultiTextureCoordinate MultiTextureTransform NavigationInfo Normal NormalInterpolator OrientationInterpolator PixelTexture PlaneSensor PointLight PointSet Polyline2D Polypoint2D PositionInterpolator ProximitySensor Rectangle2D ScalarInterpolator Script Shape Sound Sphere SphereSensor SpotLight StringSensor Switch Text TextureCoordinate TextureCoordinateGenerator TextureTransform TimeSensor TimeTrigger TouchSensor TriangleFanSet TriangleSet TriangleSet2D TriangleStripSet Transform Viewpoint VisibilitySensor WorldInfo.
    'MedicalInterchange', # The MedicalInterchange profile adds support for VolumeRendering component to Interchange profile. Allowed X3D nodes for this profile are: Anchor Arc2D ArcClose2D Appearance Background Billboard BlendedVolumeStyle BooleanFilter BooleanSequencer BooleanToggle BooleanTrigger BoundaryEnhancementVolumeStyle Box CartoonVolumeStyle Circle2D ClipPlane Collision Color ColorInterpolator ColorRGBA ComposedVolumeStyle CompositeTexture3D Cone Coordinate CoordinateDouble CoordinateInterpolator Cylinder DirectionalLight Disk2D EdgeEnhancementVolumeStyle FillProperties FontStyle Group ImageTexture ImageTexture3D IndexedFaceSet IndexedLineSet IndexedTriangleFanSet IndexedTriangleSet IndexedTriangleStripSet Inline IntegerSequencer IntegerTrigger IsoSurfaceVolumeData LineProperties LineSet LOD Material MetadataBoolean MetadataDouble MetadataFloat MetadataInteger MetadataSet MetadataString MultiTexture MultiTextureCoordinate MultiTextureTransform NavigationInfo Normal NormalInterpolator OctTree OpacityMapVolumeStyle OrientationInterpolator OrthoViewpoint PixelTexture PixelTexture3D PointSet Polyline2D Polypoint2D PositionInterpolator ProjectionVolumeStyle Rectangle2D ScalarInterpolator SegmentedVolumeData ShadedVolumeStyle Shape SilhouetteEnhancementVolumeStyle Sphere StaticGroup Switch Text TextureCoordinate TextureCoordinate3D TextureCoordinate4D TextureCoordinateGenerator TextureMatrixTransform TextureProperties TextureTransform TextureTransform3D TimeSensor TimeTrigger ToneMappedVolumeStyle Transform TriangleFanSet TriangleSet TriangleStripSet Viewpoint ViewpointGroup VolumeData WorldInfo.
    'MPEG4Interactive', # MPEGInteractive Profile defines base interoperability with MPEG4 standards to a small subset of nodes needed to display lightweight compelling content. Allowed X3D nodes for this profile are: Anchor Appearance Background Box Color ColorInterpolator ColorRGBA Cone Coordinate CoordinateInterpolator Cylinder CylinderSensor DirectionalLight ElevationGrid Group ImageTexture IndexedFaceSet IndexedLineSet Inline LineSet Material MetadataBoolean MetadataDouble MetadataFloat MetadataInteger MetadataSet MetadataString NavigationInfo NormalInterpolator OrientationInterpolator PixelTexture PlaneSensor PointLight PointSet PositionInterpolator ProximitySensor ScalarInterpolator Shape Sphere SphereSensor SpotLight Switch TextureCoordinate TextureTransform TimeSensor TouchSensor Transform Viewpoint WorldInfo.
    'Full' # The Full Profile corresponds to all Immersive X3D nodes plus all approved/implemented extensions. All X3D nodes and statements are allowed in this profile.
)
def assertValidProfileName(fieldName, value):
    """
    Utility function to assert type validity of profileNameChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in PROFILENAMECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in PROFILENAMECHOICES=' + str(PROFILENAMECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in PROFILENAMECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in PROFILENAMECHOICES=' + str(PROFILENAMECHOICES))

PROJECTIONVOLUMESTYLETYPECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'MAX',
    'MIN',
    'AVERAGE'
)
def assertValidProjectionVolumeStyleType(fieldName, value):
    """
    Utility function to assert type validity of projectionVolumeStyleTypeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in PROJECTIONVOLUMESTYLETYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in PROJECTIONVOLUMESTYLETYPECHOICES=' + str(PROJECTIONVOLUMESTYLETYPECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in PROJECTIONVOLUMESTYLETYPECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in PROJECTIONVOLUMESTYLETYPECHOICES=' + str(PROJECTIONVOLUMESTYLETYPECHOICES))

SHADERLANGUAGEVALUES = (
    # specification-defined values follow, other values are also allowed
    'Cg',
    'GLSL',
    'HLSL'
)

SHADERPARTTYPEVALUES = (
    # specification-defined values follow, other values are also allowed
    'VERTEX',
    'FRAGMENT'
)

TEXTUREBOUNDARYMODECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'CLAMP',
    'CLAMP_TO_EDGE',
    'CLAMP_TO_BOUNDARY',
    'MIRRORED_REPEAT',
    'REPEAT'
)
def assertValidTextureBoundaryMode(fieldName, value):
    """
    Utility function to assert type validity of textureBoundaryModeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in TEXTUREBOUNDARYMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in TEXTUREBOUNDARYMODECHOICES=' + str(TEXTUREBOUNDARYMODECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in TEXTUREBOUNDARYMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in TEXTUREBOUNDARYMODECHOICES=' + str(TEXTUREBOUNDARYMODECHOICES))

TEXTURECOMPRESSIONMODECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'DEFAULT',
    'FASTEST',
    'HIGH',
    'LOW',
    'MEDIUM',
    'NICEST'
)
def assertValidTextureCompressionMode(fieldName, value):
    """
    Utility function to assert type validity of textureCompressionModeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in TEXTURECOMPRESSIONMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in TEXTURECOMPRESSIONMODECHOICES=' + str(TEXTURECOMPRESSIONMODECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in TEXTURECOMPRESSIONMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in TEXTURECOMPRESSIONMODECHOICES=' + str(TEXTURECOMPRESSIONMODECHOICES))

TEXTURECOORDINATEGENERATORMODECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'SPHERE',
    'CAMERASPACENORMAL',
    'CAMERASPACEPOSITION',
    'CAMERASPACEREFLECTIONVECTOR',
    'SPHERELOCAL',
    'COORD',
    'COORDEYE',
    'NOISE',
    'NOISEEYE',
    'SPHEREREFLECT',
    'SPHEREREFLECTLOCAL'
)
def assertValidTextureCoordinateGeneratorMode(fieldName, value):
    """
    Utility function to assert type validity of textureCoordinateGeneratorModeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in TEXTURECOORDINATEGENERATORMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in TEXTURECOORDINATEGENERATORMODECHOICES=' + str(TEXTURECOORDINATEGENERATORMODECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in TEXTURECOORDINATEGENERATORMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in TEXTURECOORDINATEGENERATORMODECHOICES=' + str(TEXTURECOORDINATEGENERATORMODECHOICES))

TEXTUREMAGNIFICATIONMODECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'AVG_PIXEL',
    'DEFAULT',
    'FASTEST',
    'NEAREST_PIXEL',
    'NICEST'
)
def assertValidTextureMagnificationMode(fieldName, value):
    """
    Utility function to assert type validity of textureMagnificationModeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in TEXTUREMAGNIFICATIONMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in TEXTUREMAGNIFICATIONMODECHOICES=' + str(TEXTUREMAGNIFICATIONMODECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in TEXTUREMAGNIFICATIONMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in TEXTUREMAGNIFICATIONMODECHOICES=' + str(TEXTUREMAGNIFICATIONMODECHOICES))

TEXTUREMINIFICATIONMODECHOICES = (
    # strict set of allowed values follow, no other values are valid
    'AVG_PIXEL',
    'AVG_PIXEL_AVG_MIPMAP',
    'AVG_PIXEL_NEAREST_MIPMAP',
    'DEFAULT',
    'FASTEST',
    'NEAREST_PIXEL',
    'NEAREST_PIXEL_AVG_MIPMAP',
    'NEAREST_PIXEL_NEAREST_MIPMAP',
    'NICEST'
)
def assertValidTextureMinificationMode(fieldName, value):
    """
    Utility function to assert type validity of textureMinificationModeChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in TEXTUREMINIFICATIONMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in TEXTUREMINIFICATIONMODECHOICES=' + str(TEXTUREMINIFICATIONMODECHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in TEXTUREMINIFICATIONMODECHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in TEXTUREMINIFICATIONMODECHOICES=' + str(TEXTUREMINIFICATIONMODECHOICES))

UNITCATEGORYCHOICES = (
    # strict set of allowed values follow, no other values are valid
    'angle',
    'force',
    'length',
    'mass'
)
def assertValidUnitCategory(fieldName, value):
    """
    Utility function to assert type validity of unitCategoryChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in UNITCATEGORYCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in UNITCATEGORYCHOICES=' + str(UNITCATEGORYCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in UNITCATEGORYCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in UNITCATEGORYCHOICES=' + str(UNITCATEGORYCHOICES))

VOLUMERENDERINGWEIGHTFUNCTIONCHOICES = (
    # strict set of allowed values follow, no other values are valid
    'CONSTANT',
    'ALPHA1',
    'ALPHA2',
    'ONE_MINUS_ALPHA1',
    'ONE_MINUS_ALPHA2',
    'TABLE'
)
def assertValidVolumeRenderingWeightFunction(fieldName, value):
    """
    Utility function to assert type validity of volumeRenderingWeightFunctionChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in VOLUMERENDERINGWEIGHTFUNCTIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in VOLUMERENDERINGWEIGHTFUNCTIONCHOICES=' + str(VOLUMERENDERINGWEIGHTFUNCTIONCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in VOLUMERENDERINGWEIGHTFUNCTIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in VOLUMERENDERINGWEIGHTFUNCTIONCHOICES=' + str(VOLUMERENDERINGWEIGHTFUNCTIONCHOICES))

X3DVERSIONCHOICES = (
    # strict set of allowed values follow, no other values are valid
    '3.0', # X3D version 3.0 approved by ISO in 2004.
    '3.1', # X3D version 3.1 Amendment 1 approved by ISO in 2005. Backwards compatibility maintained with version 3.0.
    '3.2', # X3D version 3.2 Amendment 2 approved by ISO in 2007. Backwards compatibility maintained with versions 3.0 and 3.1.
    '3.3', # X3D version 3.3 approved by ISO in 2013 as International Standard (IS). Backwards compatibility maintained with versions 3.0, 3.1 and 3.2.
    '4.0' # X3D version 4.0 under final development by Web3D Consortium. Backwards compatibility maintained with versions 3.0, 3.1, 3.2 and 3.3.
)
def assertValidX3dVersion(fieldName, value):
    """
    Utility function to assert type validity of x3dVersionChoices value, otherwise raise X3DTypeError with diagnostic message.
    Note MFString enumeration values are provided in XML syntax, so check accordingly.
    """
    if  not value:
        return True # no failure on empty defaults
    if  isinstance(value,SFString) or isinstance(value,str):
        if str(value) in X3DVERSIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + value + ' does not match allowed enumerations in X3DVERSIONCHOICES=' + str(X3DVERSIONCHOICES))
    if  isinstance(value,MFString):
        if MFString(value).XML() in X3DVERSIONCHOICES:
            return True
        raise X3DTypeError(fieldName + ' value=' + MFString(value).XML() + ' does not match allowed enumerations in X3DVERSIONCHOICES=' + str(X3DVERSIONCHOICES))

###############################################

# Utility Functions

def metaDiagnostics(self, headElement=None):
    """
    Utility function to return any meta info, hint, warning, error, TODO values in this model.
    """
    if  headElement is None:
        headElement = self
    if  isinstance(headElement, X3D):
        headElement = headElement.head
    # print('type(headElement)=' + str(type(headElement)), flush=True) # diagnostic
    if  isinstance(headElement, head):
        result = "meta "
        for each in headElement.children:
            if isinstance(each, meta) and each.name in ('info', 'hint', 'warning', 'error', 'TODO'):
                result += each.name.strip() + ': ' + each.content.strip()
                if  result.endswith('.') or result.endswith(','):
                    result += ' '
                else:
                    result += ', '
        if  result.strip() != "meta":
            return result.rstrip(', ').strip()
    return ''

###############################################

# Field Validation Functions

# Type-specific functions to check for valid values, throw exception if illegal value is found

def fixBoolean(value, default=None):
    """
    Utility function to convert boolean to corresponding Python value.
    """
    # if _DEBUG: print('fixBoolean(value=' + str(value) + ', default=' + str(default) + ')', flush=True)
    if  value is None:
        return default
    if isinstance(value, list) and len(value) == 1:
        # if _DEBUG: print('fixBoolean downcasting by resetting singleton list value=' + str(value) + ' as value=' + str(value[0]), flush=True)
        value = value[0]
    elif isinstance(value, SFBool):
        return value.value # dereference
    elif isinstance(value, MFBool) and len(value) == 1:
        return value.value[0] # dereference
    if value in ('true', 'True'):
        return True
    if value in ('false', 'False'):
        return False
    if isinstance(value, bool):
        return value
    if isinstance(value, list):
        index = 0
        result = value
        for each in value:
#           print('each=' + str(each), flush=True) # debug
            if  each in ('true', 'True'):
                result[index] = True
            elif each in ('false', 'False'):
                result[index] = False
            while isinstance(each, list) and len(each) == 1:
                # if _DEBUG: print('fixBoolean downcasting by extracting singleton list value[' + str(index) + ']=' + str(each) + ' as each[0]=' + str(each[0]), flush=True)
                result[index] = each[0]
            if not isinstance(result[index], bool):
                # print(flush=True)
                raise X3DTypeError('fixBoolean(value=' + str(value) + ') MFBool value[' + str(index) + ']=' + str(each) + ', result[' + str(index) + ']=' + result[index] + ' with type=' + str(type(value)) + ' is not a valid Python bool expression')
            index += 1
        # if _DEBUG: print('...fixBoolean result=' + str(result), flush=True)
        return result
    # print(flush=True)
    raise X3DTypeError('fixBoolean(value=' + str(value) + ') with type=' + str(type(value)) + ') is not a valid Python bool')

def isPositive(value):
    """
    Utility function to confirm positive value(s) greater than or equal to zero.
    """
    if isinstance(value, list) and any(isinstance(x, tuple) for x in value):
        for each in value:
            for element in each:
                if element <= 0:
                    return False
        return True
    if isinstance(value, (list, tuple)):
        for each in value:
            if each <= 0:
                return False
        return True
    if isinstance(value, (int, float)):
        return value > 0

def assertPositive(fieldName, value):
    """
    Utility function to raise X3DTypeError if not isPositive(value).
    """
    # if _DEBUG: print('* debug: assertPositive(' + str(fieldName) + ', ' + str(value) + ')', flush=True);
    assert isPositive(value), fieldName + '=' + str(value) + ' fails assertPositive requirements: value(s) greater than or equal to zero'

def isNonNegative(value):
    """
    Utility function to confirm nonnegative value(s) greater than or equal to zero.
    """
    if isinstance(value, list) and any(isinstance(x, tuple) for x in value):
        for each in value:
            for element in each:
                if element < 0:
                    return False
        return True
    if isinstance(value, (list, tuple)):
        # if _DEBUG: print('isNonNegative: ', value, flush=True);
        for each in value:
            if each < 0:
                return False
        return True
    if isinstance(value, (int, float)):
        return value >= 0

def assertNonNegative(fieldName, value):
    """
    Utility function to raise X3DTypeError if not isNonNegative(value).
    """
    # if _DEBUG: print('* debug: assertNonNegative(' + str(fieldName) + ', ' + str(value) + ')', flush=True);
    assert isNonNegative(value), fieldName + '=' + str(value) + ' fails assertNonNegative requirements: value(s) greater than or equal to zero'

def isZeroToOne(value):
    """
    Utility function to confirm value(s) in range [0..1]
    """
    # if True or _DEBUG: print('* debug: isZeroToOne(' + str(value) + ')', flush=True);
    if isinstance(value, (list, tuple)):
        for each in value:
            if isinstance(each, (list, tuple)):
                for another in each:
                    if not 0 <= another <= 1:
                        return False
            elif not 0 <= each <= 1:
                return False
        return True
    if isinstance(value, (int, float)):
        return 0 <= value <= 1

def assertZeroToOne(fieldName, value):
    """
    Utility function to raise X3DTypeError if not isZeroToOne(value)
    """
    # if _DEBUG: print('* debug: assertZeroToOne(' + str(fieldName) + ', ' + str(value) + ')', flush=True);
    assert isZeroToOne(value), fieldName + '=' + str(value) + ' fails assertZeroToOne requirements: value(s) in range [0..1]'

def isLessThanEquals(value, maximum):
    """
    Utility function to confirm value(s) less than or equal to maximum.
    """
    # if True or _DEBUG: print('* debug: isLessThanEquals(' + str(value) + ')', flush=True);
    if isinstance(value, list) and any(isinstance(x, tuple) for x in value):
        for each in value:
            for element in each:
                if element > maximum:
                    return False
        return True
    if isinstance(value, (list, tuple)):
        for each in value:
            if each > maximum:
                return False
        return True
    if isinstance(value, (int, float)):
        return value <= maximum

def assertLessThanEquals(fieldName, value, maximum):
    """
    Utility function to raise X3DTypeError if not isLessThanEquals(value)
    """
    # if _DEBUG: print('* debug: assertLessThanEquals(' + str(fieldName) + ', ' + str(value) + ')', flush=True);
    assert isLessThanEquals(value, maximum), fieldName + '=' + str(value) + ' fails assertLessThanEquals maximum=' + str(maximum)

def isLessThan(value, maximum):
    """
    Utility function to confirm value(s) less than maximum.
    """
    # if True or _DEBUG: print('* debug: isLessThan(' + str(value) + ')', flush=True);
    if isinstance(value, list) and any(isinstance(x, tuple) for x in value):
        for each in value:
            for element in each:
                if element >= maximum:
                    return False
        return True
    if isinstance(value, (list, tuple)):
        for each in value:
            if each >= maximum:
                return False
        return True
    if isinstance(value, (int, float)):
        return value < maximum

def assertLessThan(fieldName, value, maximum):
    """
    Utility function to raise X3DTypeError if not isLessThan(value)
    """
    # if _DEBUG: print('* debug: assertLessThan(' + str(fieldName) + ', ' + str(value) + ')', flush=True);
    assert isLessThan(value, maximum), fieldName + '=' + str(value) + ' fails assertLessThan maximum=' + str(maximum)

######
def isGreaterThanEquals(value, minimum):
    """
    Utility function to confirm value(s) less than or equal to minimum.
    """
    # if True or _DEBUG: print('* debug: isGreaterThanEquals(' + str(value) + ')', flush=True);
    if isinstance(value, list) and any(isinstance(x, tuple) for x in value):
        for each in value:
            for element in each:
                if element < minimum:
                    return False
        return True
    if isinstance(value, (list, tuple)):
        for each in value:
            if each < minimum:
                return False
        return True
    if isinstance(value, (int, float)):
        return value >= minimum

def assertGreaterThanEquals(fieldName, value, minimum):
    """
    Utility function to raise X3DTypeError if not isGreaterThanEquals(value)
    """
    # if _DEBUG: print('* debug: assertGreaterThanEquals(' + str(fieldName) + ', ' + str(value) + ')', flush=True);
    assert isGreaterThanEquals(value, minimum), fieldName + '=' + str(value) + ' fails assertGreaterThanEquals minimum=' + str(minimum)

def isGreaterThan(value, minimum):
    """
    Utility function to confirm value(s) less than minimum.
    """
    # if True or _DEBUG: print('* debug: isGreaterThan(' + str(value) + ')', flush=True);
    if isinstance(value, list) and any(isinstance(x, tuple) for x in value):
        for each in value:
            for element in each:
                if element <= minimum:
                    return False
        return True
    if isinstance(value, (list, tuple)):
        for each in value:
            if each <= minimum:
                return False
        return True
    if isinstance(value, (int, float)):
        return value > minimum

def assertGreaterThan(fieldName, value, minimum):
    """
    Utility function to raise X3DTypeError if not isGreaterThan(value)
    """
    # if _DEBUG: print('* debug: assertGreaterThan(' + str(fieldName) + ', ' + str(value) + ')', flush=True);
    assert isGreaterThan(value, minimum), fieldName + '=' + str(value) + ' fails assertGreaterThan minimum=' + str(minimum)

def isBoundingBox(value):
    """
    Utility function to confirm legal X3D bounding box value of (-1 -1 -1) or nonnegative triple.
    """
    if value is None:
        return None
    # if True or _DEBUG: print('* debug: isBoundingBox(' + str(value) + ')', 'isinstance(value, tuple)=' + str(isinstance(value, tuple)), 'len(value)=' + str(len(value)), flush=True);
    if isinstance(value, (list, tuple)):
        if len(value) != 3:
            return False
        if value[0] == -1 and value[1] == -1 and value[2] == -1:
            return True
        return isNonNegative(value) # legal bounding box tuple

def assertBoundingBox(fieldName, value):
    """
    Utility function to raise X3DTypeError if not isBoundingBox(value)
    """
    # if True or _DEBUG: print('* debug: assertBoundingBox(' + str(fieldName) + ', ' + str(value) + ')', flush=True);
    assert isBoundingBox(value), fieldName + '=' + str(value) + ' fails assertBoundingBox requirements: must be (-1, -1, -1) or non-negative 3-tuple'

def isValidSFBool(value):
    """
    Utility function to determine type validity of a SFBool value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFBool) and not isinstance(value, MFBool):
            # if _DEBUG: print('SFBool type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFBool)=' + str(isinstance(value, SFBool)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFBool):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFBool) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, bool):
        return False
    return True

def assertValidSFBool(value):
    """
    Utility function to assert type validity of a SFBool value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFBool) and not isinstance(value, MFBool):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFBool')
    if isinstance(value, SFBool):
        value = value.value # dereference value from this base type
    if isinstance(value, MFBool) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, bool):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid bool value (True or False) for SFBool')
    if not isValidSFBool(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python bool value (True or False) for SFBool')
    return True

def isValidMFBool(value):
    """
    Utility function to determine type validity of a MFBool value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFBool) and not isinstance(value, MFBool):
            # if _DEBUG: print('MFBool type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFBool)=' + str(isinstance(value, MFBool)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFBool):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFBool):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFBool):
            each = each.value # dereference
        if not isinstance(each, bool):
            return False
    return True

def assertValidMFBool(value):
    """
    Utility function to assert type validity of a MFBool value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFBool) and not isinstance(value, MFBool):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFBool')
    if isinstance(value, MFBool):
        value = value.value # dereference value from this base type
    if isinstance(value, SFBool) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFBool')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFBool):
            each = each.value # dereference
        if not isinstance(each, bool):
            # print(flush=True)
            raise X3DTypeError('MFBool list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid bool')
    if not isValidMFBool(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFBool')
    return True

def isValidSFColor(value):
    """
    Utility function to determine type validity of a SFColor value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFColor) and not isinstance(value, MFColor):
            # if _DEBUG: print('SFColor type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFColor)=' + str(isinstance(value, SFColor)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFColor):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFColor) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFColor):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
        if (each < 0) or (each > 1):
            return False
    if tupleCount != 3:
        return False
    if not isZeroToOne(value):
        return False
    return True

def assertValidSFColor(value):
    """
    Utility function to assert type validity of a SFColor value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFColor) and not isinstance(value, MFColor):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFColor')
    if isinstance(value, SFColor):
        value = value.value # dereference value from this base type
    if isinstance(value, MFColor) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFColor')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFColor):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFColor list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
        if (each < 0) or (each > 1):
            # print(flush=True)
            raise X3DTypeError('SFColor' + str(value)[:100] + ' has value ' + str(each) + ' with type=' + str(type(value)) + ' is  out of range [0..1] and is not a valid SFColor')
    if tupleCount != 3:
        # print(flush=True)
        raise X3DTypeError('SFColor ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 3')
    assertZeroToOne('SFColor', value)
    if not isValidSFColor(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFColor')
    return True

def isValidMFColor(value):
    """
    Utility function to determine type validity of a MFColor value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFColor) and not isinstance(value, MFColor):
            # if _DEBUG: print('MFColor type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFColor)=' + str(isinstance(value, MFColor)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFColor):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFColor):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFColor.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFColor tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFColor.TUPLE_SIZE=' + str(MFColor.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
            if (element < 0) or (element > 1):
                return False
    if not isZeroToOne(value):
        return False
    return True

def assertValidMFColor(value):
    """
    Utility function to assert type validity of a MFColor value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFColor) and not isinstance(value, MFColor):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFColor')
    if isinstance(value, MFColor):
        value = value.value # dereference value from this base type
    if isinstance(value, SFColor) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFColor')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFColor.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFColor tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFColor.TUPLE_SIZE=' + str(MFColor.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFColor)):
#                # print(flush=True)
#                raise X3DTypeError('MFColor element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFColor element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
                    if (element < 0) or (element > 1):
                        # print(flush=True)
                        raise X3DTypeError('MFColor' + str(value)[:100] + ' has value ' + str(element) + ' with type=' + str(type(value)) + ' out of range [0..1] and is not a valid MFColor')
    assertZeroToOne('MFColor', value)
    if not isValidMFColor(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFColor')
    return True

def isValidSFColorRGBA(value):
    """
    Utility function to determine type validity of a SFColorRGBA value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFColorRGBA) and not isinstance(value, MFColorRGBA):
            # if _DEBUG: print('SFColorRGBA type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFColorRGBA)=' + str(isinstance(value, SFColorRGBA)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFColorRGBA):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFColorRGBA) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFColorRGBA):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
        if (each < 0) or (each > 1):
            return False
    if tupleCount != 4:
        return False
    if not isZeroToOne(value):
        return False
    return True

def assertValidSFColorRGBA(value):
    """
    Utility function to assert type validity of a SFColorRGBA value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFColorRGBA) and not isinstance(value, MFColorRGBA):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFColorRGBA')
    if isinstance(value, SFColorRGBA):
        value = value.value # dereference value from this base type
    if isinstance(value, MFColorRGBA) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFColorRGBA')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFColorRGBA):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFColorRGBA list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
        if (each < 0) or (each > 1):
            # print(flush=True)
            raise X3DTypeError('SFColorRGBA' + str(value)[:100] + ' has value ' + str(each) + ' with type=' + str(type(value)) + ' is  out of range [0..1] and is not a valid SFColorRGBA')
    if tupleCount != 4:
        # print(flush=True)
        raise X3DTypeError('SFColorRGBA ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 4')
    assertZeroToOne('SFColorRGBA', value)
    if not isValidSFColorRGBA(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFColorRGBA')
    return True

def isValidMFColorRGBA(value):
    """
    Utility function to determine type validity of a MFColorRGBA value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFColorRGBA) and not isinstance(value, MFColorRGBA):
            # if _DEBUG: print('MFColorRGBA type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFColorRGBA)=' + str(isinstance(value, MFColorRGBA)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFColorRGBA):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFColorRGBA):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFColorRGBA.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFColorRGBA tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFColorRGBA.TUPLE_SIZE=' + str(MFColorRGBA.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
            if (element < 0) or (element > 1):
                return False
    if not isZeroToOne(value):
        return False
    return True

def assertValidMFColorRGBA(value):
    """
    Utility function to assert type validity of a MFColorRGBA value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFColorRGBA) and not isinstance(value, MFColorRGBA):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFColorRGBA')
    if isinstance(value, MFColorRGBA):
        value = value.value # dereference value from this base type
    if isinstance(value, SFColorRGBA) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFColorRGBA')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFColorRGBA.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFColorRGBA tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFColorRGBA.TUPLE_SIZE=' + str(MFColorRGBA.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFColorRGBA)):
#                # print(flush=True)
#                raise X3DTypeError('MFColorRGBA element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFColorRGBA element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
                    if (element < 0) or (element > 1):
                        # print(flush=True)
                        raise X3DTypeError('MFColorRGBA' + str(value)[:100] + ' has value ' + str(element) + ' with type=' + str(type(value)) + ' out of range [0..1] and is not a valid MFColorRGBA')
    assertZeroToOne('MFColorRGBA', value)
    if not isValidMFColorRGBA(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFColorRGBA')
    return True

def isValidSFDouble(value):
    """
    Utility function to determine type validity of a SFDouble value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFDouble) and not isinstance(value, MFDouble):
            # if _DEBUG: print('SFDouble type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFDouble)=' + str(isinstance(value, SFDouble)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFDouble):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFDouble) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, float) and not isinstance(value, int):
        return False
    return True

def assertValidSFDouble(value):
    """
    Utility function to assert type validity of a SFDouble value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFDouble) and not isinstance(value, MFDouble):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFDouble')
    if isinstance(value, SFDouble):
        value = value.value # dereference value from this base type
    if isinstance(value, MFDouble) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, float) and not isinstance(value, int):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid float value for SFDouble')
    if not isValidSFDouble(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python float value for SFDouble')
    return True

def isValidMFDouble(value):
    """
    Utility function to determine type validity of a MFDouble value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFDouble) and not isinstance(value, MFDouble):
            # if _DEBUG: print('MFDouble type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFDouble)=' + str(isinstance(value, MFDouble)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFDouble):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFDouble):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFDouble):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    return True

def assertValidMFDouble(value):
    """
    Utility function to assert type validity of a MFDouble value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFDouble) and not isinstance(value, MFDouble):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFDouble')
    if isinstance(value, MFDouble):
        value = value.value # dereference value from this base type
    if isinstance(value, SFDouble) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFDouble')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFDouble):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('MFDouble list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if not isValidMFDouble(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFDouble')
    return True

def isValidSFFloat(value):
    """
    Utility function to determine type validity of a SFFloat value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFFloat) and not isinstance(value, MFFloat):
            # if _DEBUG: print('SFFloat type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFFloat)=' + str(isinstance(value, SFFloat)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFFloat):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFFloat) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, float) and not isinstance(value, int):
        return False
    return True

def assertValidSFFloat(value):
    """
    Utility function to assert type validity of a SFFloat value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFFloat) and not isinstance(value, MFFloat):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFFloat')
    if isinstance(value, SFFloat):
        value = value.value # dereference value from this base type
    if isinstance(value, MFFloat) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, float) and not isinstance(value, int):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid float value for SFFloat')
    if not isValidSFFloat(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python float value for SFFloat')
    return True

def isValidMFFloat(value):
    """
    Utility function to determine type validity of a MFFloat value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFFloat) and not isinstance(value, MFFloat):
            # if _DEBUG: print('MFFloat type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFFloat)=' + str(isinstance(value, MFFloat)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFFloat):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFFloat):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFFloat):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    return True

def assertValidMFFloat(value):
    """
    Utility function to assert type validity of a MFFloat value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFFloat) and not isinstance(value, MFFloat):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFFloat')
    if isinstance(value, MFFloat):
        value = value.value # dereference value from this base type
    if isinstance(value, SFFloat) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFFloat')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFFloat):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('MFFloat list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if not isValidMFFloat(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFFloat')
    return True

def isValidSFImage(value):
    """
    Utility function to determine type validity of a SFImage value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFImage) and not isinstance(value, MFImage):
            # if _DEBUG: print('SFImage type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFImage)=' + str(isinstance(value, SFImage)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFImage):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFImage) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, list):
        return False
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFImage):
            each = each.value # dereference
        if not isinstance(each, int):
            return False
    if len(value) > 0: # SFImage list length checks
        if 0 < len(value) < 3:
            return False # SFImage list must start with width, height and number of components (0..4)
        width = value[0]
        height = value[1]
        numberComponents = value[2]
        if  len(value) != (width * height) + 3: # assumes each value in array has all component values in single integer
            print('SFImage array length of ' + str(len(value)) + ' does not equal (width=' + str(width)+ ' * height=' + str(height)+ ') + 3) = ' + str(width * height * numberComponents + 3) + ' (numberComponents=' + numberComponents + ')', flush=True)
            return False # SFImage has invalid list length
    return True

def assertValidSFImage(value):
    """
    Utility function to assert type validity of a SFImage value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFImage) and not isinstance(value, MFImage):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFImage')
    if isinstance(value, SFImage):
        value = value.value # dereference value from this base type
    if isinstance(value, MFImage) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for SFImage')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFImage):
            each = each.value # dereference
        if not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFImage list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid int')
    if not isValidSFImage(value):
        # print(flush=True)
        diagnostic = ''
        if len(value) > 0: # SFImage list length checks
            if 0 < len(value) < 3:
                diagnostic = 'SFImage list must start with width, height and number of components (0..4)'
            else:
                width = value[0]
                height = value[1]
                numberComponents = value[2]
                diagnostic = ' array length of ' + str(len(value)) + ' does not equal (width=' + str(width)+ ' * height=' + str(height)+ ') + 3) = ' + str(width * height + 3)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for SFImage' + diagnostic)
    return True

def isValidMFImage(value):
    """
    Utility function to determine type validity of a MFImage value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFImage) and not isinstance(value, MFImage):
            # if _DEBUG: print('MFImage type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFImage)=' + str(isinstance(value, MFImage)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFImage):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFImage):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFImage):
            each = each.value # dereference
        if not isinstance(each, int):
            return False
    return True

def assertValidMFImage(value):
    """
    Utility function to assert type validity of a MFImage value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFImage) and not isinstance(value, MFImage):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFImage')
    if isinstance(value, MFImage):
        value = value.value # dereference value from this base type
    if isinstance(value, SFImage) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFImage')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFImage):
            each = each.value # dereference
        if not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('MFImage list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid int')
    if not isValidMFImage(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFImage')
    return True

def isValidSFInt32(value):
    """
    Utility function to determine type validity of a SFInt32 value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFInt32) and not isinstance(value, MFInt32):
            # if _DEBUG: print('SFInt32 type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFInt32)=' + str(isinstance(value, SFInt32)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFInt32):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFInt32) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, int):
        return False
    return True

def assertValidSFInt32(value):
    """
    Utility function to assert type validity of a SFInt32 value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFInt32) and not isinstance(value, MFInt32):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFInt32')
    if isinstance(value, SFInt32):
        value = value.value # dereference value from this base type
    if isinstance(value, MFInt32) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, int):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid int value for SFInt32')
    if not isValidSFInt32(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python int value for SFInt32')
    return True

def isValidMFInt32(value):
    """
    Utility function to determine type validity of a MFInt32 value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFInt32) and not isinstance(value, MFInt32):
            # if _DEBUG: print('MFInt32 type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFInt32)=' + str(isinstance(value, MFInt32)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFInt32):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFInt32):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFInt32):
            each = each.value # dereference
        if not isinstance(each, int):
            return False
    return True

def assertValidMFInt32(value):
    """
    Utility function to assert type validity of a MFInt32 value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFInt32) and not isinstance(value, MFInt32):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFInt32')
    if isinstance(value, MFInt32):
        value = value.value # dereference value from this base type
    if isinstance(value, SFInt32) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFInt32')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFInt32):
            each = each.value # dereference
        if not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('MFInt32 list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid int')
    if not isValidMFInt32(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFInt32')
    return True

def isValidSFMatrix3d(value):
    """
    Utility function to determine type validity of a SFMatrix3d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFMatrix3d) and not isinstance(value, MFMatrix3d):
            # if _DEBUG: print('SFMatrix3d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFMatrix3d)=' + str(isinstance(value, SFMatrix3d)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFMatrix3d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFMatrix3d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFMatrix3d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 9:
        return False
    return True

def assertValidSFMatrix3d(value):
    """
    Utility function to assert type validity of a SFMatrix3d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFMatrix3d) and not isinstance(value, MFMatrix3d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFMatrix3d')
    if isinstance(value, SFMatrix3d):
        value = value.value # dereference value from this base type
    if isinstance(value, MFMatrix3d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFMatrix3d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFMatrix3d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFMatrix3d list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 9:
        # print(flush=True)
        raise X3DTypeError('SFMatrix3d ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 9')
    if not isValidSFMatrix3d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFMatrix3d')
    return True

def isValidMFMatrix3d(value):
    """
    Utility function to determine type validity of a MFMatrix3d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFMatrix3d) and not isinstance(value, MFMatrix3d):
            # if _DEBUG: print('MFMatrix3d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFMatrix3d)=' + str(isinstance(value, MFMatrix3d)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFMatrix3d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFMatrix3d):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFMatrix3d.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFMatrix3d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFMatrix3d.TUPLE_SIZE=' + str(MFMatrix3d.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFMatrix3d(value):
    """
    Utility function to assert type validity of a MFMatrix3d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFMatrix3d) and not isinstance(value, MFMatrix3d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFMatrix3d')
    if isinstance(value, MFMatrix3d):
        value = value.value # dereference value from this base type
    if isinstance(value, SFMatrix3d) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFMatrix3d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFMatrix3d.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFMatrix3d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFMatrix3d.TUPLE_SIZE=' + str(MFMatrix3d.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFMatrix3d)):
#                # print(flush=True)
#                raise X3DTypeError('MFMatrix3d element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFMatrix3d element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFMatrix3d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFMatrix3d')
    return True

def isValidSFMatrix3f(value):
    """
    Utility function to determine type validity of a SFMatrix3f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFMatrix3f) and not isinstance(value, MFMatrix3f):
            # if _DEBUG: print('SFMatrix3f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFMatrix3f)=' + str(isinstance(value, SFMatrix3f)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFMatrix3f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFMatrix3f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFMatrix3f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 9:
        return False
    return True

def assertValidSFMatrix3f(value):
    """
    Utility function to assert type validity of a SFMatrix3f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFMatrix3f) and not isinstance(value, MFMatrix3f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFMatrix3f')
    if isinstance(value, SFMatrix3f):
        value = value.value # dereference value from this base type
    if isinstance(value, MFMatrix3f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFMatrix3f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFMatrix3f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFMatrix3f list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 9:
        # print(flush=True)
        raise X3DTypeError('SFMatrix3f ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 9')
    if not isValidSFMatrix3f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFMatrix3f')
    return True

def isValidMFMatrix3f(value):
    """
    Utility function to determine type validity of a MFMatrix3f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFMatrix3f) and not isinstance(value, MFMatrix3f):
            # if _DEBUG: print('MFMatrix3f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFMatrix3f)=' + str(isinstance(value, MFMatrix3f)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFMatrix3f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFMatrix3f):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFMatrix3f.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFMatrix3f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFMatrix3f.TUPLE_SIZE=' + str(MFMatrix3f.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFMatrix3f(value):
    """
    Utility function to assert type validity of a MFMatrix3f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFMatrix3f) and not isinstance(value, MFMatrix3f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFMatrix3f')
    if isinstance(value, MFMatrix3f):
        value = value.value # dereference value from this base type
    if isinstance(value, SFMatrix3f) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFMatrix3f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFMatrix3f.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFMatrix3f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFMatrix3f.TUPLE_SIZE=' + str(MFMatrix3f.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFMatrix3f)):
#                # print(flush=True)
#                raise X3DTypeError('MFMatrix3f element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFMatrix3f element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFMatrix3f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFMatrix3f')
    return True

def isValidSFMatrix4d(value):
    """
    Utility function to determine type validity of a SFMatrix4d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFMatrix4d) and not isinstance(value, MFMatrix4d):
            # if _DEBUG: print('SFMatrix4d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFMatrix4d)=' + str(isinstance(value, SFMatrix4d)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFMatrix4d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFMatrix4d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFMatrix4d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 16:
        return False
    return True

def assertValidSFMatrix4d(value):
    """
    Utility function to assert type validity of a SFMatrix4d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFMatrix4d) and not isinstance(value, MFMatrix4d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFMatrix4d')
    if isinstance(value, SFMatrix4d):
        value = value.value # dereference value from this base type
    if isinstance(value, MFMatrix4d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFMatrix4d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFMatrix4d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFMatrix4d list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 16:
        # print(flush=True)
        raise X3DTypeError('SFMatrix4d ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 16')
    if not isValidSFMatrix4d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFMatrix4d')
    return True

def isValidMFMatrix4d(value):
    """
    Utility function to determine type validity of a MFMatrix4d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFMatrix4d) and not isinstance(value, MFMatrix4d):
            # if _DEBUG: print('MFMatrix4d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFMatrix4d)=' + str(isinstance(value, MFMatrix4d)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFMatrix4d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFMatrix4d):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFMatrix4d.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFMatrix4d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFMatrix4d.TUPLE_SIZE=' + str(MFMatrix4d.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFMatrix4d(value):
    """
    Utility function to assert type validity of a MFMatrix4d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFMatrix4d) and not isinstance(value, MFMatrix4d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFMatrix4d')
    if isinstance(value, MFMatrix4d):
        value = value.value # dereference value from this base type
    if isinstance(value, SFMatrix4d) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFMatrix4d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFMatrix4d.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFMatrix4d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFMatrix4d.TUPLE_SIZE=' + str(MFMatrix4d.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFMatrix4d)):
#                # print(flush=True)
#                raise X3DTypeError('MFMatrix4d element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFMatrix4d element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFMatrix4d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFMatrix4d')
    return True

def isValidSFMatrix4f(value):
    """
    Utility function to determine type validity of a SFMatrix4f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFMatrix4f) and not isinstance(value, MFMatrix4f):
            # if _DEBUG: print('SFMatrix4f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFMatrix4f)=' + str(isinstance(value, SFMatrix4f)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFMatrix4f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFMatrix4f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFMatrix4f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 16:
        return False
    return True

def assertValidSFMatrix4f(value):
    """
    Utility function to assert type validity of a SFMatrix4f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFMatrix4f) and not isinstance(value, MFMatrix4f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFMatrix4f')
    if isinstance(value, SFMatrix4f):
        value = value.value # dereference value from this base type
    if isinstance(value, MFMatrix4f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFMatrix4f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFMatrix4f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFMatrix4f list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 16:
        # print(flush=True)
        raise X3DTypeError('SFMatrix4f ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 16')
    if not isValidSFMatrix4f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFMatrix4f')
    return True

def isValidMFMatrix4f(value):
    """
    Utility function to determine type validity of a MFMatrix4f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFMatrix4f) and not isinstance(value, MFMatrix4f):
            # if _DEBUG: print('MFMatrix4f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFMatrix4f)=' + str(isinstance(value, MFMatrix4f)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFMatrix4f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFMatrix4f):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFMatrix4f.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFMatrix4f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFMatrix4f.TUPLE_SIZE=' + str(MFMatrix4f.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFMatrix4f(value):
    """
    Utility function to assert type validity of a MFMatrix4f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFMatrix4f) and not isinstance(value, MFMatrix4f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFMatrix4f')
    if isinstance(value, MFMatrix4f):
        value = value.value # dereference value from this base type
    if isinstance(value, SFMatrix4f) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFMatrix4f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFMatrix4f.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFMatrix4f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFMatrix4f.TUPLE_SIZE=' + str(MFMatrix4f.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFMatrix4f)):
#                # print(flush=True)
#                raise X3DTypeError('MFMatrix4f element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFMatrix4f element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFMatrix4f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFMatrix4f')
    return True

def isValidSFNode(value):
    """
    Utility function to determine type validity of a SFNode value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFNode) and not isinstance(value, MFNode):
            # if _DEBUG: print('SFNode type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFNode)=' + str(isinstance(value, SFNode)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFNode):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFNode) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, object):
        return False
    return True

def assertValidSFNode(value):
    """
    Utility function to assert type validity of a SFNode value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFNode) and not isinstance(value, MFNode):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFNode')
    if isinstance(value, SFNode):
        value = value.value # dereference value from this base type
    if isinstance(value, MFNode) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, object):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid object value for SFNode')
    if not isValidSFNode(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python object value for SFNode')
    return True

def isValidMFNode(value):
    """
    Utility function to determine type validity of a MFNode value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFNode) and not isinstance(value, MFNode):
            # if _DEBUG: print('MFNode type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFNode)=' + str(isinstance(value, MFNode)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFNode):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFNode):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    for each in value:
        if not isinstance(each, (_X3DNode, _X3DStatement)):
            return False
    return True

def assertValidMFNode(value):
    """
    Utility function to assert type validity of a MFNode value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFNode) and not isinstance(value, MFNode):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFNode')
    if isinstance(value, MFNode):
        value = value.value # dereference value from this base type
    if isinstance(value, SFNode) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    for each in value:
        if not isinstance(each, _X3DNode) and not isinstance(each, _X3DStatement):
            # print(flush=True)
            raise X3DTypeError(str(value)[:100] + ' element ' + str(each) + ', type=' + str(type(each)) + ' is not a valid _X3DNode or _X3DStatement for MFNode')
    if not isValidMFNode(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid _X3DNode or _X3DStatement for MFNode')
    return True

def isValidSFRotation(value):
    """
    Utility function to determine type validity of a SFRotation value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFRotation) and not isinstance(value, MFRotation):
            # if _DEBUG: print('SFRotation type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFRotation)=' + str(isinstance(value, SFRotation)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFRotation):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFRotation) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFRotation):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 4:
        return False
    return True

def assertValidSFRotation(value):
    """
    Utility function to assert type validity of a SFRotation value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFRotation) and not isinstance(value, MFRotation):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFRotation')
    if isinstance(value, SFRotation):
        value = value.value # dereference value from this base type
    if isinstance(value, MFRotation) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFRotation')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFRotation):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFRotation list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 4:
        # print(flush=True)
        raise X3DTypeError('SFRotation ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 4')
    if not isValidSFRotation(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFRotation')
    return True

def isValidMFRotation(value):
    """
    Utility function to determine type validity of a MFRotation value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFRotation) and not isinstance(value, MFRotation):
            # if _DEBUG: print('MFRotation type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFRotation)=' + str(isinstance(value, MFRotation)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFRotation):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFRotation):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFRotation.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFRotation tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFRotation.TUPLE_SIZE=' + str(MFRotation.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFRotation(value):
    """
    Utility function to assert type validity of a MFRotation value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFRotation) and not isinstance(value, MFRotation):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFRotation')
    if isinstance(value, MFRotation):
        value = value.value # dereference value from this base type
    if isinstance(value, SFRotation) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFRotation')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFRotation.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFRotation tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFRotation.TUPLE_SIZE=' + str(MFRotation.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFRotation)):
#                # print(flush=True)
#                raise X3DTypeError('MFRotation element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFRotation element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFRotation(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFRotation')
    return True

def isValidSFString(value):
    """
    Utility function to determine type validity of a SFString value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFString) and not isinstance(value, MFString):
            # if _DEBUG: print('SFString type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFString)=' + str(isinstance(value, SFString)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFString):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFString) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, str):
        return False
    return True

def assertValidSFString(value):
    """
    Utility function to assert type validity of a SFString value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFString) and not isinstance(value, MFString):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFString')
    if isinstance(value, SFString):
        value = value.value # dereference value from this base type
    if isinstance(value, MFString) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, str):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid str value for SFString')
    if not isValidSFString(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python str value for SFString')
    return True

def isValidMFString(value):
    """
    Utility function to determine type validity of a MFString value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFString) and not isinstance(value, MFString):
            # if _DEBUG: print('MFString type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFString)=' + str(isinstance(value, MFString)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFString):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFString):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFString):
            each = each.value # dereference
        if not isinstance(each, str):
            return False
    return True

def assertValidMFString(value):
    """
    Utility function to assert type validity of a MFString value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFString) and not isinstance(value, MFString):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFString')
    if isinstance(value, MFString):
        value = value.value # dereference value from this base type
    if isinstance(value, SFString) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFString')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFString):
            each = each.value # dereference
        if not isinstance(each, str):
            # print(flush=True)
            raise X3DTypeError('MFString list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid str')
    if not isValidMFString(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFString')
    return True

def isValidSFTime(value):
    """
    Utility function to determine type validity of a SFTime value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFTime) and not isinstance(value, MFTime):
            # if _DEBUG: print('SFTime type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFTime)=' + str(isinstance(value, SFTime)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFTime):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFTime) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, float) and not isinstance(value, int):
        return False
    return True

def assertValidSFTime(value):
    """
    Utility function to assert type validity of a SFTime value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFTime) and not isinstance(value, MFTime):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFTime')
    if isinstance(value, SFTime):
        value = value.value # dereference value from this base type
    if isinstance(value, MFTime) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, float) and not isinstance(value, int):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid float value for SFTime')
    if not isValidSFTime(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python float value for SFTime')
    return True

def isValidMFTime(value):
    """
    Utility function to determine type validity of a MFTime value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFTime) and not isinstance(value, MFTime):
            # if _DEBUG: print('MFTime type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFTime)=' + str(isinstance(value, MFTime)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFTime):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFTime):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFTime):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    return True

def assertValidMFTime(value):
    """
    Utility function to assert type validity of a MFTime value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFTime) and not isinstance(value, MFTime):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFTime')
    if isinstance(value, MFTime):
        value = value.value # dereference value from this base type
    if isinstance(value, SFTime) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFTime')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    for each in value:
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFTime):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('MFTime list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if not isValidMFTime(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFTime')
    return True

def isValidSFVec2d(value):
    """
    Utility function to determine type validity of a SFVec2d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec2d) and not isinstance(value, MFVec2d):
            # if _DEBUG: print('SFVec2d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFVec2d)=' + str(isinstance(value, SFVec2d)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFVec2d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFVec2d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec2d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 2:
        return False
    return True

def assertValidSFVec2d(value):
    """
    Utility function to assert type validity of a SFVec2d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec2d) and not isinstance(value, MFVec2d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFVec2d')
    if isinstance(value, SFVec2d):
        value = value.value # dereference value from this base type
    if isinstance(value, MFVec2d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec2d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec2d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFVec2d list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 2:
        # print(flush=True)
        raise X3DTypeError('SFVec2d ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 2')
    if not isValidSFVec2d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec2d')
    return True

def isValidMFVec2d(value):
    """
    Utility function to determine type validity of a MFVec2d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec2d) and not isinstance(value, MFVec2d):
            # if _DEBUG: print('MFVec2d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFVec2d)=' + str(isinstance(value, MFVec2d)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFVec2d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFVec2d):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFVec2d.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFVec2d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec2d.TUPLE_SIZE=' + str(MFVec2d.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFVec2d(value):
    """
    Utility function to assert type validity of a MFVec2d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec2d) and not isinstance(value, MFVec2d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFVec2d')
    if isinstance(value, MFVec2d):
        value = value.value # dereference value from this base type
    if isinstance(value, SFVec2d) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec2d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFVec2d.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFVec2d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec2d.TUPLE_SIZE=' + str(MFVec2d.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFVec2d)):
#                # print(flush=True)
#                raise X3DTypeError('MFVec2d element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFVec2d element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFVec2d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec2d')
    return True

def isValidSFVec2f(value):
    """
    Utility function to determine type validity of a SFVec2f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec2f) and not isinstance(value, MFVec2f):
            # if _DEBUG: print('SFVec2f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFVec2f)=' + str(isinstance(value, SFVec2f)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFVec2f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFVec2f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec2f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 2:
        return False
    return True

def assertValidSFVec2f(value):
    """
    Utility function to assert type validity of a SFVec2f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec2f) and not isinstance(value, MFVec2f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFVec2f')
    if isinstance(value, SFVec2f):
        value = value.value # dereference value from this base type
    if isinstance(value, MFVec2f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec2f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec2f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFVec2f list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 2:
        # print(flush=True)
        raise X3DTypeError('SFVec2f ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 2')
    if not isValidSFVec2f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec2f')
    return True

def isValidMFVec2f(value):
    """
    Utility function to determine type validity of a MFVec2f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec2f) and not isinstance(value, MFVec2f):
            # if _DEBUG: print('MFVec2f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFVec2f)=' + str(isinstance(value, MFVec2f)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFVec2f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFVec2f):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFVec2f.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFVec2f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec2f.TUPLE_SIZE=' + str(MFVec2f.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFVec2f(value):
    """
    Utility function to assert type validity of a MFVec2f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec2f) and not isinstance(value, MFVec2f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFVec2f')
    if isinstance(value, MFVec2f):
        value = value.value # dereference value from this base type
    if isinstance(value, SFVec2f) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec2f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFVec2f.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFVec2f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec2f.TUPLE_SIZE=' + str(MFVec2f.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFVec2f)):
#                # print(flush=True)
#                raise X3DTypeError('MFVec2f element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFVec2f element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFVec2f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec2f')
    return True

def isValidSFVec3d(value):
    """
    Utility function to determine type validity of a SFVec3d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec3d) and not isinstance(value, MFVec3d):
            # if _DEBUG: print('SFVec3d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFVec3d)=' + str(isinstance(value, SFVec3d)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFVec3d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFVec3d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec3d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 3:
        return False
    return True

def assertValidSFVec3d(value):
    """
    Utility function to assert type validity of a SFVec3d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec3d) and not isinstance(value, MFVec3d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFVec3d')
    if isinstance(value, SFVec3d):
        value = value.value # dereference value from this base type
    if isinstance(value, MFVec3d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec3d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec3d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFVec3d list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 3:
        # print(flush=True)
        raise X3DTypeError('SFVec3d ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 3')
    if not isValidSFVec3d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec3d')
    return True

def isValidMFVec3d(value):
    """
    Utility function to determine type validity of a MFVec3d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec3d) and not isinstance(value, MFVec3d):
            # if _DEBUG: print('MFVec3d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFVec3d)=' + str(isinstance(value, MFVec3d)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFVec3d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFVec3d):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFVec3d.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFVec3d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec3d.TUPLE_SIZE=' + str(MFVec3d.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFVec3d(value):
    """
    Utility function to assert type validity of a MFVec3d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec3d) and not isinstance(value, MFVec3d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFVec3d')
    if isinstance(value, MFVec3d):
        value = value.value # dereference value from this base type
    if isinstance(value, SFVec3d) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec3d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFVec3d.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFVec3d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec3d.TUPLE_SIZE=' + str(MFVec3d.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFVec3d)):
#                # print(flush=True)
#                raise X3DTypeError('MFVec3d element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFVec3d element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFVec3d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec3d')
    return True

def isValidSFVec3f(value):
    """
    Utility function to determine type validity of a SFVec3f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec3f) and not isinstance(value, MFVec3f):
            # if _DEBUG: print('SFVec3f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFVec3f)=' + str(isinstance(value, SFVec3f)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFVec3f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFVec3f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec3f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 3:
        return False
    return True

def assertValidSFVec3f(value):
    """
    Utility function to assert type validity of a SFVec3f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec3f) and not isinstance(value, MFVec3f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFVec3f')
    if isinstance(value, SFVec3f):
        value = value.value # dereference value from this base type
    if isinstance(value, MFVec3f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec3f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec3f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFVec3f list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 3:
        # print(flush=True)
        raise X3DTypeError('SFVec3f ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 3')
    if not isValidSFVec3f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec3f')
    return True

def isValidMFVec3f(value):
    """
    Utility function to determine type validity of a MFVec3f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec3f) and not isinstance(value, MFVec3f):
            # if _DEBUG: print('MFVec3f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFVec3f)=' + str(isinstance(value, MFVec3f)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFVec3f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFVec3f):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFVec3f.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFVec3f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec3f.TUPLE_SIZE=' + str(MFVec3f.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFVec3f(value):
    """
    Utility function to assert type validity of a MFVec3f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec3f) and not isinstance(value, MFVec3f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFVec3f')
    if isinstance(value, MFVec3f):
        value = value.value # dereference value from this base type
    if isinstance(value, SFVec3f) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec3f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFVec3f.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFVec3f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec3f.TUPLE_SIZE=' + str(MFVec3f.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFVec3f)):
#                # print(flush=True)
#                raise X3DTypeError('MFVec3f element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFVec3f element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFVec3f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec3f')
    return True

def isValidSFVec4d(value):
    """
    Utility function to determine type validity of a SFVec4d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec4d) and not isinstance(value, MFVec4d):
            # if _DEBUG: print('SFVec4d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFVec4d)=' + str(isinstance(value, SFVec4d)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFVec4d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFVec4d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec4d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 4:
        return False
    return True

def assertValidSFVec4d(value):
    """
    Utility function to assert type validity of a SFVec4d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec4d) and not isinstance(value, MFVec4d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFVec4d')
    if isinstance(value, SFVec4d):
        value = value.value # dereference value from this base type
    if isinstance(value, MFVec4d) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec4d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec4d):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFVec4d list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 4:
        # print(flush=True)
        raise X3DTypeError('SFVec4d ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 4')
    if not isValidSFVec4d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec4d')
    return True

def isValidMFVec4d(value):
    """
    Utility function to determine type validity of a MFVec4d value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec4d) and not isinstance(value, MFVec4d):
            # if _DEBUG: print('MFVec4d type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFVec4d)=' + str(isinstance(value, MFVec4d)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFVec4d):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFVec4d):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFVec4d.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFVec4d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec4d.TUPLE_SIZE=' + str(MFVec4d.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFVec4d(value):
    """
    Utility function to assert type validity of a MFVec4d value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec4d) and not isinstance(value, MFVec4d):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFVec4d')
    if isinstance(value, MFVec4d):
        value = value.value # dereference value from this base type
    if isinstance(value, SFVec4d) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec4d')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFVec4d.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFVec4d tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec4d.TUPLE_SIZE=' + str(MFVec4d.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFVec4d)):
#                # print(flush=True)
#                raise X3DTypeError('MFVec4d element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFVec4d element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFVec4d(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec4d')
    return True

def isValidSFVec4f(value):
    """
    Utility function to determine type validity of a SFVec4f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec4f) and not isinstance(value, MFVec4f):
            # if _DEBUG: print('SFVec4f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, SFVec4f)=' + str(isinstance(value, SFVec4f)), flush=True)
            return False # type mismatch!
    if isinstance(value, SFVec4f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, MFVec4f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
        return True
    if not isinstance(value, tuple):
        return False
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec4f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            return False
    if tupleCount != 4:
        return False
    return True

def assertValidSFVec4f(value):
    """
    Utility function to assert type validity of a SFVec4f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec4f) and not isinstance(value, MFVec4f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a SFVec4f')
    if isinstance(value, SFVec4f):
        value = value.value # dereference value from this base type
    if isinstance(value, MFVec4f) and len(value) == 1:
        value = value.value[0] # dereference value from this MF type
    if not isinstance(value, tuple):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec4f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #1
    tupleCount = 0
    for each in value:
        tupleCount += 1
        while isinstance(each, list) and len(each) == 1:
            each = each[0] # dereference
        if isinstance(each, SFVec4f):
            each = each.value # dereference
        if not isinstance(each, float) and not isinstance(each, int):
            # print(flush=True)
            raise X3DTypeError('SFVec4f list has contained value=' + str(each) + ' with type=' + str(type(each)) + ' which is not a valid float')
    if tupleCount != 4:
        # print(flush=True)
        raise X3DTypeError('SFVec4f ' + str(value)[:100] + ', type=' + str(type(value)) + ' has ' + str(tupleCount) + ' elements instead of 4')
    if not isValidSFVec4f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python tuple for SFVec4f')
    return True

def isValidMFVec4f(value):
    """
    Utility function to determine type validity of a MFVec4f value.
    """
    if isinstance(value, _X3DField):
        if not isinstance(value, SFVec4f) and not isinstance(value, MFVec4f):
            # if _DEBUG: print('MFVec4f type mismatch diagnostic: value=' + str(value)[:100] + ' has type=' + str(type(value)) + ', isinstance(value, MFVec4f)=' + str(isinstance(value, MFVec4f)), flush=True)
            return False # type mismatch!
    if isinstance(value, MFVec4f):
        value = value.value # dereference value from base type
        return True
    if isinstance(value, SFVec4f):
        value = [value.value] # dereference value from this SF type, convert to list #1
        return True
    if not isinstance(value, list):
        return False
    _index = 0
    for each in value:
        _index += 1
        if len(each) % MFVec4f.TUPLE_SIZE != 0:
            # if _DEBUG:
            print('* isValidMFVec4f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec4f.TUPLE_SIZE=' + str(MFVec4f.TUPLE_SIZE) + ' for value=' + str(value), flush=True)
            return False
        for element in each:
            if not isinstance(element, float) and not isinstance(element, int):
                return False
    return True

def assertValidMFVec4f(value):
    """
    Utility function to assert type validity of a MFVec4f value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* debug value.__class__=' + str(value.__class__) + ', issubclass(value.__class__, _X3DField)=' + str(issubclass(value.__class__, _X3DField)) + ', super(value.__class__)=' + str(super(value.__class__)), flush=True)
    if isinstance(value, _X3DField) and not isinstance(value, SFVec4f) and not isinstance(value, MFVec4f):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ' has type ' + str(type(value)) + ' and is not a MFVec4f')
    if isinstance(value, MFVec4f):
        value = value.value # dereference value from this base type
    if isinstance(value, SFVec4f) or not isinstance(value, list):
        value = [value.value] # dereference value from this SF type, convert to list #2
    if not isinstance(value, list):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec4f')
    # perform duplicative tests prior to isValid call in order to provide better assertion diagnostics #2
    if isinstance(value, list):
        _index = 0
        for each in value:
            if len(each) % MFVec4f.TUPLE_SIZE != 0:
                # print(flush=True)
                raise X3DValueError('MFVec4f tuple ' + str(each) + ' has length ' + str(len(each)) + ' which is not a multiple of MFVec4f.TUPLE_SIZE=' + str(MFVec4f.TUPLE_SIZE) + ' for value=' + str(value)[:100])
#            if not isinstance(each, (tuple, SFVec4f)):
#                # print(flush=True)
#                raise X3DTypeError('MFVec4f element #' + str(_index) + ' with value ' + str(each) + ', type=' + str(type(each)) + ' is not a valid tuple')
            _index += 1
            if isinstance(each, tuple):
                for element in each:
                    if not isinstance(element, float) and not isinstance(element, int):
                        # print(flush=True)
                        raise X3DTypeError('MFVec4f element #' + str(_index) + ' tuple ' + str(each) + ' has value=' + str(element) + ', type=' + str(type(element)) + ' that is not a valid float')
    if not isValidMFVec4f(value):
        # print(flush=True)
        raise X3DTypeError(str(value)[:100] + ', type=' + str(type(value)) + ' is not a valid Python list for MFVec4f')
    return True


def assertValidFieldInitializationValue(name, fieldType, value, parent=''):
    """
    Utility function to assert fieldType validity of a field initialization value, otherwise raise X3DTypeError with diagnostic message.
    """
    # if _DEBUG: print('* assertValidFieldInitializationValue name=' + str(name) + ', fieldType=' + str(fieldType) + ', value=' + str(value)[:100] + ', parent=' + parent, flush=True)
    # note that ExternProtoDeclare field definitions do not have any value
    if name is None:
        print('* assertValidFieldInitializationValue improper invocation: name=' + str(name) + ', fieldType=' + str(fieldType) + ', value=' + str(value)[:100] + ', parent=' + parent + ', ignored', flush=True)
        return # ignore
    if value is None or (not(fieldType == bool) and not value):
        return # ignore
    if fieldType == 'SFString':
        assertValidSFString(value)
    elif fieldType == 'MFString':
        assertValidMFString(value)
    elif (fieldType == 'SFBool') or (fieldType == bool) or isinstance(value, bool):
        assertValidSFBool(value)
    elif fieldType == 'MFBool':
        assertValidMFBool(value)
    elif (fieldType == 'SFInt32') or (fieldType == int) or isinstance(value, int):
        assertValidSFInt32(value)
    elif fieldType == 'MFInt32':
        assertValidMFInt32(value)
    elif (fieldType == 'SFFloat') or (fieldType == float) or isinstance(value, float):
        assertValidSFFloat(value)
    elif fieldType == 'MFFloat':
        assertValidMFFloat(value)
    elif fieldType == 'SFDouble':
        assertValidSFDouble(value)
    elif fieldType == 'MFDouble':
        assertValidMFDouble(value)
    elif fieldType == 'SFTime':
        assertValidSFTime(value)
    elif fieldType == 'MFTime':
        assertValidMFTime(value)
    elif fieldType == 'SFColor':
        assertValidSFColor(value)
    elif fieldType == 'MFColorRGBA':
        assertValidMFColorRGBA(value)
    elif fieldType == 'SFRotation':
        assertValidSFRotation(value)
    elif fieldType == 'MFRotation':
        assertValidMFRotation(value)
    elif fieldType == 'SFImage':
        assertValidSFImage(value)
    elif fieldType == 'MFImage':
        assertValidMFImage(value)
    elif fieldType == 'SFNode':
        assertValidSFNode(value)
    elif fieldType == 'MFNode':
        assertValidMFNode(value)
    elif fieldType == 'SFVec2f':
        assertValidSFVec2f(value)
    elif fieldType == 'MFVec2f':
        assertValidMFVec2f(value)
    elif fieldType == 'SFVec3f':
        assertValidSFVec3f(value)
    elif fieldType == 'MFVec3f':
        assertValidMFVec3f(value)
    elif fieldType == 'SFVec4f':
        assertValidSFVec4f(value)
    elif fieldType == 'MFVec4f':
        assertValidMFVec4f(value)
    elif fieldType == 'SFVec2d':
        assertValidSFVec2d(value)
    elif fieldType == 'MFVec2d':
        assertValidMFVec2d(value)
    elif fieldType == 'SFVec3d':
        assertValidSFVec3d(value)
    elif fieldType == 'MFVec3d':
        assertValidMFVec3d(value)
    elif fieldType == 'SFVec4d':
        assertValidSFVec4d(value)
    elif fieldType == 'MFVec4d':
        assertValidMFVec4d(value)
    elif fieldType == 'SFMatrix3d':
        assertValidSFMatrix3f(value)
    elif fieldType == 'MFMatrix3f':
        assertValidMFMatrix3f(value)
    elif fieldType == 'SFMatrix4f':
        assertValidSFMatrix4f(value)
    elif fieldType == 'MFMatrix4f':
        assertValidMFMatrix4f(value)
    elif fieldType == 'SFMatrix3d':
        assertValidSFMatrix3d(value)
    elif fieldType == 'MFMatrix3d':
        assertValidMFMatrix3d(value)
    elif fieldType == 'SFMatrix4d':
        assertValidSFMatrix4d(value)
    elif fieldType == 'MFMatrix4d':
        assertValidMFMatrix4d(value)
    elif (fieldType == str)   or isinstance(value, str):
        assertValidSFString(value)
    elif str(parent) == 'fieldValue':
        return True # TODO check further if possible
    elif (fieldType == list) or isinstance(value, list):
        try:
            if isinstance(value[0], tuple):
                print('*** assertValidFieldInitializationValue TODO validate list fieldType: name=' + str(name) + ', passed fieldType=' + str(fieldType) + ', fieldType(value)=' + str(fieldType(value)) + ', value=' + str(value)[:100] + ', parent=' + parent, flush=True)
                return True # TODO check further
            initialListItemType = fieldType(value[0])
            # https://stackoverflow.com/questions/522563/accessing-the-index-in-for-loops/28072982#28072982
            # https://stackoverflow.com/questions/1952464/in-python-how-do-i-determine-if-an-object-is-iterable
            for index, each in enumerate(value):
                assertValidFieldInitializationValue(name + '[' + str(index) + ']', initialListItemType, value[index], parent)
        except TypeError:
            return True # TODO check further if possible
    elif (fieldType == tuple) or isinstance(value, tuple):
        print('*** assertValidFieldInitializationValue TODO validate tuple fieldType: name=' + str(name) + ', passed fieldType=' + str(fieldType) + ', fieldType(value)=' + str(fieldType(value)) + ', value=' + str(value)[:100] + ', parent=' + parent, flush=True)
        return True # TODO check further if possible
#       initialListItemType = fieldType(value[0])
#       for index, each in enumerate(value):
#           assertValidFieldInitializationValue(name + '[' + str(index) + '], fieldType(value[index])', value[index], parent)
    else:
        print('*** assertValidFieldInitializationValue unknown fieldType: name=' + str(name) + ', passed fieldType=' + str(fieldType) + ', fieldType(value)=' + str(fieldType(value)) + ', value=' + str(value)[:100] + ', parent=' + parent, flush=True)
###############################################

class _X3DField(object):
    """
    All X3D fields implement _X3DField abstract type.
    """
    value = None
    NAME = '_X3DField'
    SPECIFICATION_URL = 'https://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/fieldsDef.html'
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#FieldTypesTable'
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide value of this field type. """
        return self.__value
    def __repl__(self):
        # if _DEBUG: print('* debug: type(self.value)=' + str(type(self.value)), flush=True)
        if isinstance(self.value, (SFString, str)):
            return "'" + self.value + "'"
        if  isinstance(self.value, tuple) and 'SF' in str(type(self)): # avoid X3DTypeError if value is not iterable
            result = '('
            for each in self.value:
                result += str(each) + ', '
                # if _DEBUG: print('* _X3DField debug: str(each)=' + str(each), flush=True)
            return result.rstrip(', ') + ')'
        if  isinstance(self.value, list) and 'MF' in str(type(self)): # avoid X3DTypeError if value is not iterable
            # isinstance(self.value, MFNode): not working, what got passed in was not an MFNode object apparently
            result = '['
            for each in self.value:
                result += str(each) + ', '
                # if _DEBUG: print('* _X3DField debug: str(each)=' + str(each), flush=True)
            return result.rstrip(', ') + ']'
        return str(self.value)
    def __str__(self):
        return self.__repl__()

def isX3DField(value):
    """
    Determine whether object is an instance of _X3DField.
    """
    return isinstance(value, _X3DField)

# Access Types

class AccessType(_X3DField):
    """
    accessType determines whether a field corresponds to event input, event output, or persistent state information. Events are strictly typed values with a corresponding timestamp. ROUTE connections must match accessType between source field and target field.

    initializeOnly: can be initialized, but cannot send or receive events. This is usually the case for fields that are considered too computationally expensive to change at run time.
    inputOutput: can be initialized, and can also send or receive events during run-time operations.
    inputOnly: cannot be initialized or included in a scene file, but can receive input event values via a ROUTE during run-time operations.
    outputOnly: cannot be initialized or included in a scene file, but can send output event values via a ROUTE during run-time operations.
    """
    SPECIFICATION_URL = 'https://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/concepts.html#FieldSemantics'
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#accessType'
    # string constants listing each allowed accessType
    initializeOnly = 'initializeOnly'
    inputOutput = 'inputOutput'
    inputOnly = 'inputOnly'
    outputOnly = 'outputOnly'


# Field Types

class FieldType(_X3DField):
    """
    The X3D Architecture specification of field types classify the possible values for a field.
    Each field in each node (i.e. each XML attribute) has a strictly defined data type.
    Multiple data types are provided for boolean, integer, floating-point and string values.
    X3D is a strongly typed language, meaning that all data must strictly conform to these data types in order for a scene to be correct.
    """
    SPECIFICATION_URL = 'https://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/fieldsDef.html'
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#type'
    # string constants listing each allowed type
    SFBool = 'SFBool'
    MFBool = 'MFBool'
    SFColor = 'SFColor'
    MFColor = 'MFColor'
    SFColorRGBA = 'SFColorRGBA'
    MFColorRGBA = 'MFColorRGBA'
    SFDouble = 'SFDouble'
    MFDouble = 'MFDouble'
    SFFloat = 'SFFloat'
    MFFloat = 'MFFloat'
    SFImage = 'SFImage'
    MFImage = 'MFImage'
    SFInt32 = 'SFInt32'
    MFInt32 = 'MFInt32'
    SFMatrix3d = 'SFMatrix3d'
    MFMatrix3d = 'MFMatrix3d'
    SFMatrix3f = 'SFMatrix3f'
    MFMatrix3f = 'MFMatrix3f'
    SFMatrix4d = 'SFMatrix4d'
    MFMatrix4d = 'MFMatrix4d'
    SFMatrix4f = 'SFMatrix4f'
    MFMatrix4f = 'MFMatrix4f'
    SFNode = 'SFNode'
    MFNode = 'MFNode'
    SFRotation = 'SFRotation'
    MFRotation = 'MFRotation'
    SFString = 'SFString'
    MFString = 'MFString'
    SFTime = 'SFTime'
    MFTime = 'MFTime'
    SFVec2d = 'SFVec2d'
    MFVec2d = 'MFVec2d'
    SFVec2f = 'SFVec2f'
    MFVec2f = 'MFVec2f'
    SFVec3d = 'SFVec3d'
    MFVec3d = 'MFVec3d'
    SFVec3f = 'SFVec3f'
    MFVec3f = 'MFVec3f'
    SFVec4d = 'SFVec4d'
    MFVec4d = 'MFVec4d'
    SFVec4f = 'SFVec4f'
    MFVec4f = 'MFVec4f'

class SFBool(_X3DField):
    """
    SFBool is a logical type with possible values (True|False).
    """
    NAME = 'SFBool'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFBool'
    DEFAULT_VALUE = True
    ARRAY_TYPE = False
    TUPLE_SIZE = 1
    REGEX_XML = r'\s*(true|false)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        value = fixBoolean(value, default=self.DEFAULT_VALUE)
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFBool) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFBool(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower()

class MFBool(_X3DField):
    """
    MFBool is an array of Boolean values.
    """
    NAME = 'MFBool'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFBool'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 1
    REGEX_XML = r'\s*((true|false)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        value = fixBoolean(value, default=self.DEFAULT_VALUE)
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFBool(value):
            value = [value]
        assertValidMFBool(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFBool(value):
                if isinstance(value, SFBool):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFBool(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFBool):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFBool(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('[','').replace(']','')

class SFColor(_X3DField):
    """
    The SFColor field specifies one RGB (red-green-blue) color triple.
    """
    NAME = 'SFColor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFColor'
    DEFAULT_VALUE = (0, 0, 0)
    ARRAY_TYPE = False
    TUPLE_SIZE = 3
    REGEX_XML = r'(\s)*(([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)(\s)+){2}([+]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)(\s)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 3-tuples
                value = [(x, y, z) for x, y, z in value]
        elif isinstance(value, MFColor) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFColor(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFColor(_X3DField):
    """
    MFColor specifies zero or more SFColor RGB triples.
    """
    NAME = 'MFColor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFColor'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 3
    REGEX_XML = r'(\s)*((([+-]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)(\s)+){2}([+-]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 3-tuples
                value = [(x, y, z) for x, y, z in value]
        elif not isinstance(value, list) and isValidSFColor(value):
            value = [value]
        assertValidMFColor(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFColor(value):
                if isinstance(value, SFColor):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFColor(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFColor):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFColor(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFColorRGBA(_X3DField):
    """
    The SFColorRGBA field specifies one RGBA (red-green-blue-alpha) color 4-tuple.
    """
    NAME = 'SFColorRGBA'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFColorRGBA'
    DEFAULT_VALUE = (0, 0, 0, 0)
    ARRAY_TYPE = False
    TUPLE_SIZE = 4
    REGEX_XML = r'(\s)*(([+-]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)(\s)+){3}([+-]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)(\s)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 4-tuples
                value = [(x, y, z, w) for x, y, z, w in value]
        elif isinstance(value, MFColorRGBA) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFColorRGBA(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFColorRGBA(_X3DField):
    """
    MFColorRGBA specifies zero or more SFColorRGBA 4-tuples.
    """
    NAME = 'MFColorRGBA'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFColorRGBA'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 4
    REGEX_XML = r'(\s)*((([+-]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)(\s)+){3}([+-]?((0(\.[0-9]*)?|\.[0-9]+)|1(\.0*)?)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 4-tuples
                value = [(x, y, z, w) for x, y, z, w in value]
        elif not isinstance(value, list) and isValidSFColorRGBA(value):
            value = [value]
        assertValidMFColorRGBA(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFColorRGBA(value):
                if isinstance(value, SFColorRGBA):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFColorRGBA(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFColorRGBA):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFColorRGBA(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFDouble(_X3DField):
    """
    SFDouble is a double-precision floating-point type.
    """
    NAME = 'SFDouble'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFDouble'
    DEFAULT_VALUE = 0.0
    ARRAY_TYPE = False
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s)*([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)(\s)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFDouble) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFDouble(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFDouble(_X3DField):
    """
    MFDouble is an array of Double values, meaning a double-precision floating-point array type.
    """
    NAME = 'MFDouble'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFDouble'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s)*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFDouble(value):
            value = [value]
        assertValidMFDouble(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFDouble(value):
                if isinstance(value, SFDouble):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFDouble(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFDouble):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFDouble(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFFloat(_X3DField):
    """
    SFFloat is a single-precision floating-point type.
    """
    NAME = 'SFFloat'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFFloat'
    DEFAULT_VALUE = 0.0
    ARRAY_TYPE = False
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s)*([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)(\s)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFFloat) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFFloat(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFFloat(_X3DField):
    """
    MFFloat is an array of SFFloat values, meaning a single-precision floating-point array type.
    """
    NAME = 'MFFloat'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFFloat'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s)*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFFloat(value):
            value = [value]
        assertValidMFFloat(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFFloat(value):
                if isinstance(value, SFFloat):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFFloat(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFFloat):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFFloat(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFImage(_X3DField):
    """
    The SFImage field specifies a single uncompressed 2-dimensional pixel image.
    """
    NAME = 'SFImage'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFImage'
    DEFAULT_VALUE = [0, 0, 0]
    ARRAY_TYPE = False
    TUPLE_SIZE = 1
    REGEX_XML = r'\s*([+]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?\s+){2}[+]?[0-4](\s+(0x[0-9a-fA-F]{1,16}|[+]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?))*\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFImage) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFImage(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFImage(_X3DField):
    """
    MFImage is an array of SFImage values.
    """
    NAME = 'MFImage'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFImage'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 1
    REGEX_XML = r'\s*(([+]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?\s+){2}[+]?[0-4](\s+(0x[0-9a-fA-F]{1,16}|[+]?(0|[1-9][0-9]*)([Ee][+]?[0-9]+)?))*\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFImage(value):
            value = [value]
        assertValidMFImage(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFImage(value):
                if isinstance(value, SFImage):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFImage(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFImage):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFImage(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFInt32(_X3DField):
    """
    An SFInt32 field specifies one 32-bit signed integer.
    """
    NAME = 'SFInt32'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFInt32'
    DEFAULT_VALUE = 0
    ARRAY_TYPE = False
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s)*[+-]?(0|[1-9][0-9]*)([Ee][+-]?[0-9]+)?(\s)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFInt32) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFInt32(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFInt32(_X3DField):
    """
    An MFInt32 field defines an array of 32-bit signed integers.
    """
    NAME = 'MFInt32'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFInt32'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s)*([+-]?(0|[1-9][0-9]*)([Ee][+-]?[0-9]+)?\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFInt32(value):
            value = [value]
        assertValidMFInt32(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFInt32(value):
                if isinstance(value, SFInt32):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFInt32(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFInt32):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFInt32(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFMatrix3d(_X3DField):
    """
    SFMatrix3d specifies a 3x3 matrix of double-precision floating point numbers, organized in row-major fashion.
    """
    NAME = 'SFMatrix3d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFMatrix3d'
    DEFAULT_VALUE = (1, 0, 0, 0, 1, 0, 0, 0, 1)
    ARRAY_TYPE = False
    TUPLE_SIZE = 9
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){8}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFMatrix3d) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFMatrix3d(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFMatrix3d(_X3DField):
    """
    MFMatrix3d specifies zero or more 3x3 matrices of double-precision floating point numbers, organized in row-major fashion.
    """
    NAME = 'MFMatrix3d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFMatrix3d'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 9
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){8}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFMatrix3d(value):
            value = [value]
        assertValidMFMatrix3d(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFMatrix3d(value):
                if isinstance(value, SFMatrix3d):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFMatrix3d(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFMatrix3d):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFMatrix3d(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFMatrix3f(_X3DField):
    """
    SFMatrix3f specifies a 3x3 matrix of single-precision floating point numbers, organized in row-major fashion.
    """
    NAME = 'SFMatrix3f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFMatrix3f'
    DEFAULT_VALUE = (1, 0, 0, 0, 1, 0, 0, 0, 1)
    ARRAY_TYPE = False
    TUPLE_SIZE = 9
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){8}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFMatrix3f) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFMatrix3f(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFMatrix3f(_X3DField):
    """
    MFMatrix3f specifies zero or more 3x3 matrices of single-precision floating point numbers, organized in row-major fashion.
    """
    NAME = 'MFMatrix3f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFMatrix3f'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 9
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){8}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFMatrix3f(value):
            value = [value]
        assertValidMFMatrix3f(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFMatrix3f(value):
                if isinstance(value, SFMatrix3f):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFMatrix3f(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFMatrix3f):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFMatrix3f(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFMatrix4d(_X3DField):
    """
    SFMatrix4d specifies a 4x4 matrix of double-precision floating point numbers, organized in row-major fashion.
    """
    NAME = 'SFMatrix4d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFMatrix4d'
    DEFAULT_VALUE = (1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
    ARRAY_TYPE = False
    TUPLE_SIZE = 16
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){15}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFMatrix4d) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFMatrix4d(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFMatrix4d(_X3DField):
    """
    MFMatrix4d specifies zero or more 4x4 matrices of double-precision floating point numbers, organized in row-major fashion.
    """
    NAME = 'MFMatrix4d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFMatrix4d'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 16
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){15}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFMatrix4d(value):
            value = [value]
        assertValidMFMatrix4d(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFMatrix4d(value):
                if isinstance(value, SFMatrix4d):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFMatrix4d(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFMatrix4d):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFMatrix4d(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFMatrix4f(_X3DField):
    """
    SFMatrix4f specifies a 4x4 matrix of single-precision floating point numbers, organized in row-major fashion.
    """
    NAME = 'SFMatrix4f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFMatrix4f'
    DEFAULT_VALUE = (1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
    ARRAY_TYPE = False
    TUPLE_SIZE = 16
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){15}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFMatrix4f) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFMatrix4f(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFMatrix4f(_X3DField):
    """
    MFMatrix4f specifies zero or more 4x4 matrices of single-precision floating point numbers, organized in row-major fashion.
    """
    NAME = 'MFMatrix4f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFMatrix4f'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 16
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){15}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFMatrix4f(value):
            value = [value]
        assertValidMFMatrix4f(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFMatrix4f(value):
                if isinstance(value, SFMatrix4f):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFMatrix4f(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFMatrix4f):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFMatrix4f(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFNode(_X3DField):
    """
    The SFNode field specifies an X3D node; the default empty value of an uninitialized SFNode field is sometimes described as NULL.
    """
    NAME = 'SFNode'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFNode'
    DEFAULT_VALUE = None
    FIELD_DECLARATIONS = [('value', 'None', FieldType.SFNode, AccessType.inputOutput, 'SFNode')]
    ARRAY_TYPE = False
    TUPLE_SIZE = 1
    REGEX_XML = r'' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFNode) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFNode(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        if (not self.__value is None):
            return self.__value.XML()

class MFNode(_X3DField):
    """
    The MFNode field specifies zero or more nodes; the default value of an MFNode field is the empty list.
    """
    NAME = 'MFNode'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFNode'
    DEFAULT_VALUE = list()
    FIELD_DECLARATIONS = [('value', None, FieldType.MFNode, AccessType.inputOutput, 'MFNode')]
    ARRAY_TYPE = True
    TUPLE_SIZE = 1
    REGEX_XML = r'' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFNode(value):
            value = [value]
        assertValidMFNode(value)
        self.__value = value
    def __repl__(self):
        result = '['
        for each in self.__value:
            result += str(each) + ', '
        return result.rstrip(', ') + ']'
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFNode(value):
                if isinstance(value, SFNode):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFNode(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFNode):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFNode(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        result = ''
        for each in self.__value:
            result += each.XML() # has line break '\n' at end, which is OK
        result = result.rstrip('\n')
        return result

class SFRotation(_X3DField):
    """
    SFRotation is an axis-angle 4-tuple, indicating X-Y-Z direction axis plus angle orientation about that axis.
    """
    NAME = 'SFRotation'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFRotation'
    DEFAULT_VALUE = (0, 0, 1, 0)
    ARRAY_TYPE = False
    TUPLE_SIZE = 4
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 4-tuples
                value = [(x, y, z, w) for x, y, z, w in value]
        elif isinstance(value, MFRotation) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFRotation(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFRotation(_X3DField):
    """
    MFRotation is an array of SFRotation values.
    """
    NAME = 'MFRotation'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFRotation'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 4
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 4-tuples
                value = [(x, y, z, w) for x, y, z, w in value]
        elif not isinstance(value, list) and isValidSFRotation(value):
            value = [value]
        assertValidMFRotation(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFRotation(value):
                if isinstance(value, SFRotation):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFRotation(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFRotation):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFRotation(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFString(_X3DField):
    """
    SFString defines a single string encoded with the UTF-8 universal character set.
    """
    NAME = 'SFString'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFString'
    DEFAULT_VALUE = ''
    ARRAY_TYPE = False
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s|\S)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFString) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFString(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value)

class MFString(_X3DField):
    """
    MFString is an array of SFString values, each "quoted" and separated by whitespace.
    """
    NAME = 'MFString'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFString'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s|\S)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFString(value):
            value = [value]
        assertValidMFString(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFString(value):
                if isinstance(value, SFString):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFString(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFString):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFString(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        result = ''
        for each in self.__value:
            result += '"' + str(each) + '"' + ' '
        result = result.rstrip(' ')
        return result

class SFTime(_X3DField):
    """
    The SFTime field specifies a single time value.
    """
    NAME = 'SFTime'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFTime'
    DEFAULT_VALUE = -1.0
    ARRAY_TYPE = False
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s)*([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)(\s)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFTime) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFTime(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFTime(_X3DField):
    """
    MFTime is an array of SFTime values.
    """
    NAME = 'MFTime'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFTime'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 1
    REGEX_XML = r'(\s)*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFTime(value):
            value = [value]
        assertValidMFTime(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFTime(value):
                if isinstance(value, SFTime):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFTime(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFTime):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFTime(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFVec2d(_X3DField):
    """
    SFVec2d is a 2-tuple pair of SFDouble values.
    """
    NAME = 'SFVec2d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFVec2d'
    DEFAULT_VALUE = (0.0, 0.0)
    ARRAY_TYPE = False
    TUPLE_SIZE = 2
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){1}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFVec2d) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFVec2d(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFVec2d(_X3DField):
    """
    MFVec2d is an array of SFVec2d values.
    """
    NAME = 'MFVec2d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFVec2d'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 2
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){1}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFVec2d(value):
            value = [value]
        assertValidMFVec2d(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFVec2d(value):
                if isinstance(value, SFVec2d):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFVec2d(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFVec2d):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFVec2d(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFVec2f(_X3DField):
    """
    SFVec2f is a 2-tuple pair of SFFloat values.
    """
    NAME = 'SFVec2f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFVec2f'
    DEFAULT_VALUE = (0.0, 0.0)
    ARRAY_TYPE = False
    TUPLE_SIZE = 2
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){1}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 2-tuples
                value = [(x, y) for x, y, in value]
        elif isinstance(value, MFVec2f) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFVec2f(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFVec2f(_X3DField):
    """
    MFVec2f is an array of SFVec2f values.
    """
    NAME = 'MFVec2f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFVec2f'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 2
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){1}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 2-tuples
                value = [(x, y) for x, y, in value]
        elif not isinstance(value, list) and isValidSFVec2f(value):
            value = [value]
        assertValidMFVec2f(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFVec2f(value):
                if isinstance(value, SFVec2f):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFVec2f(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFVec2f):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFVec2f(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFVec3d(_X3DField):
    """
    SFVec3d is a 3-tuple triplet of SFDouble values.
    """
    NAME = 'SFVec3d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFVec3d'
    DEFAULT_VALUE = (0.0, 0.0, 0.0)
    ARRAY_TYPE = False
    TUPLE_SIZE = 3
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){2}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFVec3d) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFVec3d(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFVec3d(_X3DField):
    """
    MFVec3d is an array of SFVec3d values.
    """
    NAME = 'MFVec3d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFVec3d'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 3
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){2}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFVec3d(value):
            value = [value]
        assertValidMFVec3d(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFVec3d(value):
                if isinstance(value, SFVec3d):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFVec3d(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFVec3d):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFVec3d(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFVec3f(_X3DField):
    """
    SFVec3f is a 3-tuple triplet of SFFloat values.
    """
    NAME = 'SFVec3f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFVec3f'
    DEFAULT_VALUE = (0.0, 0.0, 0.0)
    ARRAY_TYPE = False
    TUPLE_SIZE = 3
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){2}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 3-tuples
                value = [(x, y, z) for x, y, z in value]
        elif isinstance(value, MFVec3f) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFVec3f(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFVec3f(_X3DField):
    """
    MFVec3f is an array of SFVec3f values.
    """
    NAME = 'MFVec3f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFVec3f'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 3
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){2}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 3-tuples
                value = [(x, y, z) for x, y, z in value]
        elif not isinstance(value, list) and isValidSFVec3f(value):
            value = [value]
        assertValidMFVec3f(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFVec3f(value):
                if isinstance(value, SFVec3f):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFVec3f(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFVec3f):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFVec3f(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFVec4d(_X3DField):
    """
    SFVec4d is a 4-tuple set of double-precision floating-point values, specifying a 3D homogeneous vector.
    """
    NAME = 'SFVec4d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFVec4d'
    DEFAULT_VALUE = (0.0, 0.0, 0.0, 0.0)
    ARRAY_TYPE = False
    TUPLE_SIZE = 4
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, MFVec4d) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFVec4d(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFVec4d(_X3DField):
    """
    MFVec4d is zero or more SFVec4d values.
    """
    NAME = 'MFVec4d'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFVec4d'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 4
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif not isinstance(value, list) and isValidSFVec4d(value):
            value = [value]
        assertValidMFVec4d(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFVec4d(value):
                if isinstance(value, SFVec4d):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFVec4d(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFVec4d):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFVec4d(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

class SFVec4f(_X3DField):
    """
    SFVec4f is a 4-tuple set of single-precision floating-point values, specifying a 3D homogeneous vector.
    """
    NAME = 'SFVec4f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SFVec4f'
    DEFAULT_VALUE = (0.0, 0.0, 0.0, 0.0)
    ARRAY_TYPE = False
    TUPLE_SIZE = 4
    REGEX_XML = r'\s*(([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 4-tuples
                value = [(x, y, z, w) for x, y, z, w in value]
        elif isinstance(value, MFVec4f) and isinstance(value.value, list) and len(value.value) == 1:
            print("downcasting by dereferencing simple-list value=" + str(value)[:100] + ", type=" + str(type(value)) + " as " + str(value.value[0]))
            value = value.value[0] # dereference
        elif isinstance(value, list) and len(value) == 1:
            value = value[0] # dereference
        assertValidSFVec4f(value)
        self.__value = value
    def __bool__(self):
        return len(self.__value) > 0
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace(',','').replace('(','').replace(')','').replace('[','').replace(']','')

class MFVec4f(_X3DField):
    """
    MFVec4f is zero or more SFVec4f values.
    """
    NAME = 'MFVec4f'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MFVec4f'
    DEFAULT_VALUE = list()
    ARRAY_TYPE = True
    TUPLE_SIZE = 4
    REGEX_XML = r'\s*((([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s+){3}([+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([Ee][+-]?[0-9]+)?)\s*,?\s*)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide typed value of this field instance. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        elif isinstance(value, list):
            for each in value: # check that elements are not tuples
                if isinstance(each, tuple):
                    break
            else: # no tuples found, create 4-tuples
                value = [(x, y, z, w) for x, y, z, w in value]
        elif not isinstance(value, list) and isValidSFVec4f(value):
            value = [value]
        assertValidMFVec4f(value)
        self.__value = value
    def append(self, value=None):
        """ Add to existing value list, first ensuring that a correctly typed value is applied. """
        if  not value is None:
            if isValidSFVec4f(value):
                if isinstance(value, SFVec4f):
                    value = value.value # dereference
                self.__value.append(value)
            elif isValidMFVec4f(value):
                for each in value:
                    while isinstance(each, list) and len(each) == 1:
                        each = each[0] # dereference
                    if isinstance(each, SFVec4f):
                        each = each.value # dereference
                    self.__value.append(each)
            else:
                assertValidMFVec4f(value) # report type failure
    def __bool__(self):
        return len(self.__value) > 0
    def __len__(self):
        return len(self.__value)
    def XML(self):
        """ Provide XML value for this field. """
        return str(self.__value).lower().replace('(','').replace(')','').replace(',','').replace('[','').replace(']','')

###############################################

# Abstract Node Types

# Note that these package-internal class names are preceded by an underscore _ character for hidden scope, since X3D authors are not expected to use them.
class _X3DNode(object):
    """
    All instantiable nodes implement X3DNode, which corresponds to SFNode in the X3D specification.
    """
    NAME = '_X3DNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF="", USE="", class_="", metadata=None, IS=None):
        self.DEF = DEF
        self.USE = USE
        self.class_ = class_
        self.IS = IS
        self.metadata = metadata
        # if _DEBUG: print('... in X3DNode __init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
    @property # getter - - - - - - - - - -
    def DEF(self):
        """ Unique ID name for this node, referenceable by other nodes. """
        return self.__DEF
    @DEF.setter
    def DEF(self, DEF=None):
        if  DEF is None:
            DEF = SFString.DEFAULT_VALUE
        assertValidSFString(DEF)
        self.__DEF = str(DEF)
        if self.__DEF:
            self.__USE = None # DEF and USE are mutually exclusive
    @property # getter - - - - - - - - - -
    def USE(self):
        """ Reuse an already DEF-ed node ID, excluding all child nodes and all other attributes. """
        return self.__USE
    @USE.setter
    def USE(self, USE=None):
        if  USE is None:
            USE = SFString.DEFAULT_VALUE
        assertValidSFString(USE)
        self.__USE = str(USE)
        if self.__USE:
            self.__DEF = None # DEF and USE are mutually exclusive
    @property # getter - - - - - - - - - -
    def class_(self):
        """ Space-separated list of classes, reserved for use by CSS cascading stylesheets. """
        return self.__class_
    @class_.setter
    def class_(self, class_=None):
        if  class_ is None:
            class_ = SFString.DEFAULT_VALUE
        assertValidSFString(class_)
        self.__class_ = class_
    @property # getter - - - - - - - - - -
    def IS(self):
        """ The IS statement connects node fields defined inside a ProtoBody declaration back to corresponding ProtoInterface fields. """
        return self.__IS
    @IS.setter
    def IS(self, IS=None):
        if  IS is None:
            IS = SFNode.DEFAULT_VALUE
        assertValidSFNode(IS)
        if not isinstance(IS, object):
            # print(flush=True)
            raise X3DTypeError(str(IS) + ' does not have a valid node type object')
        self.__IS = IS
    @property # getter - - - - - - - - - -
    def metadata(self):
        """ The metadata field can contain a single MetadataBoolean, MetadataInteger, MetadataFloat, MetadataDouble, MetadataString or MetadataSet node. """
        return self.__metadata
    @metadata.setter
    def metadata(self, metadata=None):
        if  metadata is None:
            metadata = SFNode.DEFAULT_VALUE
        assertValidSFNode(metadata)
        if not isinstance(metadata, object):
            # print(flush=True)
            raise X3DTypeError(str(metadata) + ' does not have a valid node type object')
        self.__metadata = metadata
    def __repl__(self):
        result = self.NAME + '('
        # TODO put DEF first, matching canonical form
        for each in self.FIELD_DECLARATIONS:
            # if _DEBUG: print(self.NAME + ' for each in self.FIELD_DECLARATIONS: each=' + str(each))
            name = each[0]
            default = each[1]
            type_ = each[2]
            accessType = each[3]
            value = getattr(self, name)
            # if _DEBUG: print('gettattr(self, ' + str(name) + ') value="' + str(value)[:100] + '" for FIELD_DECLARATIONS ' + str(each) + ')', flush=True)
            if value != default:
                # consider whether indentation is useful; probably not
                # print("\n\t")
                if  isinstance(value, list): # avoid X3DTypeError if value is not iterable
                    result += str(name) + '=['
                    for each in value:
                        # if _DEBUG: print('* X3DNode debug: str(each)=' + str(each), flush=True)
                        result += str(each) + ', '
                    result = result.rstrip(', ')
                    result += '],'
                elif isinstance(value, str) and "'" in value:
                    result += str(name) + '=' + '"' + str(value)[:100] + '"' + ','
                elif isinstance(value, str) and value != default:
                    result += str(name) + '=' + "'" + str(value)[:100] + "'" + ','
                elif value != default:
                    result += str(name) + '='       + str(value)[:100]       + ','
                # elif _DEBUG:
                #   result += str(name) + '=' + "'" + str(value)[:100] + "'" + ','
        return result.strip().rstrip(',').rstrip(', ') + ')'
    def __str__(self):
        return self.__repl__().strip() # X3DNode


def isX3DNode(value):
    """
    Whether or not value is a concrete node (Shape WorldInfo etc.) meaning any _X3DNode object.
    """
    return isinstance(value, _X3DNode)

class _X3DChildNode(_X3DNode):
    """
    A node that implements X3DChildNode is one of the legal children for a X3DGroupingNode parent.
    """
    NAME = '_X3DChildNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DChildNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DTimeDependentNode(_X3DChildNode):
    """
    Base type from which all time-dependent nodes are derived.
    """
    NAME = '_X3DTimeDependentNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DTimeDependentNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DGeometryNode(_X3DNode):
    """
    Geometry nodes produce renderable geometry and are contained by a Shape node.
    """
    NAME = '_X3DGeometryNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DGeometryNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DParametricGeometryNode(_X3DGeometryNode):
    """
    Base type for all geometry node types that are created parametrically and use control points to describe the final shape of the surface.
    """
    NAME = '_X3DParametricGeometryNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DParametricGeometryNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DAppearanceChildNode(_X3DNode):
    """
    Nodes of this type can be used as child nodes for Appearance.
    """
    NAME = '_X3DAppearanceChildNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DAppearanceChildNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DTextureNode(_X3DAppearanceChildNode):
    """
    Base type for all nodes which specify sources for texture images.
    """
    NAME = '_X3DTextureNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DTextureNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DSensorNode(_X3DChildNode):
    """
    Base type for all sensors.
    """
    NAME = '_X3DSensorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DSensorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DPointingDeviceSensorNode(_X3DSensorNode):
    """
    Base type for all pointing device sensors.
    """
    NAME = '_X3DPointingDeviceSensorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DPointingDeviceSensorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DVolumeRenderStyleNode(_X3DNode):
    """
    The X3DVolumeRenderStyleNode abstract node type is the base type for all node types that specify a specific visual rendering style to be used when rendering volume data.
    """
    NAME = '_X3DVolumeRenderStyleNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DVolumeRenderStyleNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DGeometricPropertyNode(_X3DNode):
    """
    Base type for all geometric property node types.
    """
    NAME = '_X3DGeometricPropertyNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DGeometricPropertyNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DFollowerNode(_X3DChildNode):
    """
    X3DFollowerNode is the abstract base class for all nodes in the Followers component.
    """
    NAME = '_X3DFollowerNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DFollowerNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DBindableNode(_X3DChildNode):
    """
    Bindable nodes implement the binding stack, so that only one of each node type is active at a given time.
    """
    NAME = '_X3DBindableNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DBindableNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DAppearanceNode(_X3DNode):
    """
    Base type for all Appearance nodes.
    """
    NAME = '_X3DAppearanceNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DAppearanceNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DBackgroundNode(_X3DBindableNode):
    """
    Abstract type from which all backgrounds inherit, also defining a background binding stack.
    """
    NAME = '_X3DBackgroundNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DBackgroundNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DChaserNode(_X3DFollowerNode):
    """
    The X3DChaserNode abstract node type calculates the output on value_changed as a finite impulse response (FIR) based on the events received on set_destination field.
    """
    NAME = '_X3DChaserNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DChaserNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DColorNode(_X3DGeometricPropertyNode):
    """
    Base type for color specifications in X3D.
    """
    NAME = '_X3DColorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DColorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DComposableVolumeRenderStyleNode(_X3DVolumeRenderStyleNode):
    """
    The X3DComposableVolumeRenderStyleNode abstract node type is the base type for all node types that allow rendering styles to be sequentially composed together to form a single renderable output.
    """
    NAME = '_X3DComposableVolumeRenderStyleNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DComposableVolumeRenderStyleNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DComposedGeometryNode(_X3DGeometryNode):
    """
    Composed geometry nodes produce renderable geometry, can contain Color Coordinate Normal TextureCoordinate, and are contained by a Shape node.
    """
    NAME = '_X3DComposedGeometryNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DComposedGeometryNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DCoordinateNode(_X3DGeometricPropertyNode):
    """
    Base type for all coordinate node types in X3D.
    """
    NAME = '_X3DCoordinateNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DCoordinateNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DDamperNode(_X3DFollowerNode):
    """
    The X3DDamperNode abstract node type creates an IIR response that approaches the destination value according to the shape of the e-function only asymptotically but very quickly.
    """
    NAME = '_X3DDamperNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DDamperNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DDragSensorNode(_X3DPointingDeviceSensorNode):
    """
    Base type for all drag-style pointing device sensors.
    """
    NAME = '_X3DDragSensorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DDragSensorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DEnvironmentalSensorNode(_X3DSensorNode):
    """
    Base type for the environmental sensor nodes ProximitySensor, TransformSensor and VisibilitySensor.
    """
    NAME = '_X3DEnvironmentalSensorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DEnvironmentalSensorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DEnvironmentTextureNode(_X3DTextureNode):
    """
    Base type for all nodes that specify cubic environment map sources for texture images.
    """
    NAME = '_X3DEnvironmentTextureNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DEnvironmentTextureNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DFontStyleNode(_X3DNode):
    """
    Base type for all font style nodes.
    """
    NAME = '_X3DFontStyleNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DFontStyleNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DGroupingNode(_X3DChildNode):
    """
    Grouping nodes can contain other nodes as children, thus making up the backbone of a scene graph.
    """
    NAME = '_X3DGroupingNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DGroupingNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DInfoNode(_X3DChildNode):
    """
    Base type for all nodes that contain only information without visual semantics.
    """
    NAME = '_X3DInfoNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DInfoNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DInterpolatorNode(_X3DChildNode):
    """
    Interpolator nodes are designed for linear keyframed animation. Interpolators are driven by an input key ranging [0..1] and produce corresponding piecewise-linear output functions.
    """
    NAME = '_X3DInterpolatorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DInterpolatorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DKeyDeviceSensorNode(_X3DSensorNode):
    """
    Base type for all sensor node types that operate using key devices.
    """
    NAME = '_X3DKeyDeviceSensorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DKeyDeviceSensorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DLayerNode(_X3DNode):
    """
    The X3DLayerNode abstract node type is the base node type for layer nodes.
    """
    NAME = '_X3DLayerNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DLayerNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DLayoutNode(_X3DChildNode):
    """
    X3DLayoutNode is the base node type for layout nodes.
    """
    NAME = '_X3DLayoutNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DLayoutNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DLightNode(_X3DChildNode):
    """
    Light nodes provide illumination for rendering geometry in the scene. Implementing nodes must include a global field with type SFBool and accessType inputOutput.
    """
    NAME = '_X3DLightNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DLightNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DMaterialNode(_X3DAppearanceChildNode):
    """
    Base type for all Material nodes.
    """
    NAME = '_X3DMaterialNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DMaterialNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DNBodyCollidableNode(_X3DChildNode):
    """
    The X3DNBodyCollidableNode abstract node type represents objects that act as the interface between the rigid body physics, collision geometry proxy, and renderable objects in the scene graph hierarchy.
    """
    NAME = '_X3DNBodyCollidableNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DNBodyCollidableNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DNBodyCollisionSpaceNode(_X3DNode):
    """
    The X3DNBodyCollisionSpaceNode abstract node type represents objects that act as a self-contained spatial collection of objects that can interact through collision detection routines.
    """
    NAME = '_X3DNBodyCollisionSpaceNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DNBodyCollisionSpaceNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DNetworkSensorNode(_X3DSensorNode):
    """
    Base typefor all sensors that generate events based on network activity.
    """
    NAME = '_X3DNetworkSensorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DNetworkSensorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DNormalNode(_X3DGeometricPropertyNode):
    """
    Base type for all normal node types in X3D.
    """
    NAME = '_X3DNormalNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DNormalNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DNurbsControlCurveNode(_X3DNode):
    """
    Base type for all nodes that provide control curve information in 2D space.
    """
    NAME = '_X3DNurbsControlCurveNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DNurbsControlCurveNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DNurbsSurfaceGeometryNode(_X3DParametricGeometryNode):
    """
    Abstract geometry type for all types of NURBS surfaces.
    """
    NAME = '_X3DNurbsSurfaceGeometryNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DNurbsSurfaceGeometryNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DParticleEmitterNode(_X3DNode):
    """
    The X3DParticleEmitterNode abstract type represents any node that is an emitter of particles.
    """
    NAME = '_X3DParticleEmitterNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DParticleEmitterNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DParticlePhysicsModelNode(_X3DNode):
    """
    The X3DParticlePhysicsModelNode abstract type represents any node that applies a form of constraints on the particles after they have been generated.
    """
    NAME = '_X3DParticlePhysicsModelNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DParticlePhysicsModelNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DPickSensorNode(_X3DSensorNode):
    """
    The X3DPickSensorNode abstract node type is the base node type that represents the lowest common denominator of picking capabilities.
    """
    NAME = '_X3DPickSensorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DPickSensorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DProductStructureChildNode(_X3DChildNode):
    """
    Base type marking nodes that are valid product structure children for the CADGeometry component.
    """
    NAME = '_X3DProductStructureChildNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DProductStructureChildNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DPrototypeInstance(_X3DNode):
    """
    Base type for all prototype instances. Note that direct children nodes are disallowed, instead let fieldValue with type SFNode/MFNode contain them. Current practice is that, if desired, prototype authors must explicitly add the metadata SFNode field in the ProtoInterface.
    """
    NAME = '_X3DPrototypeInstance'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DPrototypeInstance __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DRigidJointNode(_X3DNode):
    """
    The X3DRigidJointNode abstract node type is the base type for all joint types.
    """
    NAME = '_X3DRigidJointNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DRigidJointNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DScriptNode(_X3DChildNode):
    """
    Base type for scripting nodes (but not shader nodes).
    """
    NAME = '_X3DScriptNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DScriptNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DSequencerNode(_X3DChildNode):
    """
    Base type from which all Sequencers are derived.
    """
    NAME = '_X3DSequencerNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DSequencerNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DShaderNode(_X3DAppearanceChildNode):
    """
    Base type for all nodes that specify a programmable shader.
    """
    NAME = '_X3DShaderNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DShaderNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DShapeNode(_X3DChildNode):
    """
    Base type for all Shape nodes.
    """
    NAME = '_X3DShapeNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DShapeNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DSoundNode(_X3DChildNode):
    """
    Base type for all sound nodes.
    """
    NAME = '_X3DSoundNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DSoundNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DSoundSourceNode(_X3DTimeDependentNode):
    """
    Nodes implementing X3DSoundSourceNode are allowed as children of Sound node.
    """
    NAME = '_X3DSoundSourceNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DSoundSourceNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DTexture2DNode(_X3DTextureNode):
    """
    Base type for all nodes which specify 2D sources for texture images.
    """
    NAME = '_X3DTexture2DNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DTexture2DNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DTexture3DNode(_X3DTextureNode):
    """
    Base type for all nodes that specify 3D sources for texture images.
    """
    NAME = '_X3DTexture3DNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DTexture3DNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DTextureCoordinateNode(_X3DGeometricPropertyNode):
    """
    Base type for all nodes which specify texture coordinates.
    """
    NAME = '_X3DTextureCoordinateNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DTextureCoordinateNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DTextureTransformNode(_X3DAppearanceChildNode):
    """
    Base type for all nodes which specify a transformation of texture coordinates.
    """
    NAME = '_X3DTextureTransformNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DTextureTransformNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DTouchSensorNode(_X3DPointingDeviceSensorNode):
    """
    Base type for all touch-style pointing device sensors.
    """
    NAME = '_X3DTouchSensorNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DTouchSensorNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DTriggerNode(_X3DChildNode):
    """
    Base type from which all trigger nodes are derived.
    """
    NAME = '_X3DTriggerNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DTriggerNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DVertexAttributeNode(_X3DGeometricPropertyNode):
    """
    Base type for all nodes that specify per-vertex attribute information to the shader.
    """
    NAME = '_X3DVertexAttributeNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DVertexAttributeNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DViewpointNode(_X3DBindableNode):
    """
    Node type X3DViewpointNode defines a specific location in the local coordinate system from which the user may view the scene, and also defines a viewpoint binding stack.
    """
    NAME = '_X3DViewpointNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DViewpointNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DViewportNode(_X3DGroupingNode):
    """
    The X3DViewportNode abstract node type is the base node type for viewport nodes.
    """
    NAME = '_X3DViewportNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DViewportNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DVolumeDataNode(_X3DChildNode):
    """
    The X3DVolumeDataNode abstract node type is the base type for all node types that describe volumetric data to be rendered.
    """
    NAME = '_X3DVolumeDataNode'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractNodeType X3DVolumeDataNode __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

###############################################

# Abstract Object Types

# Note that these package-internal class names are preceded by an underscore _ character since X3D authors are not expected to use them

class _X3DBoundedObject(_X3DNode):
    """
    X3DBoundedObject indicates that bounding box values can be provided (or computed) to encompass this node and any children.
    """
    NAME = '_X3DBoundedObject'
    SPECIFICATION_URL = ''

class _X3DFogObject(_X3DNode):
    """
    Abstract type describing a node that influences the lighting equation through the use of fog semantics.
    """
    NAME = '_X3DFogObject'
    SPECIFICATION_URL = ''

class _X3DMetadataObject(_X3DNode):
    """
    Each node inheriting the X3DMetadataObject interface contains a single array of strictly typed values: MFBool, MFInt32, MFFloat, MFDouble, MFString, or MFNode, the latter having children that are all Metadata nodes.
    """
    NAME = '_X3DMetadataObject'
    SPECIFICATION_URL = ''
    def __init__(self, DEF, USE, class_, IS, metadata):
        # if _DEBUG: print('... in AbstractObjectType X3DMetadataObject __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only

class _X3DPickableObject(_X3DNode):
    """
    The X3DPickableObject abstract interface marks a node as being capable of having customized picking performed on its contents or children.
    """
    NAME = '_X3DPickableObject'
    SPECIFICATION_URL = ''

class _X3DProgrammableShaderObject(_X3DNode):
    """
    Base type for all nodes that specify arbitrary fields for interfacing with per-object attribute values.
    """
    NAME = '_X3DProgrammableShaderObject'
    SPECIFICATION_URL = ''

class _X3DUrlObject(_X3DNode):
    """
    X3DUrlObject indicates that a node has content loaded from a Uniform Resource Locator (URL) and can be tracked via a LoadSensor. Such child nodes have containerField='watchList' to indicate their relationship to the parent LoadSensor node.
    """
    NAME = '_X3DUrlObject'
    SPECIFICATION_URL = ''

###############################################

# Statements

class _X3DStatement(object):
    """
    All X3D statements implement _X3DStatement abstract type.
    """
    NAME = '_X3DStatement'
    SPECIFICATION_URL = 'https://www.web3d.org/documents/specifications/19775-1/V3.3/Part01/components/core.html#AbstractX3DStructure'
    def __repl__(self):
        result = self.NAME + '('
        # if _DEBUG: print(self.NAME + ' self.FIELD_DECLARATIONS: ' + str(self.FIELD_DECLARATIONS))
        for each in self.FIELD_DECLARATIONS:
            # if _DEBUG: print(self.NAME + ' for each in self.FIELD_DECLARATIONS: each=' + str(each))
            name = each[0]
            default = each[1]
            type_ = each[2]
            accessType = each[3]
            value = getattr(self, name)
            # if _DEBUG: print('gettattr(self, ' + str(name) + ') value="' + str(value)[:100] + '" for FIELD_DECLARATIONS ' + str(each) + ')', flush=True)
            if value != default:
                if  isinstance(value, list): # avoid X3DTypeError if value is not iterable
                    result += str(name) + '=['
                    for each in value:
                        result += str(each) + ', '
                        # if _DEBUG: print('* _X3DStatement debug: str(each)=' + str(each), flush=True)
                    result = result.rstrip(', ')
                    result += '],'
                elif isinstance(value, str) and "'" in value:
                    result += str(name) + '=' + '"' + str(value)[:100] + '"' + ','
                elif isinstance(value, str) and value != default:
                    result += str(name) + '=' + "'" + str(value)[:100] + "'" + ','
                elif value != default:
                    result += str(name) + '='       + str(value)[:100]       + ','
                # elif _DEBUG:
                #   result += str(name) + '=' + "'" + str(value)[:100] + "'" + ','
        return result.strip().rstrip(',').rstrip(', ') + ')'
    def __str__(self):
        return self.__repl__().strip() # _X3DStatement

def isX3DStatement(value):
    """
    Whether or not value is an _X3DStatement object.
    """
    return isinstance(value, _X3DStatement)

class Comment(_X3DStatement):
    """
    X3D statement containing zero or more comment strings.
    """
    NAME = 'Comment'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html'
    DEFAULT_VALUE = list()
    REGEX_XML = r'(\s|\S)*' # (includes lower-case true, false)
    def __init__(self, value=None):
        self.value = value
    @property # getter - - - - - - - - - -
    def value(self):
        """ Provide list of comment strings. """
        return self.__value
    @value.setter
    def value(self, value=None):
        """ The value setter only allows correctly typed values. """
        if  value is None:
            value = self.DEFAULT_VALUE
        assertValidMFString(value)
        self.__value = value

def isComment(value):
    """
    Whether or not value is an _X3DComment object.
    """
    return isinstance(value, _X3DComment)

class component(_X3DStatement):
    """
    Functional summary: each added component statement indicates needed scene functionality support above the given X3D profile.
    """
    NAME = 'component'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#component'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('level', 1, FieldType.SFInt32, AccessType.inputOutput, 'component'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'component')]
    def __init__(self,
                 level=1,
                 name=''):
        self.level = level
        self.name = name
    @property # getter - - - - - - - - - -
    def level(self):
        """Necessary level of support for this scene, as defined in corresponding Support table for a given node's component."""
        return self.__level
    @level.setter
    def level(self, level=None):
        if  level is None:
            level = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(level)
        assertGreaterThanEquals('level', level, 1)
        assertLessThanEquals('level', level, 5)
        self.__level = level
    @property # getter - - - - - - - - - -
    def name(self):
        """Provides name of this component, as defined in corresponding X3D Specification component Introduction."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return False
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function component.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<component'
        if self.level != 1:
            result += " level='" + SFInt32(self.level).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            result += indent + '</component>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class connect(_X3DStatement):
    """
    Functional summary: connect statements define event-routing connections between node fields defined inside a ProtoBody declaration back to corresponding ProtoInterface fields.
    """
    NAME = 'connect'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#connect'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('nodeField', '', FieldType.SFString, AccessType.inputOutput, 'connect'),
        ('protoField', '', FieldType.SFString, AccessType.inputOutput, 'connect')]
    def __init__(self,
                 nodeField='',
                 protoField=''):
        self.nodeField = nodeField
        self.protoField = protoField
    @property # getter - - - - - - - - - -
    def nodeField(self):
        """Name of field within this node which IS CONNECTed to the ancestor ProtoDeclare field definition."""
        return self.__nodeField
    @nodeField.setter
    def nodeField(self, nodeField=None):
        if  nodeField is None:
            nodeField = SFString.DEFAULT_VALUE
        assertValidSFString(nodeField)
        self.__nodeField = nodeField
    @property # getter - - - - - - - - - -
    def protoField(self):
        """Name of parent ProtoDeclare field definition connecting to field in this node."""
        return self.__protoField
    @protoField.setter
    def protoField(self, protoField=None):
        if  protoField is None:
            protoField = SFString.DEFAULT_VALUE
        assertValidSFString(protoField)
        self.__protoField = protoField
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return False
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function connect.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<connect'
        if self.nodeField:
            result += " nodeField='" + self.nodeField + "'"
        if self.protoField:
            result += " protoField='" + self.protoField + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            result += indent + '</connect>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class EXPORT(_X3DStatement):
    """
    Functional summary: EXPORT exposes a local node for ROUTE passing of event values when the current Scene is included via Inline by a parent external world. These connections allow event values to be exchanged via ROUTE statements between a parent model and a child Inline model.
    """
    NAME = 'EXPORT'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#EXPORT'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('AS', '', FieldType.SFString, AccessType.inputOutput, 'EXPORT'),
        ('localDEF', '', FieldType.SFString, AccessType.inputOutput, 'EXPORT')]
    def __init__(self,
                 AS='',
                 localDEF=''):
        self.AS = AS
        self.localDEF = localDEF
    @property # getter - - - - - - - - - -
    def AS(self):
        """rename localDEF node AS a different name when exporting."""
        return self.__AS
    @AS.setter
    def AS(self, AS=None):
        if  AS is None:
            AS = SFString.DEFAULT_VALUE
        assertValidSFString(AS)
        self.__AS = AS
    @property # getter - - - - - - - - - -
    def localDEF(self):
        """localDEF is the DEF name of the local node to be EXPORTed."""
        return self.__localDEF
    @localDEF.setter
    def localDEF(self, localDEF=None):
        if  localDEF is None:
            localDEF = SFString.DEFAULT_VALUE
        assertValidSFString(localDEF)
        self.__localDEF = localDEF
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return False
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function EXPORT.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<EXPORT'
        if self.AS:
            result += " AS='" + self.AS + "'"
        if self.localDEF:
            result += " localDEF='" + self.localDEF + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            result += indent + '</EXPORT>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ExternProtoDeclare(_X3DStatement):
    """
    ExternProtoDeclare refers to a ProtoDeclare node declaration provided in another file. ExternProtoDeclare interfaces are defined by field statements (and without IS/connect statements).
    """
    NAME = 'ExternProtoDeclare'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ExternProtoDeclare'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('appinfo', '', FieldType.SFString, AccessType.inputOutput, 'ExternProtoDeclare'),
        ('documentation', '', FieldType.SFString, AccessType.inputOutput, 'ExternProtoDeclare'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'ExternProtoDeclare'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'ExternProtoDeclare'),
        ('field', list(), FieldType.MFNode, AccessType.inputOutput, 'ExternProtoDeclare')]
    def __init__(self,
                 appinfo='',
                 documentation='',
                 name='',
                 url=list(),
                 field=list()):
        self.appinfo = appinfo
        self.documentation = documentation
        self.name = name
        self.url = url
        self.field = field
    @property # getter - - - - - - - - - -
    def appinfo(self):
        """Application information to provide simple description usable as a tooltip, similar to XML Schema appinfo tag."""
        return self.__appinfo
    @appinfo.setter
    def appinfo(self, appinfo=None):
        if  appinfo is None:
            appinfo = SFString.DEFAULT_VALUE
        assertValidSFString(appinfo)
        self.__appinfo = appinfo
    @property # getter - - - - - - - - - -
    def documentation(self):
        """Documentation url for further information, similar to XML Schema documentation tag."""
        return self.__documentation
    @documentation.setter
    def documentation(self, documentation=None):
        if  documentation is None:
            documentation = SFString.DEFAULT_VALUE
        assertValidSFString(documentation)
        self.__documentation = documentation
    @property # getter - - - - - - - - - -
    def name(self):
        """name of the ExternProtoDeclare (External Prototype Declaration) being referenced."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def url(self):
        """Location and filename of ProtoDeclare source declaration of interest."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def field(self):
        """Include a field statement for each field declaration in the corresponding original ProtoDeclare."""
        return self.__field
    @field.setter
    def field(self, field=None):
        if  field is None:
            field = MFNode.DEFAULT_VALUE
        # TODO type-aware checks for field
        if field: # walk each child node, if any
            for each in field:
                assertValidFieldInitializationValue(each.name, type(each.value), each.value, parent='ExternProtoDeclare/field')
        self.__field = field
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.field)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ExternProtoDeclare.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ExternProtoDeclare'
        if self.appinfo:
            result += " appinfo='" + self.appinfo + "'"
        if self.documentation:
            result += " documentation='" + self.documentation + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.field: # walk each child node, if any
                for each in self.field:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ExternProtoDeclare>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class field(_X3DStatement):
    """
    Functional summary: a field statement defines an interface attribute or node. Each field statement can contain either attribute-value or node content.
    """
    NAME = 'field'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#field'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('accessType', '', FieldType.SFString, AccessType.inputOutput, 'field'),
        ('appinfo', '', FieldType.SFString, AccessType.inputOutput, 'field'),
        ('documentation', '', FieldType.SFString, AccessType.inputOutput, 'field'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'field'),
        ('type', '', FieldType.SFString, AccessType.inputOutput, 'field'),
        ('value', '', FieldType.SFString, AccessType.inputOutput, 'field'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'field')]
    def __init__(self,
                 accessType='',
                 appinfo='',
                 documentation='',
                 name='',
                 type='',
                 value='',
                 children=list()):
        self.accessType = accessType
        self.appinfo = appinfo
        self.documentation = documentation
        self.name = name
        self.type = type
        self.value = value
        self.children = children
    @property # getter - - - - - - - - - -
    def accessType(self):
        """Event-model semantics for field set/get capabilities."""
        return self.__accessType
    @accessType.setter
    def accessType(self, accessType=None):
        if  accessType is None:
            accessType = SFString.DEFAULT_VALUE
        assertValidSFString(accessType)
        self.__accessType = accessType
    @property # getter - - - - - - - - - -
    def appinfo(self):
        """Application information to provide simple description usable as a tooltip, similar to XML Schema appinfo tag."""
        return self.__appinfo
    @appinfo.setter
    def appinfo(self, appinfo=None):
        if  appinfo is None:
            appinfo = SFString.DEFAULT_VALUE
        assertValidSFString(appinfo)
        self.__appinfo = appinfo
    @property # getter - - - - - - - - - -
    def documentation(self):
        """Documentation url for further information, similar to XML Schema documentation tag."""
        return self.__documentation
    @documentation.setter
    def documentation(self, documentation=None):
        if  documentation is None:
            documentation = SFString.DEFAULT_VALUE
        assertValidSFString(documentation)
        self.__documentation = documentation
    @property # getter - - - - - - - - - -
    def name(self):
        """Name of this field declaration."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def type(self):
        """Base type of this field variable."""
        return self.__type
    @type.setter
    def type(self, type=None):
        if  type is None:
            type = SFString.DEFAULT_VALUE
        assertValidSFString(type)
        self.__type = type
    @property # getter - - - - - - - - - -
    def value(self):
        """Provide default initialization value for this field variable (which may be re-initialized later by instantiation value of a named ProtoInstance fieldValue)."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = SFString.DEFAULT_VALUE
        assertValidFieldInitializationValue(self.name, self.type, value, parent='field/@value')
        self.__value = value
    @property # getter - - - - - - - - - -
    def children(self):
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function field.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<field'
        if self.accessType:
            result += " accessType='" + self.accessType + "'"
        if self.appinfo:
            result += " appinfo='" + self.appinfo + "'"
        if self.documentation:
            result += " documentation='" + self.documentation + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.type:
            result += " type='" + self.type + "'"
        if self.value:
            result += " value='" + SFString(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</field>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class fieldValue(_X3DStatement):
    """
    Functional summary: a fieldValue statement re-initializes the default value of a field in a ProtoInstance. Each fieldValue statement can contain either attribute-value or node content.
    """
    NAME = 'fieldValue'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#fieldValue'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'fieldValue'),
        ('value', '', FieldType.SFString, AccessType.inputOutput, 'fieldValue'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'fieldValue')]
    def __init__(self,
                 name='',
                 value='',
                 children=list()):
        self.name = name
        self.value = value
        self.children = children
    @property # getter - - - - - - - - - -
    def name(self):
        """Name of the ProtoInstance field being re-initialized (corresponding to field name already defined in ProtoDeclare or ExternProtoDeclare)."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def value(self):
        """Initial value for this field, which overrides default initialization value defined in original ProtoDeclare field."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = SFString.DEFAULT_VALUE
        assertValidFieldInitializationValue(self.name, type(value), value, parent='fieldValue')
        self.__value = value
    @property # getter - - - - - - - - - -
    def children(self):
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function fieldValue.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<fieldValue'
        if self.name:
            result += " name='" + self.name + "'"
        if self.value:
            result += " value='" + SFString(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</fieldValue>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class head(_X3DStatement):
    """
    Functional summary: each X3D scene includes a head statement that can contain component, unit and meta statements.
    """
    NAME = 'head'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#head'
    FIELD_DECLARATIONS = [('children', None, FieldType.MFNode, AccessType.inputOutput, 'head')]
    def __init__(self, children=None):
        self.children = children
    @property # getter - - - - - - - - - -
    def children(self):
        """ The head statement has children consisting of component, unit and meta statements. """
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function head.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<head'
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                ## print('* head found self.children, now invoking XML(' + str(indentLevel+1) + ')', flush=True)
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</head>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IMPORT(_X3DStatement):
    """
    Functional summary: IMPORT provides ROUTE access to a node that has a corresponding EXPORT statement within an Inline scene. These connections allow event values to be exchanged via ROUTE statements between a parent model and a child Inline model.
    """
    NAME = 'IMPORT'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IMPORT'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('AS', '', FieldType.SFString, AccessType.inputOutput, 'IMPORT'),
        ('importedDEF', '', FieldType.SFString, AccessType.inputOutput, 'IMPORT'),
        ('inlineDEF', '', FieldType.SFString, AccessType.inputOutput, 'IMPORT')]
    def __init__(self,
                 AS='',
                 importedDEF='',
                 inlineDEF=''):
        self.AS = AS
        self.importedDEF = importedDEF
        self.inlineDEF = inlineDEF
    @property # getter - - - - - - - - - -
    def AS(self):
        """map importedDEF name AS a new name in current scene."""
        return self.__AS
    @AS.setter
    def AS(self, AS=None):
        if  AS is None:
            AS = SFString.DEFAULT_VALUE
        assertValidSFString(AS)
        self.__AS = AS
    @property # getter - - - - - - - - - -
    def importedDEF(self):
        """importedDEF is DEF name of the node of interest that is contained in the remote inlineDEF scene."""
        return self.__importedDEF
    @importedDEF.setter
    def importedDEF(self, importedDEF=None):
        if  importedDEF is None:
            importedDEF = SFString.DEFAULT_VALUE
        assertValidSFString(importedDEF)
        self.__importedDEF = importedDEF
    @property # getter - - - - - - - - - -
    def inlineDEF(self):
        """inlineDEF is the DEF name of Inline node in the same scene as this IMPORT statement."""
        return self.__inlineDEF
    @inlineDEF.setter
    def inlineDEF(self, inlineDEF=None):
        if  inlineDEF is None:
            inlineDEF = SFString.DEFAULT_VALUE
        assertValidSFString(inlineDEF)
        self.__inlineDEF = inlineDEF
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return False
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IMPORT.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IMPORT'
        if self.AS:
            result += " AS='" + self.AS + "'"
        if self.importedDEF:
            result += " importedDEF='" + self.importedDEF + "'"
        if self.inlineDEF:
            result += " inlineDEF='" + self.inlineDEF + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            result += indent + '</IMPORT>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IS(_X3DStatement):
    """
    Functional summary: the IS statement connects node fields defined inside a ProtoBody declaration back to corresponding ProtoInterface fields. IS/connect statements can be added if the parent node is within a ProtoBody and connect statements define correspondences between prototype fields and built-in node fields.
    """
    NAME = 'IS'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IS'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('connect', list(), FieldType.MFNode, AccessType.inputOutput, 'IS')]
    def __init__(self,
                 connect=list()):
        self.connect = connect
    @property # getter - - - - - - - - - -
    def connect(self):
        """When inside a ProtoBody declaration and an IS statement, add a connect statement to define event-routing connections between a parent node's field to a corresponding ProtoInterface field."""
        return self.__connect
    @connect.setter
    def connect(self, connect=None):
        if  connect is None:
            connect = MFNode.DEFAULT_VALUE
        assertValidMFNode(connect)
        self.__connect = connect
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.connect)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IS.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IS'
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.connect: # walk each child node, if any
                for each in self.connect:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</IS>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class meta(_X3DStatement):
    """
    Functional summary: the meta statement provides metadata information about a scene, where name and content attributes provide attribute=value metadata pairs.
    """
    NAME = 'meta'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#meta'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('content', '', FieldType.SFString, AccessType.inputOutput, 'meta'),
        ('dir', '', FieldType.SFString, AccessType.inputOutput, 'meta'),
        ('httpequiv', '', FieldType.SFString, AccessType.inputOutput, 'meta'),
        ('lang', '', FieldType.SFString, AccessType.inputOutput, 'meta'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'meta'),
        ('scheme', '', FieldType.SFString, AccessType.inputOutput, 'meta')]
    def __init__(self,
                 content='',
                 dir='',
                 httpequiv='',
                 lang='',
                 name='',
                 scheme=''):
        self.content = content
        self.dir = dir
        self.httpequiv = httpequiv
        self.lang = lang
        self.name = name
        self.scheme = scheme
    @property # getter - - - - - - - - - -
    def content(self):
        """The content attribute provides metadata information relevant to the name attribute provided."""
        return self.__content
    @content.setter
    def content(self, content=None):
        if  content is None:
            content = SFString.DEFAULT_VALUE
        assertValidSFString(content)
        self.__content = content
    @property # getter - - - - - - - - - -
    def dir(self):
        """Direction for weak/neutral text (ltr=left-to-right, rtl=right-to-left)."""
        return self.__dir
    @dir.setter
    def dir(self, dir=None):
        if  dir is None:
            dir = SFString.DEFAULT_VALUE
        assertValidSFString(dir)
        self.__dir = dir
    @property # getter - - - - - - - - - -
    def httpequiv(self):
        return self.__httpequiv
    @httpequiv.setter
    def httpequiv(self, httpequiv=None):
        if  httpequiv is None:
            httpequiv = SFString.DEFAULT_VALUE
        assertValidSFString(httpequiv)
        self.__httpequiv = httpequiv
    @property # getter - - - - - - - - - -
    def lang(self):
        """Language code, as per [IETF BCP47/RFC5646] http://www."""
        return self.__lang
    @lang.setter
    def lang(self, lang=None):
        if  lang is None:
            lang = SFString.DEFAULT_VALUE
        assertValidSFString(lang)
        self.__lang = lang
    @property # getter - - - - - - - - - -
    def name(self):
        """Keyword name of the meta attribute, following the same naming conventions as HTML's meta tag."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def scheme(self):
        """The scheme attribute allows authors to provide user agents more context for the correct interpretation of meta information."""
        return self.__scheme
    @scheme.setter
    def scheme(self, scheme=None):
        if  scheme is None:
            scheme = SFString.DEFAULT_VALUE
        assertValidSFString(scheme)
        self.__scheme = scheme
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return False
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function meta.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<meta'
        if self.content:
            result += " content='" + self.content + "'"
        if self.dir:
            result += " dir='" + self.dir + "'"
        if self.httpequiv:
            result += " httpequiv='" + self.httpequiv + "'"
        if self.lang:
            result += " lang='" + self.lang + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.scheme:
            result += " scheme='" + self.scheme + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            result += indent + '</meta>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ProtoBody(_X3DStatement):
    """
    ProtoBody contains the definition nodes for new Prototype nodes.
    """
    NAME = 'ProtoBody'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ProtoBody'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'ProtoBody')]
    def __init__(self,
                 children=list()):
        self.children = children
    @property # getter - - - - - - - - - -
    def children(self):
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ProtoBody.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ProtoBody'
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ProtoBody>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ProtoDeclare(_X3DStatement):
    """
    ProtoDeclare defines new Prototype nodes. Nested ProtoDeclares and ProtoInstances are allowed by the specification.
    """
    NAME = 'ProtoDeclare'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ProtoDeclare'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('appinfo', '', FieldType.SFString, AccessType.inputOutput, 'ProtoDeclare'),
        ('documentation', '', FieldType.SFString, AccessType.inputOutput, 'ProtoDeclare'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'ProtoDeclare'),
        ('ProtoBody', None, FieldType.SFNode, AccessType.inputOutput, 'ProtoDeclare'),
        ('ProtoInterface', None, FieldType.SFNode, AccessType.inputOutput, 'ProtoDeclare')]
    def __init__(self,
                 appinfo='',
                 documentation='',
                 name='',
                 ProtoBody=None,
                 ProtoInterface=None):
        self.appinfo = appinfo
        self.documentation = documentation
        self.name = name
        self.ProtoBody = ProtoBody
        self.ProtoInterface = ProtoInterface
    @property # getter - - - - - - - - - -
    def appinfo(self):
        """Application information to provide simple description usable as a tooltip, similar to XML Schema appinfo tag."""
        return self.__appinfo
    @appinfo.setter
    def appinfo(self, appinfo=None):
        if  appinfo is None:
            appinfo = SFString.DEFAULT_VALUE
        assertValidSFString(appinfo)
        self.__appinfo = appinfo
    @property # getter - - - - - - - - - -
    def documentation(self):
        """Documentation url for further information, similar to XML Schema documentation tag."""
        return self.__documentation
    @documentation.setter
    def documentation(self, documentation=None):
        if  documentation is None:
            documentation = SFString.DEFAULT_VALUE
        assertValidSFString(documentation)
        self.__documentation = documentation
    @property # getter - - - - - - - - - -
    def name(self):
        """name of this prototype being declared."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def ProtoBody(self):
        """Include one ProtoBody statements after the ProtoInterface statement."""
        return self.__ProtoBody
    @ProtoBody.setter
    def ProtoBody(self, ProtoBody=None):
        if  ProtoBody is None:
            ProtoBody = SFNode.DEFAULT_VALUE
        assertValidSFNode(ProtoBody)
        if not isinstance(ProtoBody, object):
            # print(flush=True)
            raise X3DTypeError(str(ProtoBody) + ' does not have a valid node type object')
        self.__ProtoBody = ProtoBody
    @property # getter - - - - - - - - - -
    def ProtoInterface(self):
        """Include an optional ProtoInterface statement if this ProtoDeclare has field declarations."""
        return self.__ProtoInterface
    @ProtoInterface.setter
    def ProtoInterface(self, ProtoInterface=None):
        if  ProtoInterface is None:
            ProtoInterface = SFNode.DEFAULT_VALUE
        assertValidSFNode(ProtoInterface)
        if not isinstance(ProtoInterface, object):
            # print(flush=True)
            raise X3DTypeError(str(ProtoInterface) + ' does not have a valid node type object')
        self.__ProtoInterface = ProtoInterface
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.ProtoBody) or bool(self.ProtoInterface)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ProtoDeclare.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ProtoDeclare'
        if self.appinfo:
            result += " appinfo='" + self.appinfo + "'"
        if self.documentation:
            result += " documentation='" + self.documentation + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.ProtoBody: # output this SFNode
                result += self.ProtoBody.XML(indentLevel=indentLevel+1)
            if self.ProtoInterface: # output this SFNode
                result += self.ProtoInterface.XML(indentLevel=indentLevel+1)
            result += indent + '</ProtoDeclare>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ProtoInterface(_X3DStatement):
    """
    ProtoInterface defines fields for new Prototype nodes.
    """
    NAME = 'ProtoInterface'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ProtoInterface'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('field', list(), FieldType.MFNode, AccessType.inputOutput, 'ProtoInterface')]
    def __init__(self,
                 field=list()):
        self.field = field
    @property # getter - - - - - - - - - -
    def field(self):
        """Include a field statement for each field declaration in this ProtoDeclare's ProtoInterface."""
        return self.__field
    @field.setter
    def field(self, field=None):
        if  field is None:
            field = MFNode.DEFAULT_VALUE
        # TODO type-aware checks for field
        if field: # walk each child node, if any
            for each in field:
                assertValidFieldInitializationValue(each.name, each.type, each.value, parent='ProtoInterface')
        self.__field = field
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.field)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ProtoInterface.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ProtoInterface'
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.field: # walk each child node, if any
                for each in self.field:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ProtoInterface>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ROUTE(_X3DStatement):
    """
    ROUTE connects output fields of event-producing nodes to input fields of event-consuming nodes.
    """
    NAME = 'ROUTE'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ROUTE'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('fromField', '', FieldType.SFString, AccessType.inputOutput, 'ROUTE'),
        ('fromNode', '', FieldType.SFString, AccessType.inputOutput, 'ROUTE'),
        ('toField', '', FieldType.SFString, AccessType.inputOutput, 'ROUTE'),
        ('toNode', '', FieldType.SFString, AccessType.inputOutput, 'ROUTE')]
    def __init__(self,
                 fromField='',
                 fromNode='',
                 toField='',
                 toNode=''):
        self.fromField = fromField
        self.fromNode = fromNode
        self.toField = toField
        self.toNode = toNode
    @property # getter - - - - - - - - - -
    def fromField(self):
        """fromField is the field name in the source node which is originating an event."""
        return self.__fromField
    @fromField.setter
    def fromField(self, fromField=None):
        if  fromField is None:
            fromField = SFString.DEFAULT_VALUE
        assertValidSFString(fromField)
        self.__fromField = fromField
    @property # getter - - - - - - - - - -
    def fromNode(self):
        """fromNode is the DEF name of the node originating an event."""
        return self.__fromNode
    @fromNode.setter
    def fromNode(self, fromNode=None):
        if  fromNode is None:
            fromNode = SFString.DEFAULT_VALUE
        assertValidSFString(fromNode)
        self.__fromNode = fromNode
    @property # getter - - - - - - - - - -
    def toField(self):
        """toField is the field name in the destination node which is receiving an event."""
        return self.__toField
    @toField.setter
    def toField(self, toField=None):
        if  toField is None:
            toField = SFString.DEFAULT_VALUE
        assertValidSFString(toField)
        self.__toField = toField
    @property # getter - - - - - - - - - -
    def toNode(self):
        """toNode is the DEF name of the destination node receiving an event."""
        return self.__toNode
    @toNode.setter
    def toNode(self, toNode=None):
        if  toNode is None:
            toNode = SFString.DEFAULT_VALUE
        assertValidSFString(toNode)
        self.__toNode = toNode
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return False
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ROUTE.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ROUTE'
        if self.fromField:
            result += " fromField='" + self.fromField + "'"
        if self.fromNode:
            result += " fromNode='" + self.fromNode + "'"
        if self.toField:
            result += " toField='" + self.toField + "'"
        if self.toNode:
            result += " toNode='" + self.toNode + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            result += indent + '</ROUTE>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Scene(_X3DStatement):
    """
    Scene is the implicit root node of the X3D scene graph.
    """
    NAME = 'Scene'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Scene'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'Scene')]
    def __init__(self,
                 children=list()):
        self.children = children
    @property # getter - - - - - - - - - -
    def children(self):
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Scene.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Scene'
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Scene>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class unit(_X3DStatement):
    """
    Functional summary: unit statement defines data-conversion factors for typed values defined in a scene.
    """
    NAME = 'unit'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#unit'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('category', '', FieldType.SFString, AccessType.initializeOnly, 'unit'),
        ('conversionFactor', 1.0, FieldType.SFDouble, AccessType.inputOutput, 'unit'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'unit')]
    def __init__(self,
                 category='',
                 conversionFactor=1.0,
                 name=''):
        self.category = category
        self.conversionFactor = conversionFactor
        self.name = name
    @property # getter - - - - - - - - - -
    def category(self):
        """Base-unit category as defined in X3D Specification."""
        return self.__category
    @category.setter
    def category(self, category=None):
        if  category is None:
            category = SFString.DEFAULT_VALUE
        assertValidSFString(category)
        self.__category = category
    @property # getter - - - - - - - - - -
    def conversionFactor(self):
        """[0,+infinity) Positive double-precision factor that converts new base unit to default base unit."""
        return self.__conversionFactor
    @conversionFactor.setter
    def conversionFactor(self, conversionFactor=None):
        if  conversionFactor is None:
            conversionFactor = SFDouble.DEFAULT_VALUE
        assertValidSFDouble(conversionFactor)
        assertPositive('conversionFactor', conversionFactor)
        self.__conversionFactor = conversionFactor
    @property # getter - - - - - - - - - -
    def name(self):
        """Author-defined name for this unit conversionFactor value (for example, FeetToMeters)."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return False
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function unit.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<unit'
        if self.category:
            result += " category='" + self.category + "'"
        if self.conversionFactor != 1.0:
            result += " conversionFactor='" + SFDouble(self.conversionFactor).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            result += indent + '</unit>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class X3D(_X3DNode):
    """
    X3D is the root node for an Extensible 3D (X3D) Graphics model.
    """
    NAME = 'X3D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#X3D'
    XML_HEADER = '<?xml version="1.0" encoding="UTF-8"?>'
    XML_DOCTYPE_X3D_3_0 = '<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "http://www.web3d.org/specifications/x3d-3.0.dtd">'
    XML_DOCTYPE_X3D_3_1 = '<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.1//EN" "http://www.web3d.org/specifications/x3d-3.1.dtd">'
    XML_DOCTYPE_X3D_3_2 = '<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.2//EN" "http://www.web3d.org/specifications/x3d-3.2.dtd">'
    XML_DOCTYPE_X3D_3_3 = '<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "http://www.web3d.org/specifications/x3d-3.3.dtd">'
    XML_DOCTYPE_X3D_4_0 = '<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "http://www.web3d.org/specifications/x3d-4.0.dtd">'
    X3D_XML_SCHEMA_ATTRIBUTES_3_0 = "xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-3.0.xsd'"
    X3D_XML_SCHEMA_ATTRIBUTES_3_1 = "xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-3.1.xsd'"
    X3D_XML_SCHEMA_ATTRIBUTES_3_2 = "xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-3.2.xsd'"
    X3D_XML_SCHEMA_ATTRIBUTES_3_3 = "xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-3.3.xsd'"
    X3D_XML_SCHEMA_ATTRIBUTES_4_0 = "xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-4.0.xsd'"
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('profile', 'Immersive', FieldType.SFString, AccessType.inputOutput, 'X3D'),
        ('version', '4.0', FieldType.SFString, AccessType.inputOutput, 'X3D'),
        ('head', None, FieldType.SFNode, AccessType.inputOutput, 'X3D'),
        ('Scene', None, FieldType.SFNode, AccessType.inputOutput, 'X3D')]
    def __init__(self,
                 profile='Immersive',
                 version='4.0',
                 head=None,
                 Scene=None):
        self.profile = profile
        self.version = version
        self.head = head
        self.Scene = Scene
    @property # getter - - - - - - - - - -
    def profile(self):
        """profile attribute is required and defines the player or tool support needed for this model."""
        return self.__profile
    @profile.setter
    def profile(self, profile=None):
        if  profile is None:
            profile = SFString.DEFAULT_VALUE
        assertValidSFString(profile)
        self.__profile = profile
    @property # getter - - - - - - - - - -
    def version(self):
        """Default is highest value matching schema and DOCTYPE in the scene."""
        return self.__version
    @version.setter
    def version(self, version=None):
        if  version is None:
            version = SFString.DEFAULT_VALUE
        assertValidSFString(version)
        self.__version = version
    @property # getter - - - - - - - - - -
    def head(self):
        """Include a head element to contain component, unit or meta statements for this X3D model."""
        return self.__head
    @head.setter
    def head(self, head=None):
        if  head is None:
            head = SFNode.DEFAULT_VALUE
        assertValidSFNode(head)
        if not isinstance(head, object):
            # print(flush=True)
            raise X3DTypeError(str(head) + ' does not have a valid node type object')
        self.__head = head
    @property # getter - - - - - - - - - -
    def Scene(self):
        """Include a Scene element to contain scene-graph nodes for this X3D model."""
        return self.__Scene
    @Scene.setter
    def Scene(self, Scene=None):
        if  Scene is None:
            Scene = SFNode.DEFAULT_VALUE
        assertValidSFNode(Scene)
        if not isinstance(Scene, object):
            # print(flush=True)
            raise X3DTypeError(str(Scene) + ' does not have a valid node type object')
        self.__Scene = Scene
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.head) or bool(self.Scene)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        # if _DEBUG: result += indent + '# invoked class function X3D.XML(indentLevel=' + str(indentLevel) + '), indent="' + indent + '"' + '\n'
        result += indent + self.XML_HEADER + '\n'
        if self.version == '3.0':
            result += indent + self.XML_DOCTYPE_X3D_3_0 + '\n'
        elif self.version == '3.1':
            result += indent + self.XML_DOCTYPE_X3D_3_1 + '\n'
        elif self.version == '3.2':
            result += indent + self.XML_DOCTYPE_X3D_3_2 + '\n'
        elif self.version == '3.3':
            result += indent + self.XML_DOCTYPE_X3D_3_3 + '\n'
        elif self.version == '4.0':
            result += indent + self.XML_DOCTYPE_X3D_4_0 + '\n'
        elif self.version == '4.1':
            result += indent + self.XML_DOCTYPE_X3D_4_1 + '\n'
        result += indent + "<X3D profile='" + self.profile +"' version='" + self.version +"' "
        if self.version == '3.0':
            result += self.X3D_XML_SCHEMA_ATTRIBUTES_3_0
        elif self.version == '3.1':
            result += self.X3D_XML_SCHEMA_ATTRIBUTES_3_1
        elif self.version == '3.2':
            result += self.X3D_XML_SCHEMA_ATTRIBUTES_3_2
        elif self.version == '3.3':
            result += self.X3D_XML_SCHEMA_ATTRIBUTES_3_3
        elif self.version == '4.0':
            result += self.X3D_XML_SCHEMA_ATTRIBUTES_4_0
        elif self.version == '4.1':
            result += self.X3D_XML_SCHEMA_ATTRIBUTES_4_1
        result += '>' + '\n' # finish open tag
        if self.head and self.head.hasChild():
            result += str(self.head.XML(indentLevel=indentLevel+1))
        if self.Scene and self.Scene.hasChild():
            result += str(self.Scene.XML(indentLevel=indentLevel+1))
        result += '</X3D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

###############################################

# Concrete Nodes

def isX3DNode(value):
    return isinstance(value, _X3DNode)

class Anchor(_X3DGroupingNode, _X3DUrlObject):
    """
    Anchor is a Grouping node that can contain most nodes.
    """
    NAME = 'Anchor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Anchor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'Anchor'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('parameter', list(), FieldType.MFString, AccessType.inputOutput, 'Anchor'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 description='',
                 displayBBox=False,
                 parameter=list(),
                 url=list(),
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Anchor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.description = description
        self.displayBBox = displayBBox
        self.parameter = parameter
        self.url = url
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def parameter(self):
        """If provided, parameter tells the X3D player where to to redirect the loaded url."""
        return self.__parameter
    @parameter.setter
    def parameter(self, parameter=None):
        if  parameter is None:
            parameter = MFString.DEFAULT_VALUE
        assertValidMFString(parameter)
        self.__parameter = parameter
    @property # getter - - - - - - - - - -
    def url(self):
        """Address of replacement world, or #ViewpointDEFName within the current scene, or alternate Web resource, activated by the user selecting Shape geometry within the Anchor children nodes."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Anchor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Anchor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.parameter != list():
            result += " parameter='" + MFString(self.parameter).XML() + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Anchor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Appearance(_X3DAppearanceNode):
    """
    Appearance specifies the visual properties of geometry by containing the Material, ImageTexture/MovieTexture/PixelTexture, FillProperties, LineProperties, programmable shader nodes (ComposedShader, PackagedShader, ProgramShader) and TextureTransform nodes.
    """
    NAME = 'Appearance'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Appearance'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('fillProperties', None, FieldType.SFNode, AccessType.inputOutput, 'Appearance'),
        ('lineProperties', None, FieldType.SFNode, AccessType.inputOutput, 'Appearance'),
        ('material', None, FieldType.SFNode, AccessType.inputOutput, 'Appearance'),
        ('pointProperties', None, FieldType.SFNode, AccessType.inputOutput, 'Appearance'),
        ('texture', None, FieldType.SFNode, AccessType.inputOutput, 'Appearance'),
        ('textureTransform', None, FieldType.SFNode, AccessType.inputOutput, 'Appearance'),
        ('shaders', list(), FieldType.MFNode, AccessType.inputOutput, 'Appearance'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 fillProperties=None,
                 lineProperties=None,
                 material=None,
                 pointProperties=None,
                 texture=None,
                 textureTransform=None,
                 shaders=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Appearance __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.fillProperties = fillProperties
        self.lineProperties = lineProperties
        self.material = material
        self.pointProperties = pointProperties
        self.texture = texture
        self.textureTransform = textureTransform
        self.shaders = shaders
    @property # getter - - - - - - - - - -
    def fillProperties(self):
        """[FillProperties] Single contained FillProperties node that specifies additional visual attributes applied to polygonal areas of corresponding geometry, on top of whatever other appearance is already defined."""
        return self.__fillProperties
    @fillProperties.setter
    def fillProperties(self, fillProperties=None):
        if  fillProperties is None:
            fillProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(fillProperties)
        if not isinstance(fillProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(fillProperties) + ' does not have a valid node type object')
        self.__fillProperties = fillProperties
    @property # getter - - - - - - - - - -
    def lineProperties(self):
        """[LineProperties] Single contained LineProperties node that specifies additional visual attributes applied to corresponding line geometry."""
        return self.__lineProperties
    @lineProperties.setter
    def lineProperties(self, lineProperties=None):
        if  lineProperties is None:
            lineProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(lineProperties)
        if not isinstance(lineProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(lineProperties) + ' does not have a valid node type object')
        self.__lineProperties = lineProperties
    @property # getter - - - - - - - - - -
    def material(self):
        """[X3DMaterialNode] Single contained Material node that specifies visual attributes for lighting response (color types, transparency, etc."""
        return self.__material
    @material.setter
    def material(self, material=None):
        if  material is None:
            material = SFNode.DEFAULT_VALUE
        assertValidSFNode(material)
        if not isinstance(material, object):
            # print(flush=True)
            raise X3DTypeError(str(material) + ' does not have a valid node type object')
        self.__material = material
    @property # getter - - - - - - - - - -
    def pointProperties(self):
        return self.__pointProperties
    @pointProperties.setter
    def pointProperties(self, pointProperties=None):
        if  pointProperties is None:
            pointProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(pointProperties)
        if not isinstance(pointProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(pointProperties) + ' does not have a valid node type object')
        self.__pointProperties = pointProperties
    @property # getter - - - - - - - - - -
    def texture(self):
        """[X3DTextureNode] Single contained texture node (ImageTexture, MovieTexture, PixelTexture, MultiTexture) that maps image(s) to surface geometry."""
        return self.__texture
    @texture.setter
    def texture(self, texture=None):
        if  texture is None:
            texture = SFNode.DEFAULT_VALUE
        assertValidSFNode(texture)
        if not isinstance(texture, object):
            # print(flush=True)
            raise X3DTypeError(str(texture) + ' does not have a valid node type object')
        self.__texture = texture
    @property # getter - - - - - - - - - -
    def textureTransform(self):
        """[X3DTextureTransformNode] Single contained TextureTransform node that defines 2D transformation applied to texture coordinates."""
        return self.__textureTransform
    @textureTransform.setter
    def textureTransform(self, textureTransform=None):
        if  textureTransform is None:
            textureTransform = SFNode.DEFAULT_VALUE
        assertValidSFNode(textureTransform)
        if not isinstance(textureTransform, object):
            # print(flush=True)
            raise X3DTypeError(str(textureTransform) + ' does not have a valid node type object')
        self.__textureTransform = textureTransform
    @property # getter - - - - - - - - - -
    def shaders(self):
        """[X3DShaderNode] Zero or more contained programmable shader nodes (ComposedShader, PackagedShader, ProgramShader) that specify, in order of preference, author-programmed rendering characteristics."""
        return self.__shaders
    @shaders.setter
    def shaders(self, shaders=None):
        if  shaders is None:
            shaders = MFNode.DEFAULT_VALUE
        assertValidMFNode(shaders)
        self.__shaders = shaders
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.shaders) or bool(self.fillProperties) or bool(self.IS) or bool(self.lineProperties) or bool(self.material) or bool(self.metadata) or bool(self.pointProperties) or bool(self.texture) or bool(self.textureTransform)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Appearance.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Appearance'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.fillProperties: # output this SFNode
                result += self.fillProperties.XML(indentLevel=indentLevel+1)
            if self.lineProperties: # output this SFNode
                result += self.lineProperties.XML(indentLevel=indentLevel+1)
            if self.material: # output this SFNode
                result += self.material.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.pointProperties: # output this SFNode
                result += self.pointProperties.XML(indentLevel=indentLevel+1)
            if self.texture: # output this SFNode
                result += self.texture.XML(indentLevel=indentLevel+1)
            if self.textureTransform: # output this SFNode
                result += self.textureTransform.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.shaders: # walk each child node, if any
                for each in self.shaders:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Appearance>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Arc2D(_X3DGeometryNode):
    """
    Arc2D is a line-based geometry node that defines a linear circular arc with center (0,0) in X-Y plane, with angles measured starting at positive x-axis and sweeping towards positive y-axis.
    """
    NAME = 'Arc2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Arc2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('endAngle', 1.570796, FieldType.SFFloat, AccessType.initializeOnly, 'Arc2D'),
        ('radius', 1, FieldType.SFFloat, AccessType.initializeOnly, 'Arc2D'),
        ('startAngle', 0, FieldType.SFFloat, AccessType.initializeOnly, 'Arc2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 endAngle=1.570796,
                 radius=1,
                 startAngle=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Arc2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.endAngle = endAngle
        self.radius = radius
        self.startAngle = startAngle
    @property # getter - - - - - - - - - -
    def endAngle(self):
        """[0,2pi] Arc extends from startAngle counterclockwise to endAngle, in radians."""
        return self.__endAngle
    @endAngle.setter
    def endAngle(self, endAngle=None):
        if  endAngle is None:
            endAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(endAngle)
        assertGreaterThan('endAngle', endAngle, -6.2832)
        assertLessThan('endAngle', endAngle, 6.2832)
        self.__endAngle = endAngle
    @property # getter - - - - - - - - - -
    def radius(self):
        """(0,+infinity) circle radius, of which the arc is a portion."""
        return self.__radius
    @radius.setter
    def radius(self, radius=None):
        if  radius is None:
            radius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(radius)
        assertPositive('radius', radius)
        self.__radius = radius
    @property # getter - - - - - - - - - -
    def startAngle(self):
        """[0,2pi] Arc extends from startAngle counterclockwise to endAngle, in radians."""
        return self.__startAngle
    @startAngle.setter
    def startAngle(self, startAngle=None):
        if  startAngle is None:
            startAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(startAngle)
        assertGreaterThan('startAngle', startAngle, -6.2832)
        assertLessThan('startAngle', startAngle, 6.2832)
        self.__startAngle = startAngle
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Arc2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Arc2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.endAngle != 1.570796:
            result += " endAngle='" + SFFloat(self.endAngle).XML() + "'"
        if self.radius != 1:
            result += " radius='" + SFFloat(self.radius).XML() + "'"
        if self.startAngle != 0:
            result += " startAngle='" + SFFloat(self.startAngle).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Arc2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ArcClose2D(_X3DGeometryNode):
    """
    ArcClose2D is a polygonal geometry node that defines a linear circular arc, closed by PIE or CHORD line segments, with center (0,0) in X-Y plane, with angles measured starting at positive x-axis and sweeping towards positive y-axis.
    """
    NAME = 'ArcClose2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ArcClose2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('closureType', 'PIE', FieldType.SFString, AccessType.initializeOnly, 'ArcClose2D'),
        ('endAngle', 1.570796, FieldType.SFFloat, AccessType.initializeOnly, 'ArcClose2D'),
        ('radius', 1, FieldType.SFFloat, AccessType.initializeOnly, 'ArcClose2D'),
        ('solid', False, FieldType.SFBool, AccessType.initializeOnly, 'ArcClose2D'),
        ('startAngle', 0, FieldType.SFFloat, AccessType.initializeOnly, 'ArcClose2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 closureType='PIE',
                 endAngle=1.570796,
                 radius=1,
                 solid=False,
                 startAngle=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ArcClose2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.closureType = closureType
        self.endAngle = endAngle
        self.radius = radius
        self.solid = solid
        self.startAngle = startAngle
    @property # getter - - - - - - - - - -
    def closureType(self):
        """Defines whether pair of line segments connect to center (PIE), or single line-segment chord connects arc endpoints (CHORD)."""
        return self.__closureType
    @closureType.setter
    def closureType(self, closureType=None):
        if  closureType is None:
            closureType = SFString.DEFAULT_VALUE
        assertValidSFString(closureType)
        self.__closureType = closureType
    @property # getter - - - - - - - - - -
    def endAngle(self):
        """[0,2pi] Arc extends from startAngle counterclockwise to endAngle, in radians."""
        return self.__endAngle
    @endAngle.setter
    def endAngle(self, endAngle=None):
        if  endAngle is None:
            endAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(endAngle)
        assertGreaterThan('endAngle', endAngle, -6.2832)
        assertLessThan('endAngle', endAngle, 6.2832)
        self.__endAngle = endAngle
    @property # getter - - - - - - - - - -
    def radius(self):
        """(0,+infinity) circle radius, of which the arc is a portion."""
        return self.__radius
    @radius.setter
    def radius(self, radius=None):
        if  radius is None:
            radius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(radius)
        assertPositive('radius', radius)
        self.__radius = radius
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def startAngle(self):
        """[0,2pi] Arc extends from startAngle counterclockwise to endAngle, in radians."""
        return self.__startAngle
    @startAngle.setter
    def startAngle(self, startAngle=None):
        if  startAngle is None:
            startAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(startAngle)
        assertGreaterThan('startAngle', startAngle, -6.2832)
        assertLessThan('startAngle', startAngle, 6.2832)
        self.__startAngle = startAngle
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ArcClose2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ArcClose2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.closureType != 'PIE':
            result += " closureType='" + self.closureType + "'"
        if self.endAngle != 1.570796:
            result += " endAngle='" + SFFloat(self.endAngle).XML() + "'"
        if self.radius != 1:
            result += " radius='" + SFFloat(self.radius).XML() + "'"
        if self.solid != False:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.startAngle != 0:
            result += " startAngle='" + SFFloat(self.startAngle).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ArcClose2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class AudioClip(_X3DSoundSourceNode, _X3DUrlObject):
    """
    AudioClip provides audio data used by parent Sound nodes.
    """
    NAME = 'AudioClip'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#AudioClip'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DSoundSourceNode'),
        ('loop', False, FieldType.SFBool, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('pauseTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('pitch', 1.0, FieldType.SFFloat, AccessType.inputOutput, 'X3DSoundSourceNode'),
        ('resumeTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('startTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('stopTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 description='',
                 loop=False,
                 pauseTime=0,
                 pitch=1.0,
                 resumeTime=0,
                 startTime=0,
                 stopTime=0,
                 url=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode AudioClip __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.description = description
        self.loop = loop
        self.pauseTime = pauseTime
        self.pitch = pitch
        self.resumeTime = resumeTime
        self.startTime = startTime
        self.stopTime = stopTime
        self.url = url
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def loop(self):
        """Repeat indefinitely when loop=true, repeat only once when loop=false."""
        return self.__loop
    @loop.setter
    def loop(self, loop=None):
        if  loop is None:
            loop = SFBool.DEFAULT_VALUE
        assertValidSFBool(loop)
        self.__loop = loop
    @property # getter - - - - - - - - - -
    def pauseTime(self):
        """When time now >= pauseTime, isPaused becomes true and AudioClip becomes paused."""
        return self.__pauseTime
    @pauseTime.setter
    def pauseTime(self, pauseTime=None):
        if  pauseTime is None:
            pauseTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(pauseTime)
        self.__pauseTime = pauseTime
    @property # getter - - - - - - - - - -
    def pitch(self):
        """(0,+infinity) Multiplier for the rate at which sampled sound is played."""
        return self.__pitch
    @pitch.setter
    def pitch(self, pitch=None):
        if  pitch is None:
            pitch = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(pitch)
        assertPositive('pitch', pitch)
        self.__pitch = pitch
    @property # getter - - - - - - - - - -
    def resumeTime(self):
        """When resumeTime becomes <= time now, isPaused becomes false and AudioClip becomes active."""
        return self.__resumeTime
    @resumeTime.setter
    def resumeTime(self, resumeTime=None):
        if  resumeTime is None:
            resumeTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(resumeTime)
        self.__resumeTime = resumeTime
    @property # getter - - - - - - - - - -
    def startTime(self):
        """Absolute time: number of seconds since January 1, 1970, 00:00:00 GMT."""
        return self.__startTime
    @startTime.setter
    def startTime(self, startTime=None):
        if  startTime is None:
            startTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(startTime)
        self.__startTime = startTime
    @property # getter - - - - - - - - - -
    def stopTime(self):
        """Absolute time: number of seconds since January 1, 1970, 00:00:00 GMT."""
        return self.__stopTime
    @stopTime.setter
    def stopTime(self, stopTime=None):
        if  stopTime is None:
            stopTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(stopTime)
        self.__stopTime = stopTime
    @property # getter - - - - - - - - - -
    def url(self):
        """Location and filename of sound file or stream."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function AudioClip.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<AudioClip'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.loop != False:
            result += " loop='" + SFBool(self.loop).XML() + "'"
        if self.pauseTime != 0:
            result += " pauseTime='" + SFTime(self.pauseTime).XML() + "'"
        if self.pitch != 1.0:
            result += " pitch='" + SFFloat(self.pitch).XML() + "'"
        if self.resumeTime != 0:
            result += " resumeTime='" + SFTime(self.resumeTime).XML() + "'"
        if self.startTime != 0:
            result += " startTime='" + SFTime(self.startTime).XML() + "'"
        if self.stopTime != 0:
            result += " stopTime='" + SFTime(self.stopTime).XML() + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</AudioClip>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Background(_X3DBackgroundNode):
    """
    Background simulates ground and sky, using vertical arrays of wraparound color values.
    """
    NAME = 'Background'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Background'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('backUrl', list(), FieldType.MFString, AccessType.inputOutput, 'Background'),
        ('bottomUrl', list(), FieldType.MFString, AccessType.inputOutput, 'Background'),
        ('frontUrl', list(), FieldType.MFString, AccessType.inputOutput, 'Background'),
        ('groundAngle', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('groundColor', list(), FieldType.MFColor, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('leftUrl', list(), FieldType.MFString, AccessType.inputOutput, 'Background'),
        ('rightUrl', list(), FieldType.MFString, AccessType.inputOutput, 'Background'),
        ('skyAngle', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('skyColor', [(0, 0, 0)], FieldType.MFColor, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('topUrl', list(), FieldType.MFString, AccessType.inputOutput, 'Background'),
        ('transparency', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 backUrl=list(),
                 bottomUrl=list(),
                 frontUrl=list(),
                 groundAngle=list(),
                 groundColor=list(),
                 leftUrl=list(),
                 rightUrl=list(),
                 skyAngle=list(),
                 skyColor=[(0, 0, 0)],
                 topUrl=list(),
                 transparency=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Background __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.backUrl = backUrl
        self.bottomUrl = bottomUrl
        self.frontUrl = frontUrl
        self.groundAngle = groundAngle
        self.groundColor = groundColor
        self.leftUrl = leftUrl
        self.rightUrl = rightUrl
        self.skyAngle = skyAngle
        self.skyColor = skyColor
        self.topUrl = topUrl
        self.transparency = transparency
    @property # getter - - - - - - - - - -
    def backUrl(self):
        """Image background panorama between ground/sky backdrop and scene's geometry."""
        return self.__backUrl
    @backUrl.setter
    def backUrl(self, backUrl=None):
        if  backUrl is None:
            backUrl = MFString.DEFAULT_VALUE
        assertValidMFString(backUrl)
        self.__backUrl = backUrl
    @property # getter - - - - - - - - - -
    def bottomUrl(self):
        """Image background panorama between ground/sky backdrop and scene's geometry."""
        return self.__bottomUrl
    @bottomUrl.setter
    def bottomUrl(self, bottomUrl=None):
        if  bottomUrl is None:
            bottomUrl = MFString.DEFAULT_VALUE
        assertValidMFString(bottomUrl)
        self.__bottomUrl = bottomUrl
    @property # getter - - - - - - - - - -
    def frontUrl(self):
        """Image background panorama between ground/sky backdrop and scene's geometry."""
        return self.__frontUrl
    @frontUrl.setter
    def frontUrl(self, frontUrl=None):
        if  frontUrl is None:
            frontUrl = MFString.DEFAULT_VALUE
        assertValidMFString(frontUrl)
        self.__frontUrl = frontUrl
    @property # getter - - - - - - - - - -
    def groundAngle(self):
        """[0,pi/2] The angle array values increase from 0."""
        return self.__groundAngle
    @groundAngle.setter
    def groundAngle(self, groundAngle=None):
        if  groundAngle is None:
            groundAngle = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(groundAngle)
        assertGreaterThanEquals('groundAngle', groundAngle, 0)
        assertLessThanEquals('groundAngle', groundAngle, 1.5708)
        self.__groundAngle = groundAngle
    @property # getter - - - - - - - - - -
    def groundColor(self):
        """Color of the ground at the various angles on the ground partial sphere."""
        return self.__groundColor
    @groundColor.setter
    def groundColor(self, groundColor=None):
        if  groundColor is None:
            groundColor = MFColor.DEFAULT_VALUE
        assertValidMFColor(groundColor)
        assertZeroToOne('groundColor', groundColor)
        self.__groundColor = groundColor
    @property # getter - - - - - - - - - -
    def leftUrl(self):
        """Image background panorama between ground/sky backdrop and scene's geometry."""
        return self.__leftUrl
    @leftUrl.setter
    def leftUrl(self, leftUrl=None):
        if  leftUrl is None:
            leftUrl = MFString.DEFAULT_VALUE
        assertValidMFString(leftUrl)
        self.__leftUrl = leftUrl
    @property # getter - - - - - - - - - -
    def rightUrl(self):
        """Image background panorama between ground/sky backdrop and scene's geometry."""
        return self.__rightUrl
    @rightUrl.setter
    def rightUrl(self, rightUrl=None):
        if  rightUrl is None:
            rightUrl = MFString.DEFAULT_VALUE
        assertValidMFString(rightUrl)
        self.__rightUrl = rightUrl
    @property # getter - - - - - - - - - -
    def skyAngle(self):
        """[0,pi] The angle array values increase from 0."""
        return self.__skyAngle
    @skyAngle.setter
    def skyAngle(self, skyAngle=None):
        if  skyAngle is None:
            skyAngle = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(skyAngle)
        assertGreaterThanEquals('skyAngle', skyAngle, 0)
        assertLessThanEquals('skyAngle', skyAngle, 3.1416)
        self.__skyAngle = skyAngle
    @property # getter - - - - - - - - - -
    def skyColor(self):
        """Color of the sky at various angles on the sky sphere."""
        return self.__skyColor
    @skyColor.setter
    def skyColor(self, skyColor=None):
        if  skyColor is None:
            skyColor = MFColor.DEFAULT_VALUE
        assertValidMFColor(skyColor)
        assertZeroToOne('skyColor', skyColor)
        self.__skyColor = skyColor
    @property # getter - - - - - - - - - -
    def topUrl(self):
        """Image background panorama between ground/sky backdrop and scene's geometry."""
        return self.__topUrl
    @topUrl.setter
    def topUrl(self, topUrl=None):
        if  topUrl is None:
            topUrl = MFString.DEFAULT_VALUE
        assertValidMFString(topUrl)
        self.__topUrl = topUrl
    @property # getter - - - - - - - - - -
    def transparency(self):
        """[0,1] how "clear" the background is, allows underlying page to show through: 1."""
        return self.__transparency
    @transparency.setter
    def transparency(self, transparency=None):
        if  transparency is None:
            transparency = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(transparency)
        assertZeroToOne('transparency', transparency)
        self.__transparency = transparency
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Background.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Background'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.backUrl != list():
            result += " backUrl='" + MFString(self.backUrl).XML() + "'"
        if self.bottomUrl != list():
            result += " bottomUrl='" + MFString(self.bottomUrl).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.frontUrl != list():
            result += " frontUrl='" + MFString(self.frontUrl).XML() + "'"
        if self.groundAngle != list():
            result += " groundAngle='" + MFFloat(self.groundAngle).XML() + "'"
        if self.groundColor != list():
            result += " groundColor='" + MFColor(self.groundColor).XML() + "'"
        if self.leftUrl != list():
            result += " leftUrl='" + MFString(self.leftUrl).XML() + "'"
        if self.rightUrl != list():
            result += " rightUrl='" + MFString(self.rightUrl).XML() + "'"
        if self.skyAngle != list():
            result += " skyAngle='" + MFFloat(self.skyAngle).XML() + "'"
        if self.skyColor != [(0, 0, 0)]:
            result += " skyColor='" + MFColor(self.skyColor).XML() + "'"
        if self.topUrl != list():
            result += " topUrl='" + MFString(self.topUrl).XML() + "'"
        if self.transparency != 0:
            result += " transparency='" + SFFloat(self.transparency).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Background>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class BallJoint(_X3DRigidJointNode):
    """
    BallJoint represents an unconstrained joint between two bodies that pivot about a common anchor point.
    """
    NAME = 'BallJoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#BallJoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('anchorPoint', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'BallJoint'),
        ('forceOutput', ["NONE"], FieldType.MFString, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('body1', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('body2', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 anchorPoint=(0, 0, 0),
                 forceOutput=["NONE"],
                 body1=None,
                 body2=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode BallJoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.anchorPoint = anchorPoint
        self.forceOutput = forceOutput
        self.body1 = body1
        self.body2 = body2
    @property # getter - - - - - - - - - -
    def anchorPoint(self):
        """anchorPoint is joint center, specified in world coordinates."""
        return self.__anchorPoint
    @anchorPoint.setter
    def anchorPoint(self, anchorPoint=None):
        if  anchorPoint is None:
            anchorPoint = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(anchorPoint)
        self.__anchorPoint = anchorPoint
    @property # getter - - - - - - - - - -
    def forceOutput(self):
        """forceOutput controls which output fields are generated for the next frame."""
        return self.__forceOutput
    @forceOutput.setter
    def forceOutput(self, forceOutput=None):
        if  forceOutput is None:
            forceOutput = MFString.DEFAULT_VALUE
        assertValidMFString(forceOutput)
        self.__forceOutput = forceOutput
    @property # getter - - - - - - - - - -
    def body1(self):
        return self.__body1
    @body1.setter
    def body1(self, body1=None):
        if  body1 is None:
            body1 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body1)
        if not isinstance(body1, object):
            # print(flush=True)
            raise X3DTypeError(str(body1) + ' does not have a valid node type object')
        self.__body1 = body1
    @property # getter - - - - - - - - - -
    def body2(self):
        return self.__body2
    @body2.setter
    def body2(self, body2=None):
        if  body2 is None:
            body2 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body2)
        if not isinstance(body2, object):
            # print(flush=True)
            raise X3DTypeError(str(body2) + ' does not have a valid node type object')
        self.__body2 = body2
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.body1) or bool(self.body2) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function BallJoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<BallJoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.anchorPoint != (0, 0, 0):
            result += " anchorPoint='" + SFVec3f(self.anchorPoint).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.forceOutput != ["NONE"]:
            result += " forceOutput='" + MFString(self.forceOutput).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.body1: # output this SFNode
                result += self.body1.XML(indentLevel=indentLevel+1)
            if self.body2: # output this SFNode
                result += self.body2.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</BallJoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Billboard(_X3DGroupingNode):
    """
    Billboard is a Grouping node that can contain most nodes.
    """
    NAME = 'Billboard'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Billboard'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('axisOfRotation', (0, 1, 0), FieldType.SFVec3f, AccessType.inputOutput, 'Billboard'),
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 axisOfRotation=(0, 1, 0),
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Billboard __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.axisOfRotation = axisOfRotation
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def axisOfRotation(self):
        """axisOfRotation direction is relative to local coordinate system."""
        return self.__axisOfRotation
    @axisOfRotation.setter
    def axisOfRotation(self, axisOfRotation=None):
        if  axisOfRotation is None:
            axisOfRotation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(axisOfRotation)
        self.__axisOfRotation = axisOfRotation
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Billboard.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Billboard'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.axisOfRotation != (0, 1, 0):
            result += " axisOfRotation='" + SFVec3f(self.axisOfRotation).XML() + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Billboard>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class BlendedVolumeStyle(_X3DComposableVolumeRenderStyleNode):
    """
    BlendedVolumeStyle combines rendering of two voxel data sets into one by blending voxel values.
    """
    NAME = 'BlendedVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#BlendedVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('weightConstant1', 0.5, FieldType.SFFloat, AccessType.inputOutput, 'BlendedVolumeStyle'),
        ('weightConstant2', 0.5, FieldType.SFFloat, AccessType.inputOutput, 'BlendedVolumeStyle'),
        ('weightFunction1', 'CONSTANT', FieldType.SFString, AccessType.inputOutput, 'BlendedVolumeStyle'),
        ('weightFunction2', 'CONSTANT', FieldType.SFString, AccessType.inputOutput, 'BlendedVolumeStyle'),
        ('renderStyle', None, FieldType.SFNode, AccessType.inputOutput, 'BlendedVolumeStyle'),
        ('voxels', None, FieldType.SFNode, AccessType.inputOutput, 'BlendedVolumeStyle'),
        ('weightTransferFunction1', None, FieldType.SFNode, AccessType.inputOutput, 'BlendedVolumeStyle'),
        ('weightTransferFunction2', None, FieldType.SFNode, AccessType.inputOutput, 'BlendedVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 weightConstant1=0.5,
                 weightConstant2=0.5,
                 weightFunction1='CONSTANT',
                 weightFunction2='CONSTANT',
                 renderStyle=None,
                 voxels=None,
                 weightTransferFunction1=None,
                 weightTransferFunction2=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode BlendedVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.weightConstant1 = weightConstant1
        self.weightConstant2 = weightConstant2
        self.weightFunction1 = weightFunction1
        self.weightFunction2 = weightFunction2
        self.renderStyle = renderStyle
        self.voxels = voxels
        self.weightTransferFunction1 = weightTransferFunction1
        self.weightTransferFunction2 = weightTransferFunction2
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def weightConstant1(self):
        """[0,1] weightConstant1 is used when weightFunction1=CONSTANT."""
        return self.__weightConstant1
    @weightConstant1.setter
    def weightConstant1(self, weightConstant1=None):
        if  weightConstant1 is None:
            weightConstant1 = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(weightConstant1)
        assertZeroToOne('weightConstant1', weightConstant1)
        self.__weightConstant1 = weightConstant1
    @property # getter - - - - - - - - - -
    def weightConstant2(self):
        """[0,1] weightConstant2 is used when weightFunction2=CONSTANT."""
        return self.__weightConstant2
    @weightConstant2.setter
    def weightConstant2(self, weightConstant2=None):
        if  weightConstant2 is None:
            weightConstant2 = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(weightConstant2)
        assertZeroToOne('weightConstant2', weightConstant2)
        self.__weightConstant2 = weightConstant2
    @property # getter - - - - - - - - - -
    def weightFunction1(self):
        """specifies 2D textures used to determine weight values when weight function is set to TABLE."""
        return self.__weightFunction1
    @weightFunction1.setter
    def weightFunction1(self, weightFunction1=None):
        if  weightFunction1 is None:
            weightFunction1 = SFString.DEFAULT_VALUE
        assertValidSFString(weightFunction1)
        self.__weightFunction1 = weightFunction1
    @property # getter - - - - - - - - - -
    def weightFunction2(self):
        """specifies 2D textures used to determine weight values when weight function is set to TABLE."""
        return self.__weightFunction2
    @weightFunction2.setter
    def weightFunction2(self, weightFunction2=None):
        if  weightFunction2 is None:
            weightFunction2 = SFString.DEFAULT_VALUE
        assertValidSFString(weightFunction2)
        self.__weightFunction2 = weightFunction2
    @property # getter - - - - - - - - - -
    def renderStyle(self):
        """[X3DComposableVolumeRenderStyleNode] Single contained X3DComposableVolumeRenderStyleNode node that defines specific rendering technique for data in the voxels field, and the result is blended with parent VolumeData or SegmentedVoliumeData node."""
        return self.__renderStyle
    @renderStyle.setter
    def renderStyle(self, renderStyle=None):
        if  renderStyle is None:
            renderStyle = SFNode.DEFAULT_VALUE
        assertValidSFNode(renderStyle)
        if not isinstance(renderStyle, object):
            # print(flush=True)
            raise X3DTypeError(str(renderStyle) + ' does not have a valid node type object')
        self.__renderStyle = renderStyle
    @property # getter - - - - - - - - - -
    def voxels(self):
        """[X3DTexture3DNode] Single contained X3DTexture3DNode (ComposedTexture3D, ImageTexture3D, PixelTexture3D) that provides second set of raw voxel information utilized by corresponding rendering styles."""
        return self.__voxels
    @voxels.setter
    def voxels(self, voxels=None):
        if  voxels is None:
            voxels = SFNode.DEFAULT_VALUE
        assertValidSFNode(voxels)
        if not isinstance(voxels, object):
            # print(flush=True)
            raise X3DTypeError(str(voxels) + ' does not have a valid node type object')
        self.__voxels = voxels
    @property # getter - - - - - - - - - -
    def weightTransferFunction1(self):
        return self.__weightTransferFunction1
    @weightTransferFunction1.setter
    def weightTransferFunction1(self, weightTransferFunction1=None):
        if  weightTransferFunction1 is None:
            weightTransferFunction1 = SFNode.DEFAULT_VALUE
        assertValidSFNode(weightTransferFunction1)
        if not isinstance(weightTransferFunction1, object):
            # print(flush=True)
            raise X3DTypeError(str(weightTransferFunction1) + ' does not have a valid node type object')
        self.__weightTransferFunction1 = weightTransferFunction1
    @property # getter - - - - - - - - - -
    def weightTransferFunction2(self):
        return self.__weightTransferFunction2
    @weightTransferFunction2.setter
    def weightTransferFunction2(self, weightTransferFunction2=None):
        if  weightTransferFunction2 is None:
            weightTransferFunction2 = SFNode.DEFAULT_VALUE
        assertValidSFNode(weightTransferFunction2)
        if not isinstance(weightTransferFunction2, object):
            # print(flush=True)
            raise X3DTypeError(str(weightTransferFunction2) + ' does not have a valid node type object')
        self.__weightTransferFunction2 = weightTransferFunction2
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.renderStyle) or bool(self.voxels) or bool(self.weightTransferFunction1) or bool(self.weightTransferFunction2)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function BlendedVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<BlendedVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.weightConstant1 != 0.5:
            result += " weightConstant1='" + SFFloat(self.weightConstant1).XML() + "'"
        if self.weightConstant2 != 0.5:
            result += " weightConstant2='" + SFFloat(self.weightConstant2).XML() + "'"
        if self.weightFunction1 != 'CONSTANT':
            result += " weightFunction1='" + self.weightFunction1 + "'"
        if self.weightFunction2 != 'CONSTANT':
            result += " weightFunction2='" + self.weightFunction2 + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.renderStyle: # output this SFNode
                result += self.renderStyle.XML(indentLevel=indentLevel+1)
            if self.voxels: # output this SFNode
                result += self.voxels.XML(indentLevel=indentLevel+1)
            if self.weightTransferFunction1: # output this SFNode
                result += self.weightTransferFunction1.XML(indentLevel=indentLevel+1)
            if self.weightTransferFunction2: # output this SFNode
                result += self.weightTransferFunction2.XML(indentLevel=indentLevel+1)
            result += indent + '</BlendedVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class BooleanFilter(_X3DChildNode):
    """
    BooleanFilter selectively passes true, false or negated events.
    """
    NAME = 'BooleanFilter'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#BooleanFilter'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode BooleanFilter __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function BooleanFilter.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<BooleanFilter'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</BooleanFilter>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class BooleanSequencer(_X3DSequencerNode):
    """
    BooleanSequencer generates periodic discrete Boolean values.
    """
    NAME = 'BooleanSequencer'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#BooleanSequencer'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DSequencerNode'),
        ('keyValue', list(), FieldType.MFBool, AccessType.inputOutput, 'BooleanSequencer'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode BooleanSequencer __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear sequencing, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFBool.DEFAULT_VALUE
        assertValidMFBool(keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function BooleanSequencer.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<BooleanSequencer'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFBool(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</BooleanSequencer>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class BooleanToggle(_X3DChildNode):
    """
    BooleanToggle maintains state and negates output when a true input is provided.
    """
    NAME = 'BooleanToggle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#BooleanToggle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('toggle', False, FieldType.SFBool, AccessType.inputOutput, 'BooleanToggle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 toggle=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode BooleanToggle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.toggle = toggle
    @property # getter - - - - - - - - - -
    def toggle(self):
        """Persistent state value that gets toggled or reset."""
        return self.__toggle
    @toggle.setter
    def toggle(self, toggle=None):
        if  toggle is None:
            toggle = SFBool.DEFAULT_VALUE
        assertValidSFBool(toggle)
        self.__toggle = toggle
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function BooleanToggle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<BooleanToggle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.toggle != False:
            result += " toggle='" + SFBool(self.toggle).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</BooleanToggle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class BooleanTrigger(_X3DTriggerNode):
    """
    BooleanTrigger converts time events to boolean true events.
    """
    NAME = 'BooleanTrigger'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#BooleanTrigger'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode BooleanTrigger __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function BooleanTrigger.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<BooleanTrigger'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</BooleanTrigger>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class BoundaryEnhancementVolumeStyle(_X3DComposableVolumeRenderStyleNode):
    """
    BoundaryEnhancementVolumeStyle provides boundary enhancement for the volume rendering style.
    """
    NAME = 'BoundaryEnhancementVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#BoundaryEnhancementVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('boundaryOpacity', 0.9, FieldType.SFFloat, AccessType.inputOutput, 'BoundaryEnhancementVolumeStyle'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('opacityFactor', 2, FieldType.SFFloat, AccessType.inputOutput, 'BoundaryEnhancementVolumeStyle'),
        ('retainedOpacity', 0.2, FieldType.SFFloat, AccessType.inputOutput, 'BoundaryEnhancementVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 boundaryOpacity=0.9,
                 enabled=True,
                 opacityFactor=2,
                 retainedOpacity=0.2,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode BoundaryEnhancementVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.boundaryOpacity = boundaryOpacity
        self.enabled = enabled
        self.opacityFactor = opacityFactor
        self.retainedOpacity = retainedOpacity
    @property # getter - - - - - - - - - -
    def boundaryOpacity(self):
        """[0,+infinity) boundaryOpacity k_gs is the factored amount of the gradient enhancement to use."""
        return self.__boundaryOpacity
    @boundaryOpacity.setter
    def boundaryOpacity(self, boundaryOpacity=None):
        if  boundaryOpacity is None:
            boundaryOpacity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(boundaryOpacity)
        assertZeroToOne('boundaryOpacity', boundaryOpacity)
        self.__boundaryOpacity = boundaryOpacity
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def opacityFactor(self):
        """[0,+infinity) opacityFactor k_ge is the power function to control the slope of the opacity curve to highlight the set of data."""
        return self.__opacityFactor
    @opacityFactor.setter
    def opacityFactor(self, opacityFactor=None):
        if  opacityFactor is None:
            opacityFactor = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(opacityFactor)
        assertNonNegative('opacityFactor', opacityFactor)
        self.__opacityFactor = opacityFactor
    @property # getter - - - - - - - - - -
    def retainedOpacity(self):
        """[0,1] retainedOpacity k_gc is the amount of initial opacity to mix into the output."""
        return self.__retainedOpacity
    @retainedOpacity.setter
    def retainedOpacity(self, retainedOpacity=None):
        if  retainedOpacity is None:
            retainedOpacity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(retainedOpacity)
        assertZeroToOne('retainedOpacity', retainedOpacity)
        self.__retainedOpacity = retainedOpacity
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function BoundaryEnhancementVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<BoundaryEnhancementVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.boundaryOpacity != 0.9:
            result += " boundaryOpacity='" + SFFloat(self.boundaryOpacity).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.opacityFactor != 2:
            result += " opacityFactor='" + SFFloat(self.opacityFactor).XML() + "'"
        if self.retainedOpacity != 0.2:
            result += " retainedOpacity='" + SFFloat(self.retainedOpacity).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</BoundaryEnhancementVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class BoundedPhysicsModel(_X3DParticlePhysicsModelNode):
    """
    BoundedPhysicsModel provides user-defined geometrical boundaries for particle motion.
    """
    NAME = 'BoundedPhysicsModel'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#BoundedPhysicsModel'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DParticlePhysicsModelNode'),
        ('geometry', None, FieldType.SFNode, AccessType.inputOutput, 'BoundedPhysicsModel'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 geometry=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode BoundedPhysicsModel __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.geometry = geometry
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def geometry(self):
        """[X3DGeometryNode] Single contained geometry node provides the geometry used for each particle when the parent ParticleSystem node has geometryType=GEOMETRY."""
        return self.__geometry
    @geometry.setter
    def geometry(self, geometry=None):
        if  geometry is None:
            geometry = SFNode.DEFAULT_VALUE
        assertValidSFNode(geometry)
        if not isinstance(geometry, object):
            # print(flush=True)
            raise X3DTypeError(str(geometry) + ' does not have a valid node type object')
        self.__geometry = geometry
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.geometry) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function BoundedPhysicsModel.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<BoundedPhysicsModel'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.geometry: # output this SFNode
                result += self.geometry.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</BoundedPhysicsModel>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Box(_X3DGeometryNode):
    """
    Box is a geometry node specifying a rectangular cuboid.
    """
    NAME = 'Box'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Box'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('size', (2, 2, 2), FieldType.SFVec3f, AccessType.initializeOnly, 'Box'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'Box'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 size=(2, 2, 2),
                 solid=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Box __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.size = size
        self.solid = solid
    @property # getter - - - - - - - - - -
    def size(self):
        """(0,+infinity) size x y z in meters."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(size)
        self.__size = size
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Box.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Box'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.size != (2, 2, 2):
            result += " size='" + SFVec3f(self.size).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Box>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CADAssembly(_X3DGroupingNode, _X3DProductStructureChildNode):
    """
    CADAssembly holds a set of Computer-Aided Design (CAD) assemblies or parts grouped together.
    """
    NAME = 'CADAssembly'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CADAssembly'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DProductStructureChildNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 name='',
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CADAssembly __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.name = name
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def name(self):
        """Optional name for this particular CAD node."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CADAssembly.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CADAssembly'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</CADAssembly>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CADFace(_X3DProductStructureChildNode, _X3DBoundedObject):
    """
    CADFace holds geometry representing one face in a Computer-Aided Design (CAD) CADPart.
    """
    NAME = 'CADFace'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CADFace'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DProductStructureChildNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('shape', None, FieldType.SFNode, AccessType.inputOutput, 'CADFace'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 name='',
                 visible=True,
                 shape=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CADFace __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.name = name
        self.visible = visible
        self.shape = shape
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def name(self):
        """Optional name for this particular CAD node."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def shape(self):
        """[X3DShapeNode|LOD|Transform] Contained Shape for this CADPart."""
        return self.__shape
    @shape.setter
    def shape(self, shape=None):
        if  shape is None:
            shape = SFNode.DEFAULT_VALUE
        assertValidSFNode(shape)
        if not isinstance(shape, object):
            # print(flush=True)
            raise X3DTypeError(str(shape) + ' does not have a valid node type object')
        self.__shape = shape
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.shape)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CADFace.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CADFace'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.shape: # output this SFNode
                result += self.shape.XML(indentLevel=indentLevel+1)
            result += indent + '</CADFace>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CADLayer(_X3DGroupingNode):
    """
    CADLayer nodes define a hierarchy that shows layer structure for a Computer-Aided Design (CAD) model.
    """
    NAME = 'CADLayer'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CADLayer'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'CADLayer'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 name='',
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CADLayer __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.name = name
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def name(self):
        """Optional name for this particular CAD node."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def visible(self):
        """Array of boolean values that specify whether each individual child CADAssembly is visible."""
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CADLayer.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CADLayer'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</CADLayer>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CADPart(_X3DProductStructureChildNode, _X3DGroupingNode):
    """
    CADPart is an atomic part that defines both coordinate-system location and the faces that constitute a part in a Computer-Aided Design (CAD) model.
    """
    NAME = 'CADPart'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CADPart'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'CADPart'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DProductStructureChildNode'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'CADPart'),
        ('scale', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'CADPart'),
        ('scaleOrientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'CADPart'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'CADPart'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'CADPart'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 center=(0, 0, 0),
                 displayBBox=False,
                 name='',
                 rotation=(0, 0, 1, 0),
                 scale=(1, 1, 1),
                 scaleOrientation=(0, 0, 1, 0),
                 translation=(0, 0, 0),
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CADPart __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.center = center
        self.displayBBox = displayBBox
        self.name = name
        self.rotation = rotation
        self.scale = scale
        self.scaleOrientation = scaleOrientation
        self.translation = translation
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def center(self):
        """Translation offset from origin of local coordinate system, applied prior to rotation or scaling."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def name(self):
        """Optional name for this particular CAD node."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def rotation(self):
        """Orientation (axis, angle in radians) of children relative to local coordinate system."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def scale(self):
        """Non-uniform x-y-z scale of child coordinate system, adjusted by center and scaleOrientation."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def scaleOrientation(self):
        """Preliminary rotation of coordinate system before scaling (to allow scaling around arbitrary orientations)."""
        return self.__scaleOrientation
    @scaleOrientation.setter
    def scaleOrientation(self, scaleOrientation=None):
        if  scaleOrientation is None:
            scaleOrientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(scaleOrientation)
        self.__scaleOrientation = scaleOrientation
    @property # getter - - - - - - - - - -
    def translation(self):
        """Position (x, y, z in meters) of children relative to local coordinate system."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CADPart.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CADPart'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.scale != (1, 1, 1):
            result += " scale='" + SFVec3f(self.scale).XML() + "'"
        if self.scaleOrientation != (0, 0, 1, 0):
            result += " scaleOrientation='" + SFRotation(self.scaleOrientation).XML() + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</CADPart>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CartoonVolumeStyle(_X3DComposableVolumeRenderStyleNode):
    """
    CartoonVolumeStyle generates cartoon-style non-photorealistic rendering of associated volumetric data.
    """
    NAME = 'CartoonVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CartoonVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('colorSteps', 4, FieldType.SFInt32, AccessType.inputOutput, 'CartoonVolumeStyle'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('orthogonalColor', (1, 1, 1, 1), FieldType.SFColorRGBA, AccessType.inputOutput, 'CartoonVolumeStyle'),
        ('parallelColor', (0, 0, 0, 1), FieldType.SFColorRGBA, AccessType.inputOutput, 'CartoonVolumeStyle'),
        ('surfaceNormals', None, FieldType.SFNode, AccessType.inputOutput, 'CartoonVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 colorSteps=4,
                 enabled=True,
                 orthogonalColor=(1, 1, 1, 1),
                 parallelColor=(0, 0, 0, 1),
                 surfaceNormals=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CartoonVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.colorSteps = colorSteps
        self.enabled = enabled
        self.orthogonalColor = orthogonalColor
        self.parallelColor = parallelColor
        self.surfaceNormals = surfaceNormals
    @property # getter - - - - - - - - - -
    def colorSteps(self):
        """[1,64] Number of distinct colors taken from interpolated colors and used to render the object."""
        return self.__colorSteps
    @colorSteps.setter
    def colorSteps(self, colorSteps=None):
        if  colorSteps is None:
            colorSteps = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(colorSteps)
        assertGreaterThanEquals('colorSteps', colorSteps, 1)
        assertLessThanEquals('colorSteps', colorSteps, 64)
        self.__colorSteps = colorSteps
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def orthogonalColor(self):
        """[0,1] orthogonalColor is used for surface normals that are orthogonal (perpendicular) to viewer's current location."""
        return self.__orthogonalColor
    @orthogonalColor.setter
    def orthogonalColor(self, orthogonalColor=None):
        if  orthogonalColor is None:
            orthogonalColor = SFColorRGBA.DEFAULT_VALUE
        assertValidSFColorRGBA(orthogonalColor)
        assertZeroToOne('orthogonalColor', orthogonalColor)
        self.__orthogonalColor = orthogonalColor
    @property # getter - - - - - - - - - -
    def parallelColor(self):
        """[0,1] parallelColor is used for surface normals that are orthogonal to viewer's current location."""
        return self.__parallelColor
    @parallelColor.setter
    def parallelColor(self, parallelColor=None):
        if  parallelColor is None:
            parallelColor = SFColorRGBA.DEFAULT_VALUE
        assertValidSFColorRGBA(parallelColor)
        assertZeroToOne('parallelColor', parallelColor)
        self.__parallelColor = parallelColor
    @property # getter - - - - - - - - - -
    def surfaceNormals(self):
        return self.__surfaceNormals
    @surfaceNormals.setter
    def surfaceNormals(self, surfaceNormals=None):
        if  surfaceNormals is None:
            surfaceNormals = SFNode.DEFAULT_VALUE
        assertValidSFNode(surfaceNormals)
        if not isinstance(surfaceNormals, object):
            # print(flush=True)
            raise X3DTypeError(str(surfaceNormals) + ' does not have a valid node type object')
        self.__surfaceNormals = surfaceNormals
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.surfaceNormals)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CartoonVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CartoonVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorSteps != 4:
            result += " colorSteps='" + SFInt32(self.colorSteps).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.orthogonalColor != (1, 1, 1, 1):
            result += " orthogonalColor='" + SFColorRGBA(self.orthogonalColor).XML() + "'"
        if self.parallelColor != (0, 0, 0, 1):
            result += " parallelColor='" + SFColorRGBA(self.parallelColor).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.surfaceNormals: # output this SFNode
                result += self.surfaceNormals.XML(indentLevel=indentLevel+1)
            result += indent + '</CartoonVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Circle2D(_X3DGeometryNode):
    """
    Circle2D is a geometry node that defines a linear X-Y circle with center (0,0) in X-Y plane.
    """
    NAME = 'Circle2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Circle2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('radius', 1, FieldType.SFFloat, AccessType.initializeOnly, 'Circle2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 radius=1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Circle2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.radius = radius
    @property # getter - - - - - - - - - -
    def radius(self):
        """(0,+infinity) circle radius."""
        return self.__radius
    @radius.setter
    def radius(self, radius=None):
        if  radius is None:
            radius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(radius)
        assertPositive('radius', radius)
        self.__radius = radius
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Circle2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Circle2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.radius != 1:
            result += " radius='" + SFFloat(self.radius).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Circle2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ClipPlane(_X3DChildNode):
    """
    ClipPlane specifies a single plane equation used to clip (i.
    """
    NAME = 'ClipPlane'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ClipPlane'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'ClipPlane'),
        ('plane', (0, 1, 0, 0), FieldType.SFVec4f, AccessType.inputOutput, 'ClipPlane'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 plane=(0, 1, 0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ClipPlane __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.plane = plane
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def plane(self):
        """[0,1] If (a,b,c,d) is the plane, with the first three components being a normalized vector describing the plane's normal direction (and thus the fourth component d being distance from the origin), a point (x,y,z) is visible to the user, with regards to the clipping plane, if a*x+b*y+c*z+d is greater than 0."""
        return self.__plane
    @plane.setter
    def plane(self, plane=None):
        if  plane is None:
            plane = SFVec4f.DEFAULT_VALUE
        assertValidSFVec4f(plane)
        assertGreaterThanEquals('plane', plane, -1)
        assertLessThanEquals('plane', plane, 1)
        self.__plane = plane
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ClipPlane.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ClipPlane'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.plane != (0, 1, 0, 0):
            result += " plane='" + SFVec4f(self.plane).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ClipPlane>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CollidableOffset(_X3DNBodyCollidableNode):
    """
    CollidableOffset repositions geometry relative to center of owning body.
    """
    NAME = 'CollidableOffset'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CollidableOffset'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DNBodyCollidableNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DNBodyCollidableNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('collidable', None, FieldType.SFNode, AccessType.initializeOnly, 'CollidableOffset'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 enabled=True,
                 rotation=(0, 0, 1, 0),
                 translation=(0, 0, 0),
                 visible=True,
                 collidable=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CollidableOffset __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.rotation = rotation
        self.translation = translation
        self.visible = visible
        self.collidable = collidable
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def rotation(self):
        """Orientation (axis, angle in radians) of children relative to local coordinate system."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def translation(self):
        """Position (x, y, z in meters) of children relative to local coordinate system."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def collidable(self):
        return self.__collidable
    @collidable.setter
    def collidable(self, collidable=None):
        if  collidable is None:
            collidable = SFNode.DEFAULT_VALUE
        assertValidSFNode(collidable)
        if not isinstance(collidable, object):
            # print(flush=True)
            raise X3DTypeError(str(collidable) + ' does not have a valid node type object')
        self.__collidable = collidable
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.collidable) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CollidableOffset.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CollidableOffset'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.collidable: # output this SFNode
                result += self.collidable.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</CollidableOffset>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CollidableShape(_X3DNBodyCollidableNode):
    """
    CollidableShape connects the collision detection system, the rigid body model, and the renderable scene graph.
    """
    NAME = 'CollidableShape'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CollidableShape'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DNBodyCollidableNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DNBodyCollidableNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DNBodyCollidableNode'),
        ('shape', None, FieldType.SFNode, AccessType.initializeOnly, 'CollidableShape'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 enabled=True,
                 rotation=(0, 0, 1, 0),
                 translation=(0, 0, 0),
                 visible=True,
                 shape=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CollidableShape __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.rotation = rotation
        self.translation = translation
        self.visible = visible
        self.shape = shape
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def rotation(self):
        """Orientation (axis, angle in radians) of children relative to local coordinate system."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def translation(self):
        """Position (x, y, z in meters) of children relative to local coordinate system."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def shape(self):
        return self.__shape
    @shape.setter
    def shape(self, shape=None):
        if  shape is None:
            shape = SFNode.DEFAULT_VALUE
        assertValidSFNode(shape)
        if not isinstance(shape, object):
            # print(flush=True)
            raise X3DTypeError(str(shape) + ' does not have a valid node type object')
        self.__shape = shape
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.shape)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CollidableShape.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CollidableShape'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.shape: # output this SFNode
                result += self.shape.XML(indentLevel=indentLevel+1)
            result += indent + '</CollidableShape>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Collision(_X3DGroupingNode, _X3DSensorNode):
    """
    Collision detects camera-to-object contact using current view and NavigationInfo avatarSize.
    """
    NAME = 'Collision'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Collision'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('proxy', None, FieldType.SFNode, AccessType.initializeOnly, 'Collision'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 enabled=True,
                 visible=True,
                 proxy=None,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Collision __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.visible = visible
        self.proxy = proxy
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables collision detection for children and all descendants."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def proxy(self):
        """[X3DChildNode] The proxy node is used as a substitute for Collision children during collision detection, simplifying collision-intersection computations."""
        return self.__proxy
    @proxy.setter
    def proxy(self, proxy=None):
        if  proxy is None:
            proxy = SFNode.DEFAULT_VALUE
        assertValidSFNode(proxy)
        if not isinstance(proxy, object):
            # print(flush=True)
            raise X3DTypeError(str(proxy) + ' does not have a valid node type object')
        self.__proxy = proxy
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata) or bool(self.proxy)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Collision.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Collision'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.proxy: # output this SFNode
                result += self.proxy.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Collision>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CollisionCollection(_X3DChildNode, _X3DBoundedObject):
    """
    CollisionCollection holds a collection of objects that can be managed as a single entity for resolution of inter-object collisions.
    """
    NAME = 'CollisionCollection'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CollisionCollection'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('appliedParameters', ["BOUNCE"], FieldType.MFString, AccessType.inputOutput, 'CollisionCollection'),
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'CollisionCollection'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'CollisionCollection'),
        ('frictionCoefficients', (0, 0), FieldType.SFVec2f, AccessType.inputOutput, 'CollisionCollection'),
        ('minBounceSpeed', 0.1, FieldType.SFFloat, AccessType.inputOutput, 'CollisionCollection'),
        ('slipFactors', (0, 0), FieldType.SFVec2f, AccessType.inputOutput, 'CollisionCollection'),
        ('softnessConstantForceMix', 0.0001, FieldType.SFFloat, AccessType.inputOutput, 'CollisionCollection'),
        ('softnessErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'CollisionCollection'),
        ('surfaceSpeed', (0, 0), FieldType.SFVec2f, AccessType.inputOutput, 'CollisionCollection'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('collidables', list(), FieldType.MFNode, AccessType.inputOutput, 'CollisionCollection'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 appliedParameters=["BOUNCE"],
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 bounce=0,
                 displayBBox=False,
                 enabled=True,
                 frictionCoefficients=(0, 0),
                 minBounceSpeed=0.1,
                 slipFactors=(0, 0),
                 softnessConstantForceMix=0.0001,
                 softnessErrorCorrection=0.8,
                 surfaceSpeed=(0, 0),
                 visible=True,
                 collidables=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CollisionCollection __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.appliedParameters = appliedParameters
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.bounce = bounce
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.frictionCoefficients = frictionCoefficients
        self.minBounceSpeed = minBounceSpeed
        self.slipFactors = slipFactors
        self.softnessConstantForceMix = softnessConstantForceMix
        self.softnessErrorCorrection = softnessErrorCorrection
        self.surfaceSpeed = surfaceSpeed
        self.visible = visible
        self.collidables = collidables
    @property # getter - - - - - - - - - -
    def appliedParameters(self):
        """Default global parameters for collision outputs of rigid body physics system."""
        return self.__appliedParameters
    @appliedParameters.setter
    def appliedParameters(self, appliedParameters=None):
        if  appliedParameters is None:
            appliedParameters = MFString.DEFAULT_VALUE
        assertValidMFString(appliedParameters)
        self.__appliedParameters = appliedParameters
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def bounce(self):
        """[0,1] bounce indicates bounciness (0 = no bounce at all, 1 = maximum bounce)."""
        return self.__bounce
    @bounce.setter
    def bounce(self, bounce=None):
        if  bounce is None:
            bounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(bounce)
        assertZeroToOne('bounce', bounce)
        self.__bounce = bounce
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def frictionCoefficients(self):
        """frictionCoefficients used for computing surface drag."""
        return self.__frictionCoefficients
    @frictionCoefficients.setter
    def frictionCoefficients(self, frictionCoefficients=None):
        if  frictionCoefficients is None:
            frictionCoefficients = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(frictionCoefficients)
        assertNonNegative('frictionCoefficients', frictionCoefficients)
        self.__frictionCoefficients = frictionCoefficients
    @property # getter - - - - - - - - - -
    def minBounceSpeed(self):
        """[0,+infinity) minBounceSpeed m/s needed to bounce."""
        return self.__minBounceSpeed
    @minBounceSpeed.setter
    def minBounceSpeed(self, minBounceSpeed=None):
        if  minBounceSpeed is None:
            minBounceSpeed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(minBounceSpeed)
        assertNonNegative('minBounceSpeed', minBounceSpeed)
        self.__minBounceSpeed = minBounceSpeed
    @property # getter - - - - - - - - - -
    def slipFactors(self):
        """slipFactors used for computing surface drag."""
        return self.__slipFactors
    @slipFactors.setter
    def slipFactors(self, slipFactors=None):
        if  slipFactors is None:
            slipFactors = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(slipFactors)
        self.__slipFactors = slipFactors
    @property # getter - - - - - - - - - -
    def softnessConstantForceMix(self):
        """[0,1] softnessConstantForceMix value applies a constant force value to make colliding surfaces appear to be somewhat soft."""
        return self.__softnessConstantForceMix
    @softnessConstantForceMix.setter
    def softnessConstantForceMix(self, softnessConstantForceMix=None):
        if  softnessConstantForceMix is None:
            softnessConstantForceMix = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(softnessConstantForceMix)
        assertZeroToOne('softnessConstantForceMix', softnessConstantForceMix)
        self.__softnessConstantForceMix = softnessConstantForceMix
    @property # getter - - - - - - - - - -
    def softnessErrorCorrection(self):
        """[0,1] softnessErrorCorrection indicates fraction of collision error fixed in a set of evaluations (0 = no error correction, 1 = all errors corrected in single step)."""
        return self.__softnessErrorCorrection
    @softnessErrorCorrection.setter
    def softnessErrorCorrection(self, softnessErrorCorrection=None):
        if  softnessErrorCorrection is None:
            softnessErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(softnessErrorCorrection)
        assertZeroToOne('softnessErrorCorrection', softnessErrorCorrection)
        self.__softnessErrorCorrection = softnessErrorCorrection
    @property # getter - - - - - - - - - -
    def surfaceSpeed(self):
        """surfaceSpeed defines speed vectors for computing surface drag, if contact surfaces move independently of bodies."""
        return self.__surfaceSpeed
    @surfaceSpeed.setter
    def surfaceSpeed(self, surfaceSpeed=None):
        if  surfaceSpeed is None:
            surfaceSpeed = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(surfaceSpeed)
        self.__surfaceSpeed = surfaceSpeed
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def collidables(self):
        """[CollisionSpace|CollidableShape|CollidableOffset] CollisionCollection node holds a collection of objects in the collidables field that can be managed as a single entity for resolution of inter-object collisions with other groups of collidable objects."""
        return self.__collidables
    @collidables.setter
    def collidables(self, collidables=None):
        if  collidables is None:
            collidables = MFNode.DEFAULT_VALUE
        assertValidMFNode(collidables)
        self.__collidables = collidables
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.collidables) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CollisionCollection.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CollisionCollection'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.appliedParameters != ["BOUNCE"]:
            result += " appliedParameters='" + MFString(self.appliedParameters).XML() + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.bounce != 0:
            result += " bounce='" + SFFloat(self.bounce).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.frictionCoefficients != (0, 0):
            result += " frictionCoefficients='" + SFVec2f(self.frictionCoefficients).XML() + "'"
        if self.minBounceSpeed != 0.1:
            result += " minBounceSpeed='" + SFFloat(self.minBounceSpeed).XML() + "'"
        if self.slipFactors != (0, 0):
            result += " slipFactors='" + SFVec2f(self.slipFactors).XML() + "'"
        if self.softnessConstantForceMix != 0.0001:
            result += " softnessConstantForceMix='" + SFFloat(self.softnessConstantForceMix).XML() + "'"
        if self.softnessErrorCorrection != 0.8:
            result += " softnessErrorCorrection='" + SFFloat(self.softnessErrorCorrection).XML() + "'"
        if self.surfaceSpeed != (0, 0):
            result += " surfaceSpeed='" + SFVec2f(self.surfaceSpeed).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.collidables: # walk each child node, if any
                for each in self.collidables:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</CollisionCollection>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CollisionSensor(_X3DSensorNode):
    """
    CollisionSensor generates collision-detection events.
    """
    NAME = 'CollisionSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CollisionSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('collider', None, FieldType.SFNode, AccessType.inputOutput, 'CollisionSensor'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 collider=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CollisionSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.collider = collider
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def collider(self):
        return self.__collider
    @collider.setter
    def collider(self, collider=None):
        if  collider is None:
            collider = SFNode.DEFAULT_VALUE
        assertValidSFNode(collider)
        if not isinstance(collider, object):
            # print(flush=True)
            raise X3DTypeError(str(collider) + ' does not have a valid node type object')
        self.__collider = collider
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.collider) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CollisionSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CollisionSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.collider: # output this SFNode
                result += self.collider.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</CollisionSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CollisionSpace(_X3DNBodyCollisionSpaceNode):
    """
    CollisionSpace holds collection of objects considered together for resolution of inter-object collisions.
    """
    NAME = 'CollisionSpace'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CollisionSpace'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DNBodyCollisionSpaceNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DNBodyCollisionSpaceNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DNBodyCollisionSpaceNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DNBodyCollisionSpaceNode'),
        ('useGeometry', False, FieldType.SFBool, AccessType.inputOutput, 'CollisionSpace'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DNBodyCollisionSpaceNode'),
        ('collidables', list(), FieldType.MFNode, AccessType.inputOutput, 'CollisionSpace'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 enabled=True,
                 useGeometry=False,
                 visible=True,
                 collidables=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CollisionSpace __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.useGeometry = useGeometry
        self.visible = visible
        self.collidables = collidables
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def useGeometry(self):
        """useGeometry indicates whether collision-detection code checks down to level of geometry, or only make approximations using geometry bounds."""
        return self.__useGeometry
    @useGeometry.setter
    def useGeometry(self, useGeometry=None):
        if  useGeometry is None:
            useGeometry = SFBool.DEFAULT_VALUE
        assertValidSFBool(useGeometry)
        self.__useGeometry = useGeometry
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def collidables(self):
        return self.__collidables
    @collidables.setter
    def collidables(self, collidables=None):
        if  collidables is None:
            collidables = MFNode.DEFAULT_VALUE
        assertValidMFNode(collidables)
        self.__collidables = collidables
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.collidables) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CollisionSpace.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CollisionSpace'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.useGeometry != False:
            result += " useGeometry='" + SFBool(self.useGeometry).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.collidables: # walk each child node, if any
                for each in self.collidables:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</CollisionSpace>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Color(_X3DColorNode):
    """
    Color node defines a set of RGB color values that apply either to a sibling Coordinate|CoordinateDouble node, or else to a parent ElevationGrid node.
    """
    NAME = 'Color'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Color'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('color', list(), FieldType.MFColor, AccessType.inputOutput, 'Color'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 color=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Color __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.color = color
    @property # getter - - - - - - - - - -
    def color(self):
        """The color field defines an array of 3-tuple RGB colors."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = MFColor.DEFAULT_VALUE
        assertValidMFColor(color)
        assertZeroToOne('color', color)
        self.__color = color
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Color.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Color'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.color != list():
            result += " color='" + MFColor(self.color).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Color>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ColorChaser(_X3DChaserNode):
    """
    ColorChaser generates a series of SFColor values that progressively change from initial value to destination value.
    """
    NAME = 'ColorChaser'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ColorChaser'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('duration', 1, FieldType.SFTime, AccessType.initializeOnly, 'X3DChaserNode'),
        ('initialDestination', (0.8, 0.8, 0.8), FieldType.SFColor, AccessType.initializeOnly, 'ColorChaser'),
        ('initialValue', (0.8, 0.8, 0.8), FieldType.SFColor, AccessType.initializeOnly, 'ColorChaser'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 duration=1,
                 initialDestination=(0.8, 0.8, 0.8),
                 initialValue=(0.8, 0.8, 0.8),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ColorChaser __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.duration = duration
        self.initialDestination = initialDestination
        self.initialValue = initialValue
    @property # getter - - - - - - - - - -
    def duration(self):
        """[0,+infinity) duration is the time interval for filter response in seconds."""
        return self.__duration
    @duration.setter
    def duration(self, duration=None):
        if  duration is None:
            duration = SFTime.DEFAULT_VALUE
        assertValidSFTime(duration)
        assertNonNegative('duration', duration)
        self.__duration = duration
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFColor.DEFAULT_VALUE
        assertValidSFColor(initialDestination)
        assertZeroToOne('initialDestination', initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFColor.DEFAULT_VALUE
        assertValidSFColor(initialValue)
        assertZeroToOne('initialValue', initialValue)
        self.__initialValue = initialValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ColorChaser.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ColorChaser'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.duration != 1:
            result += " duration='" + SFTime(self.duration).XML() + "'"
        if self.initialDestination != (0.8, 0.8, 0.8):
            result += " initialDestination='" + SFColor(self.initialDestination).XML() + "'"
        if self.initialValue != (0.8, 0.8, 0.8):
            result += " initialValue='" + SFColor(self.initialValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ColorChaser>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ColorDamper(_X3DDamperNode):
    """
    ColorDamper generates a series of RGB color values that progressively change from initial value to destination value.
    """
    NAME = 'ColorDamper'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ColorDamper'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('initialDestination', (0.8, 0.8, 0.8), FieldType.SFColor, AccessType.initializeOnly, 'ColorDamper'),
        ('initialValue', (0.8, 0.8, 0.8), FieldType.SFColor, AccessType.initializeOnly, 'ColorDamper'),
        ('order', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DDamperNode'),
        ('tau', 0.3, FieldType.SFTime, AccessType.inputOutput, 'X3DDamperNode'),
        ('tolerance', -1, FieldType.SFFloat, AccessType.inputOutput, 'X3DDamperNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 initialDestination=(0.8, 0.8, 0.8),
                 initialValue=(0.8, 0.8, 0.8),
                 order=3,
                 tau=0.3,
                 tolerance=-1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ColorDamper __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.initialDestination = initialDestination
        self.initialValue = initialValue
        self.order = order
        self.tau = tau
        self.tolerance = tolerance
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFColor.DEFAULT_VALUE
        assertValidSFColor(initialDestination)
        assertZeroToOne('initialDestination', initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFColor.DEFAULT_VALUE
        assertValidSFColor(initialValue)
        assertZeroToOne('initialValue', initialValue)
        self.__initialValue = initialValue
    @property # getter - - - - - - - - - -
    def order(self):
        """[0,5] order defines the number of internal filters (larger means smoother response, longer delay)."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 0)
        assertLessThanEquals('order', order, 5)
        self.__order = order
    @property # getter - - - - - - - - - -
    def tau(self):
        """[0,+infinity) tau is the exponential-decay time constant for filter response in seconds."""
        return self.__tau
    @tau.setter
    def tau(self, tau=None):
        if  tau is None:
            tau = SFTime.DEFAULT_VALUE
        assertValidSFTime(tau)
        assertNonNegative('tau', tau)
        self.__tau = tau
    @property # getter - - - - - - - - - -
    def tolerance(self):
        """[0,+infinity) or -1."""
        return self.__tolerance
    @tolerance.setter
    def tolerance(self, tolerance=None):
        if  tolerance is None:
            tolerance = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(tolerance)
        self.__tolerance = tolerance
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ColorDamper.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ColorDamper'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.initialDestination != (0.8, 0.8, 0.8):
            result += " initialDestination='" + SFColor(self.initialDestination).XML() + "'"
        if self.initialValue != (0.8, 0.8, 0.8):
            result += " initialValue='" + SFColor(self.initialValue).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.tau != 0.3:
            result += " tau='" + SFTime(self.tau).XML() + "'"
        if self.tolerance != -1:
            result += " tolerance='" + SFFloat(self.tolerance).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ColorDamper>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ColorInterpolator(_X3DInterpolatorNode):
    """
    ColorInterpolator generates a range of color values.
    """
    NAME = 'ColorInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ColorInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFColor, AccessType.inputOutput, 'ColorInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ColorInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFColor.DEFAULT_VALUE
        assertValidMFColor(keyValue)
        assertZeroToOne('keyValue', keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ColorInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ColorInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFColor(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ColorInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ColorRGBA(_X3DColorNode):
    """
    ColorRGBA node defines a set of RGBA color values that apply either to a sibling Coordinate|CoordinateDouble node, or else to a parent ElevationGrid node.
    """
    NAME = 'ColorRGBA'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ColorRGBA'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('color', list(), FieldType.MFColorRGBA, AccessType.inputOutput, 'ColorRGBA'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 color=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ColorRGBA __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.color = color
    @property # getter - - - - - - - - - -
    def color(self):
        """[0,1] The color field defines an array of 4-tuple RGBA colors."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = MFColorRGBA.DEFAULT_VALUE
        assertValidMFColorRGBA(color)
        assertZeroToOne('color', color)
        self.__color = color
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ColorRGBA.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ColorRGBA'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.color != list():
            result += " color='" + MFColorRGBA(self.color).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ColorRGBA>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ComposedCubeMapTexture(_X3DEnvironmentTextureNode):
    """
    ComposedCubeMapTexture is a texture node that defines a cubic environment map source as an explicit set of images drawn from individual 2D texture nodes.
    """
    NAME = 'ComposedCubeMapTexture'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ComposedCubeMapTexture'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('back', None, FieldType.SFNode, AccessType.inputOutput, 'ComposedCubeMapTexture'),
        ('bottom', None, FieldType.SFNode, AccessType.inputOutput, 'ComposedCubeMapTexture'),
        ('front', None, FieldType.SFNode, AccessType.inputOutput, 'ComposedCubeMapTexture'),
        ('left', None, FieldType.SFNode, AccessType.inputOutput, 'ComposedCubeMapTexture'),
        ('right', None, FieldType.SFNode, AccessType.inputOutput, 'ComposedCubeMapTexture'),
        ('top', None, FieldType.SFNode, AccessType.inputOutput, 'ComposedCubeMapTexture'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 back=None,
                 bottom=None,
                 front=None,
                 left=None,
                 right=None,
                 top=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ComposedCubeMapTexture __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.back = back
        self.bottom = bottom
        self.front = front
        self.left = left
        self.right = right
        self.top = top
    @property # getter - - - - - - - - - -
    def back(self):
        return self.__back
    @back.setter
    def back(self, back=None):
        if  back is None:
            back = SFNode.DEFAULT_VALUE
        assertValidSFNode(back)
        if not isinstance(back, object):
            # print(flush=True)
            raise X3DTypeError(str(back) + ' does not have a valid node type object')
        self.__back = back
    @property # getter - - - - - - - - - -
    def bottom(self):
        return self.__bottom
    @bottom.setter
    def bottom(self, bottom=None):
        if  bottom is None:
            bottom = SFNode.DEFAULT_VALUE
        assertValidSFNode(bottom)
        if not isinstance(bottom, object):
            # print(flush=True)
            raise X3DTypeError(str(bottom) + ' does not have a valid node type object')
        self.__bottom = bottom
    @property # getter - - - - - - - - - -
    def front(self):
        return self.__front
    @front.setter
    def front(self, front=None):
        if  front is None:
            front = SFNode.DEFAULT_VALUE
        assertValidSFNode(front)
        if not isinstance(front, object):
            # print(flush=True)
            raise X3DTypeError(str(front) + ' does not have a valid node type object')
        self.__front = front
    @property # getter - - - - - - - - - -
    def left(self):
        return self.__left
    @left.setter
    def left(self, left=None):
        if  left is None:
            left = SFNode.DEFAULT_VALUE
        assertValidSFNode(left)
        if not isinstance(left, object):
            # print(flush=True)
            raise X3DTypeError(str(left) + ' does not have a valid node type object')
        self.__left = left
    @property # getter - - - - - - - - - -
    def right(self):
        return self.__right
    @right.setter
    def right(self, right=None):
        if  right is None:
            right = SFNode.DEFAULT_VALUE
        assertValidSFNode(right)
        if not isinstance(right, object):
            # print(flush=True)
            raise X3DTypeError(str(right) + ' does not have a valid node type object')
        self.__right = right
    @property # getter - - - - - - - - - -
    def top(self):
        return self.__top
    @top.setter
    def top(self, top=None):
        if  top is None:
            top = SFNode.DEFAULT_VALUE
        assertValidSFNode(top)
        if not isinstance(top, object):
            # print(flush=True)
            raise X3DTypeError(str(top) + ' does not have a valid node type object')
        self.__top = top
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.back) or bool(self.bottom) or bool(self.front) or bool(self.IS) or bool(self.left) or bool(self.metadata) or bool(self.right) or bool(self.top)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ComposedCubeMapTexture.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ComposedCubeMapTexture'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.back: # output this SFNode
                result += self.back.XML(indentLevel=indentLevel+1)
            if self.bottom: # output this SFNode
                result += self.bottom.XML(indentLevel=indentLevel+1)
            if self.front: # output this SFNode
                result += self.front.XML(indentLevel=indentLevel+1)
            if self.left: # output this SFNode
                result += self.left.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.right: # output this SFNode
                result += self.right.XML(indentLevel=indentLevel+1)
            if self.top: # output this SFNode
                result += self.top.XML(indentLevel=indentLevel+1)
            result += indent + '</ComposedCubeMapTexture>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ComposedShader(_X3DShaderNode): # , _X3DProgrammableShaderObject # TODO fix additional inheritance method resolution order (MRO)
    """
    ComposedShader can contain field declarations, but no CDATA section of plain-text source code, since programs are composed from child ShaderPart nodes.
    """
    NAME = 'ComposedShader'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ComposedShader'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('language', '', FieldType.SFString, AccessType.initializeOnly, 'X3DShaderNode'),
        ('field', list(), FieldType.MFNode, AccessType.inputOutput, 'ComposedShader'),
        ('parts', list(), FieldType.MFNode, AccessType.inputOutput, 'ComposedShader'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'ComposedShader'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'ComposedShader')]
    def __init__(self,
                 language='',
                 field=list(),
                 parts=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ComposedShader __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.language = language
        self.field = field
        self.parts = parts
    @property # getter - - - - - - - - - -
    def language(self):
        """The language field indicates to the X3D player which shading language is used."""
        return self.__language
    @language.setter
    def language(self, language=None):
        if  language is None:
            language = SFString.DEFAULT_VALUE
        assertValidSFString(language)
        self.__language = language
    @property # getter - - - - - - - - - -
    def field(self):
        """Include a field statement for each field declaration in the ComposedShader node."""
        return self.__field
    @field.setter
    def field(self, field=None):
        if  field is None:
            field = MFNode.DEFAULT_VALUE
        # TODO type-aware checks for field
        if field: # walk each child node, if any
            for each in field:
                assertValidFieldInitializationValue(each.name, each.type, each.value, parent='ComposedShader')
        self.__field = field
    @property # getter - - - - - - - - - -
    def parts(self):
        """[ShaderPart] ComposedShader can contain multiple ShaderPart nodes in the parts field."""
        return self.__parts
    @parts.setter
    def parts(self, parts=None):
        if  parts is None:
            parts = MFNode.DEFAULT_VALUE
        assertValidMFNode(parts)
        self.__parts = parts
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.field) or bool(self.parts) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ComposedShader.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ComposedShader'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.language:
            result += " language='" + self.language + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.field: # walk each child node, if any
                for each in self.field:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.parts: # walk each child node, if any
                for each in self.parts:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ComposedShader>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ComposedTexture3D(_X3DTexture3DNode):
    """
    ComposedTexture3D defines a 3D image-based texture map as a collection of 2D texture sources at various depths.
    """
    NAME = 'ComposedTexture3D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ComposedTexture3D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('repeatR', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('repeatS', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('repeatT', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('textureProperties', None, FieldType.SFNode, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('texture', list(), FieldType.MFNode, AccessType.inputOutput, 'ComposedTexture3D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 repeatR=False,
                 repeatS=False,
                 repeatT=False,
                 textureProperties=None,
                 texture=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ComposedTexture3D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.repeatR = repeatR
        self.repeatS = repeatS
        self.repeatT = repeatT
        self.textureProperties = textureProperties
        self.texture = texture
    @property # getter - - - - - - - - - -
    def repeatR(self):
        """Whether to vertically repeat texture along R axis."""
        return self.__repeatR
    @repeatR.setter
    def repeatR(self, repeatR=None):
        if  repeatR is None:
            repeatR = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatR)
        self.__repeatR = repeatR
    @property # getter - - - - - - - - - -
    def repeatS(self):
        """Whether to horizontally repeat texture along S axis."""
        return self.__repeatS
    @repeatS.setter
    def repeatS(self, repeatS=None):
        if  repeatS is None:
            repeatS = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatS)
        self.__repeatS = repeatS
    @property # getter - - - - - - - - - -
    def repeatT(self):
        """Whether to vertically repeat texture along T axis."""
        return self.__repeatT
    @repeatT.setter
    def repeatT(self, repeatT=None):
        if  repeatT is None:
            repeatT = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatT)
        self.__repeatT = repeatT
    @property # getter - - - - - - - - - -
    def textureProperties(self):
        return self.__textureProperties
    @textureProperties.setter
    def textureProperties(self, textureProperties=None):
        if  textureProperties is None:
            textureProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(textureProperties)
        if not isinstance(textureProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(textureProperties) + ' does not have a valid node type object')
        self.__textureProperties = textureProperties
    @property # getter - - - - - - - - - -
    def texture(self):
        return self.__texture
    @texture.setter
    def texture(self, texture=None):
        if  texture is None:
            texture = MFNode.DEFAULT_VALUE
        assertValidMFNode(texture)
        self.__texture = texture
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.texture) or bool(self.IS) or bool(self.metadata) or bool(self.textureProperties)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ComposedTexture3D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ComposedTexture3D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.repeatR != False:
            result += " repeatR='" + SFBool(self.repeatR).XML() + "'"
        if self.repeatS != False:
            result += " repeatS='" + SFBool(self.repeatS).XML() + "'"
        if self.repeatT != False:
            result += " repeatT='" + SFBool(self.repeatT).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.textureProperties: # output this SFNode
                result += self.textureProperties.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.texture: # walk each child node, if any
                for each in self.texture:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ComposedTexture3D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ComposedVolumeStyle(_X3DComposableVolumeRenderStyleNode):
    """
    ComposedVolumeStyle allows compositing multiple rendering styles into single rendering pass.
    """
    NAME = 'ComposedVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ComposedVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('renderStyle', list(), FieldType.MFNode, AccessType.inputOutput, 'ComposedVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 renderStyle=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ComposedVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.renderStyle = renderStyle
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def renderStyle(self):
        """[X3DComposableVolumeRenderStyleNode] List of contributing rendering style nodes or node references that can be applied to the object."""
        return self.__renderStyle
    @renderStyle.setter
    def renderStyle(self, renderStyle=None):
        if  renderStyle is None:
            renderStyle = MFNode.DEFAULT_VALUE
        assertValidMFNode(renderStyle)
        self.__renderStyle = renderStyle
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.renderStyle) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ComposedVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ComposedVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.renderStyle: # walk each child node, if any
                for each in self.renderStyle:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ComposedVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Cone(_X3DGeometryNode):
    """
    Cone is a geometry node.
    """
    NAME = 'Cone'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Cone'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bottom', True, FieldType.SFBool, AccessType.initializeOnly, 'Cone'),
        ('bottomRadius', 1, FieldType.SFFloat, AccessType.initializeOnly, 'Cone'),
        ('height', 2, FieldType.SFFloat, AccessType.initializeOnly, 'Cone'),
        ('side', True, FieldType.SFBool, AccessType.initializeOnly, 'Cone'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'Cone'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bottom=True,
                 bottomRadius=1,
                 height=2,
                 side=True,
                 solid=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Cone __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bottom = bottom
        self.bottomRadius = bottomRadius
        self.height = height
        self.side = side
        self.solid = solid
    @property # getter - - - - - - - - - -
    def bottom(self):
        """Whether to draw bottom (other inside faces are not drawn)."""
        return self.__bottom
    @bottom.setter
    def bottom(self, bottom=None):
        if  bottom is None:
            bottom = SFBool.DEFAULT_VALUE
        assertValidSFBool(bottom)
        self.__bottom = bottom
    @property # getter - - - - - - - - - -
    def bottomRadius(self):
        """(0,+infinity) Size in meters."""
        return self.__bottomRadius
    @bottomRadius.setter
    def bottomRadius(self, bottomRadius=None):
        if  bottomRadius is None:
            bottomRadius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(bottomRadius)
        assertPositive('bottomRadius', bottomRadius)
        self.__bottomRadius = bottomRadius
    @property # getter - - - - - - - - - -
    def height(self):
        """(0,+infinity) Size in meters."""
        return self.__height
    @height.setter
    def height(self, height=None):
        if  height is None:
            height = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(height)
        assertPositive('height', height)
        self.__height = height
    @property # getter - - - - - - - - - -
    def side(self):
        """Whether to draw sides (other inside faces are not drawn)."""
        return self.__side
    @side.setter
    def side(self, side=None):
        if  side is None:
            side = SFBool.DEFAULT_VALUE
        assertValidSFBool(side)
        self.__side = side
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Cone.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Cone'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bottom != True:
            result += " bottom='" + SFBool(self.bottom).XML() + "'"
        if self.bottomRadius != 1:
            result += " bottomRadius='" + SFFloat(self.bottomRadius).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.height != 2:
            result += " height='" + SFFloat(self.height).XML() + "'"
        if self.side != True:
            result += " side='" + SFBool(self.side).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Cone>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ConeEmitter(_X3DParticleEmitterNode):
    """
    ConeEmitter generates all available particles from a specific point in space.
    """
    NAME = 'ConeEmitter'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ConeEmitter'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('angle', 0.7854, FieldType.SFFloat, AccessType.inputOutput, 'ConeEmitter'),
        ('direction', (0, 1, 0), FieldType.SFVec3f, AccessType.inputOutput, 'ConeEmitter'),
        ('mass', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('position', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'ConeEmitter'),
        ('speed', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('surfaceArea', 0, FieldType.SFFloat, AccessType.initializeOnly, 'X3DParticleEmitterNode'),
        ('variation', 0.25, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 angle=0.7854,
                 direction=(0, 1, 0),
                 mass=0,
                 position=(0, 0, 0),
                 speed=0,
                 surfaceArea=0,
                 variation=0.25,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ConeEmitter __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.angle = angle
        self.direction = direction
        self.mass = mass
        self.position = position
        self.speed = speed
        self.surfaceArea = surfaceArea
        self.variation = variation
    @property # getter - - - - - - - - - -
    def angle(self):
        """[0,+infinity) Cone boundary for random distribution of particles about initial direction."""
        return self.__angle
    @angle.setter
    def angle(self, angle=None):
        if  angle is None:
            angle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(angle)
        assertGreaterThanEquals('angle', angle, 0)
        assertLessThanEquals('angle', angle, 3.1416)
        self.__angle = angle
    @property # getter - - - - - - - - - -
    def direction(self):
        """Initial direction from which particles emanate."""
        return self.__direction
    @direction.setter
    def direction(self, direction=None):
        if  direction is None:
            direction = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(direction)
        assertGreaterThanEquals('direction', direction, -1)
        assertLessThanEquals('direction', direction, 1)
        self.__direction = direction
    @property # getter - - - - - - - - - -
    def mass(self):
        return self.__mass
    @mass.setter
    def mass(self, mass=None):
        if  mass is None:
            mass = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(mass)
        assertNonNegative('mass', mass)
        self.__mass = mass
    @property # getter - - - - - - - - - -
    def position(self):
        """Point from which particles emanate."""
        return self.__position
    @position.setter
    def position(self, position=None):
        if  position is None:
            position = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(position)
        self.__position = position
    @property # getter - - - - - - - - - -
    def speed(self):
        """[0,+infinity) Initial linear speed (default is m/s) imparted to all particles along their direction of movement."""
        return self.__speed
    @speed.setter
    def speed(self, speed=None):
        if  speed is None:
            speed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speed)
        assertNonNegative('speed', speed)
        self.__speed = speed
    @property # getter - - - - - - - - - -
    def surfaceArea(self):
        """[0,+infinity) Particle surface area in area base units (default is meters squared)."""
        return self.__surfaceArea
    @surfaceArea.setter
    def surfaceArea(self, surfaceArea=None):
        if  surfaceArea is None:
            surfaceArea = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(surfaceArea)
        assertNonNegative('surfaceArea', surfaceArea)
        self.__surfaceArea = surfaceArea
    @property # getter - - - - - - - - - -
    def variation(self):
        """[0,+infinity) Multiplier for the randomness used to control the range of possible output values."""
        return self.__variation
    @variation.setter
    def variation(self, variation=None):
        if  variation is None:
            variation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(variation)
        assertNonNegative('variation', variation)
        self.__variation = variation
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ConeEmitter.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ConeEmitter'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.angle != 0.7854:
            result += " angle='" + SFFloat(self.angle).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.direction != (0, 1, 0):
            result += " direction='" + SFVec3f(self.direction).XML() + "'"
        if self.mass != 0:
            result += " mass='" + SFFloat(self.mass).XML() + "'"
        if self.position != (0, 0, 0):
            result += " position='" + SFVec3f(self.position).XML() + "'"
        if self.speed != 0:
            result += " speed='" + SFFloat(self.speed).XML() + "'"
        if self.surfaceArea != 0:
            result += " surfaceArea='" + SFFloat(self.surfaceArea).XML() + "'"
        if self.variation != 0.25:
            result += " variation='" + SFFloat(self.variation).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ConeEmitter>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Contact(_X3DNode):
    """
    Contact nodes are produced as output events when two collidable objects or spaces make contact.
    """
    NAME = 'Contact'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Contact'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('appliedParameters', ["BOUNCE"], FieldType.MFString, AccessType.inputOutput, 'Contact'),
        ('bounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'Contact'),
        ('contactNormal', (0, 1, 0), FieldType.SFVec3f, AccessType.inputOutput, 'Contact'),
        ('depth', 0, FieldType.SFFloat, AccessType.inputOutput, 'Contact'),
        ('frictionCoefficients', (0, 0), FieldType.SFVec2f, AccessType.inputOutput, 'Contact'),
        ('frictionDirection', (0, 1, 0), FieldType.SFVec3f, AccessType.inputOutput, 'Contact'),
        ('minBounceSpeed', 0, FieldType.SFFloat, AccessType.inputOutput, 'Contact'),
        ('position', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'Contact'),
        ('slipCoefficients', (0, 0), FieldType.SFVec2f, AccessType.inputOutput, 'Contact'),
        ('softnessConstantForceMix', 0.0001, FieldType.SFFloat, AccessType.inputOutput, 'Contact'),
        ('softnessErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'Contact'),
        ('surfaceSpeed', (0, 0), FieldType.SFVec2f, AccessType.inputOutput, 'Contact'),
        ('body1', None, FieldType.SFNode, AccessType.inputOutput, 'Contact'),
        ('body2', None, FieldType.SFNode, AccessType.inputOutput, 'Contact'),
        ('geometry1', None, FieldType.SFNode, AccessType.inputOutput, 'Contact'),
        ('geometry2', None, FieldType.SFNode, AccessType.inputOutput, 'Contact'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 appliedParameters=["BOUNCE"],
                 bounce=0,
                 contactNormal=(0, 1, 0),
                 depth=0,
                 frictionCoefficients=(0, 0),
                 frictionDirection=(0, 1, 0),
                 minBounceSpeed=0,
                 position=(0, 0, 0),
                 slipCoefficients=(0, 0),
                 softnessConstantForceMix=0.0001,
                 softnessErrorCorrection=0.8,
                 surfaceSpeed=(0, 0),
                 body1=None,
                 body2=None,
                 geometry1=None,
                 geometry2=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Contact __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.appliedParameters = appliedParameters
        self.bounce = bounce
        self.contactNormal = contactNormal
        self.depth = depth
        self.frictionCoefficients = frictionCoefficients
        self.frictionDirection = frictionDirection
        self.minBounceSpeed = minBounceSpeed
        self.position = position
        self.slipCoefficients = slipCoefficients
        self.softnessConstantForceMix = softnessConstantForceMix
        self.softnessErrorCorrection = softnessErrorCorrection
        self.surfaceSpeed = surfaceSpeed
        self.body1 = body1
        self.body2 = body2
        self.geometry1 = geometry1
        self.geometry2 = geometry2
    @property # getter - - - - - - - - - -
    def appliedParameters(self):
        """Default global parameters for collision outputs of rigid body physics system."""
        return self.__appliedParameters
    @appliedParameters.setter
    def appliedParameters(self, appliedParameters=None):
        if  appliedParameters is None:
            appliedParameters = MFString.DEFAULT_VALUE
        assertValidMFString(appliedParameters)
        self.__appliedParameters = appliedParameters
    @property # getter - - - - - - - - - -
    def bounce(self):
        """[0,1] bounce indicates bounciness (0 = no bounce at all, 1 = maximum bounce)."""
        return self.__bounce
    @bounce.setter
    def bounce(self, bounce=None):
        if  bounce is None:
            bounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(bounce)
        assertZeroToOne('bounce', bounce)
        self.__bounce = bounce
    @property # getter - - - - - - - - - -
    def contactNormal(self):
        """contactNormal is unit vector describing normal between two colliding bodies."""
        return self.__contactNormal
    @contactNormal.setter
    def contactNormal(self, contactNormal=None):
        if  contactNormal is None:
            contactNormal = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(contactNormal)
        self.__contactNormal = contactNormal
    @property # getter - - - - - - - - - -
    def depth(self):
        """[0,1] depth indicates how deep the current intersection is along normal vector."""
        return self.__depth
    @depth.setter
    def depth(self, depth=None):
        if  depth is None:
            depth = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(depth)
        self.__depth = depth
    @property # getter - - - - - - - - - -
    def frictionCoefficients(self):
        """frictionCoefficients used for computing surface drag."""
        return self.__frictionCoefficients
    @frictionCoefficients.setter
    def frictionCoefficients(self, frictionCoefficients=None):
        if  frictionCoefficients is None:
            frictionCoefficients = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(frictionCoefficients)
        assertNonNegative('frictionCoefficients', frictionCoefficients)
        self.__frictionCoefficients = frictionCoefficients
    @property # getter - - - - - - - - - -
    def frictionDirection(self):
        """frictionDirection controls friction vector."""
        return self.__frictionDirection
    @frictionDirection.setter
    def frictionDirection(self, frictionDirection=None):
        if  frictionDirection is None:
            frictionDirection = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(frictionDirection)
        self.__frictionDirection = frictionDirection
    @property # getter - - - - - - - - - -
    def minBounceSpeed(self):
        """[0,+infinity) minBounceSpeed m/s needed to bounce."""
        return self.__minBounceSpeed
    @minBounceSpeed.setter
    def minBounceSpeed(self, minBounceSpeed=None):
        if  minBounceSpeed is None:
            minBounceSpeed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(minBounceSpeed)
        assertNonNegative('minBounceSpeed', minBounceSpeed)
        self.__minBounceSpeed = minBounceSpeed
    @property # getter - - - - - - - - - -
    def position(self):
        """position (x, y, z in meters) of exact location of collision."""
        return self.__position
    @position.setter
    def position(self, position=None):
        if  position is None:
            position = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(position)
        self.__position = position
    @property # getter - - - - - - - - - -
    def slipCoefficients(self):
        """slipCoefficients used for computing surface drag."""
        return self.__slipCoefficients
    @slipCoefficients.setter
    def slipCoefficients(self, slipCoefficients=None):
        if  slipCoefficients is None:
            slipCoefficients = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(slipCoefficients)
        self.__slipCoefficients = slipCoefficients
    @property # getter - - - - - - - - - -
    def softnessConstantForceMix(self):
        """[0,1] softnessConstantForceMix value applies a constant force value to make colliding surfaces appear to be somewhat soft."""
        return self.__softnessConstantForceMix
    @softnessConstantForceMix.setter
    def softnessConstantForceMix(self, softnessConstantForceMix=None):
        if  softnessConstantForceMix is None:
            softnessConstantForceMix = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(softnessConstantForceMix)
        assertZeroToOne('softnessConstantForceMix', softnessConstantForceMix)
        self.__softnessConstantForceMix = softnessConstantForceMix
    @property # getter - - - - - - - - - -
    def softnessErrorCorrection(self):
        """[0,1] softnessErrorCorrection indicates fraction of collision error fixed in a set of evaluations (0 = no error correction, 1 = all errors corrected in single step)."""
        return self.__softnessErrorCorrection
    @softnessErrorCorrection.setter
    def softnessErrorCorrection(self, softnessErrorCorrection=None):
        if  softnessErrorCorrection is None:
            softnessErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(softnessErrorCorrection)
        assertZeroToOne('softnessErrorCorrection', softnessErrorCorrection)
        self.__softnessErrorCorrection = softnessErrorCorrection
    @property # getter - - - - - - - - - -
    def surfaceSpeed(self):
        """surfaceSpeed defines speed vectors for computing surface drag, if contact surfaces move independently of bodies."""
        return self.__surfaceSpeed
    @surfaceSpeed.setter
    def surfaceSpeed(self, surfaceSpeed=None):
        if  surfaceSpeed is None:
            surfaceSpeed = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(surfaceSpeed)
        self.__surfaceSpeed = surfaceSpeed
    @property # getter - - - - - - - - - -
    def body1(self):
        return self.__body1
    @body1.setter
    def body1(self, body1=None):
        if  body1 is None:
            body1 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body1)
        if not isinstance(body1, object):
            # print(flush=True)
            raise X3DTypeError(str(body1) + ' does not have a valid node type object')
        self.__body1 = body1
    @property # getter - - - - - - - - - -
    def body2(self):
        return self.__body2
    @body2.setter
    def body2(self, body2=None):
        if  body2 is None:
            body2 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body2)
        if not isinstance(body2, object):
            # print(flush=True)
            raise X3DTypeError(str(body2) + ' does not have a valid node type object')
        self.__body2 = body2
    @property # getter - - - - - - - - - -
    def geometry1(self):
        return self.__geometry1
    @geometry1.setter
    def geometry1(self, geometry1=None):
        if  geometry1 is None:
            geometry1 = SFNode.DEFAULT_VALUE
        assertValidSFNode(geometry1)
        if not isinstance(geometry1, object):
            # print(flush=True)
            raise X3DTypeError(str(geometry1) + ' does not have a valid node type object')
        self.__geometry1 = geometry1
    @property # getter - - - - - - - - - -
    def geometry2(self):
        return self.__geometry2
    @geometry2.setter
    def geometry2(self, geometry2=None):
        if  geometry2 is None:
            geometry2 = SFNode.DEFAULT_VALUE
        assertValidSFNode(geometry2)
        if not isinstance(geometry2, object):
            # print(flush=True)
            raise X3DTypeError(str(geometry2) + ' does not have a valid node type object')
        self.__geometry2 = geometry2
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.body1) or bool(self.body2) or bool(self.geometry1) or bool(self.geometry2) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Contact.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Contact'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.appliedParameters != ["BOUNCE"]:
            result += " appliedParameters='" + MFString(self.appliedParameters).XML() + "'"
        if self.bounce != 0:
            result += " bounce='" + SFFloat(self.bounce).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.contactNormal != (0, 1, 0):
            result += " contactNormal='" + SFVec3f(self.contactNormal).XML() + "'"
        if self.depth != 0:
            result += " depth='" + SFFloat(self.depth).XML() + "'"
        if self.frictionCoefficients != (0, 0):
            result += " frictionCoefficients='" + SFVec2f(self.frictionCoefficients).XML() + "'"
        if self.frictionDirection != (0, 1, 0):
            result += " frictionDirection='" + SFVec3f(self.frictionDirection).XML() + "'"
        if self.minBounceSpeed != 0:
            result += " minBounceSpeed='" + SFFloat(self.minBounceSpeed).XML() + "'"
        if self.position != (0, 0, 0):
            result += " position='" + SFVec3f(self.position).XML() + "'"
        if self.slipCoefficients != (0, 0):
            result += " slipCoefficients='" + SFVec2f(self.slipCoefficients).XML() + "'"
        if self.softnessConstantForceMix != 0.0001:
            result += " softnessConstantForceMix='" + SFFloat(self.softnessConstantForceMix).XML() + "'"
        if self.softnessErrorCorrection != 0.8:
            result += " softnessErrorCorrection='" + SFFloat(self.softnessErrorCorrection).XML() + "'"
        if self.surfaceSpeed != (0, 0):
            result += " surfaceSpeed='" + SFVec2f(self.surfaceSpeed).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.body1: # output this SFNode
                result += self.body1.XML(indentLevel=indentLevel+1)
            if self.body2: # output this SFNode
                result += self.body2.XML(indentLevel=indentLevel+1)
            if self.geometry1: # output this SFNode
                result += self.geometry1.XML(indentLevel=indentLevel+1)
            if self.geometry2: # output this SFNode
                result += self.geometry2.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Contact>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Contour2D(_X3DNode):
    """
    Contour2D groups a set of curve segments into a composite contour.
    """
    NAME = 'Contour2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Contour2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'Contour2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Contour2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.children = children
    @property # getter - - - - - - - - - -
    def children(self):
        """[NurbsCurve2D|ContourPolyline2D] The children form a closed loop with first point of first child repeated as last point of last child, and the last point of a segment repeated as first point of the consecutive one."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Contour2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Contour2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Contour2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ContourPolyline2D(_X3DNurbsControlCurveNode):
    """
    ContourPolyline2D defines a linear curve segment as part of a trimming contour in the u-v domain of a NURBS surface.
    """
    NAME = 'ContourPolyline2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ContourPolyline2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('controlPoint', list(), FieldType.MFVec2d, AccessType.inputOutput, 'X3DNurbsControlCurveNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 controlPoint=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ContourPolyline2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.controlPoint = controlPoint
    @property # getter - - - - - - - - - -
    def controlPoint(self):
        """controlPoint specifies the end points of each segment of the piecewise linear curve."""
        return self.__controlPoint
    @controlPoint.setter
    def controlPoint(self, controlPoint=None):
        if  controlPoint is None:
            controlPoint = MFVec2d.DEFAULT_VALUE
        assertValidMFVec2d(controlPoint)
        self.__controlPoint = controlPoint
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ContourPolyline2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ContourPolyline2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.controlPoint != list():
            result += " controlPoint='" + MFVec2d(self.controlPoint).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ContourPolyline2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Coordinate(_X3DCoordinateNode):
    """
    Coordinate builds geometry by defining a set of 3D coordinate (triplet) point values.
    """
    NAME = 'Coordinate'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Coordinate'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('point', list(), FieldType.MFVec3f, AccessType.inputOutput, 'Coordinate'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 point=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Coordinate __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.point = point
    @property # getter - - - - - - - - - -
    def point(self):
        """point contains a set of 3D coordinate (triplet) point values."""
        return self.__point
    @point.setter
    def point(self, point=None):
        if  point is None:
            point = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(point)
        self.__point = point
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Coordinate.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Coordinate'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.point != list():
            result += " point='" + MFVec3f(self.point).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Coordinate>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CoordinateChaser(_X3DChaserNode):
    """
    CoordinateChaser generates a series of coordinate arrays that progressively change from initial value to destination value.
    """
    NAME = 'CoordinateChaser'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CoordinateChaser'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('duration', 1, FieldType.SFTime, AccessType.initializeOnly, 'X3DChaserNode'),
        ('initialDestination', [(0, 0, 0)], FieldType.MFVec3f, AccessType.initializeOnly, 'CoordinateChaser'),
        ('initialValue', [(0, 0, 0)], FieldType.MFVec3f, AccessType.initializeOnly, 'CoordinateChaser'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 duration=1,
                 initialDestination=[(0, 0, 0)],
                 initialValue=[(0, 0, 0)],
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CoordinateChaser __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.duration = duration
        self.initialDestination = initialDestination
        self.initialValue = initialValue
    @property # getter - - - - - - - - - -
    def duration(self):
        """[0,+infinity) duration is the time interval for filter response in seconds."""
        return self.__duration
    @duration.setter
    def duration(self, duration=None):
        if  duration is None:
            duration = SFTime.DEFAULT_VALUE
        assertValidSFTime(duration)
        assertNonNegative('duration', duration)
        self.__duration = duration
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(initialValue)
        self.__initialValue = initialValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CoordinateChaser.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CoordinateChaser'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.duration != 1:
            result += " duration='" + SFTime(self.duration).XML() + "'"
        if self.initialDestination != [(0, 0, 0)]:
            result += " initialDestination='" + MFVec3f(self.initialDestination).XML() + "'"
        if self.initialValue != [(0, 0, 0)]:
            result += " initialValue='" + MFVec3f(self.initialValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</CoordinateChaser>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CoordinateDamper(_X3DDamperNode):
    """
    CoordinateDamper generates a series of coordinate arrays that progressively change from initial value to destination value.
    """
    NAME = 'CoordinateDamper'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CoordinateDamper'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('initialDestination', [(0, 0, 0)], FieldType.MFVec3f, AccessType.initializeOnly, 'CoordinateDamper'),
        ('initialValue', [(0, 0, 0)], FieldType.MFVec3f, AccessType.initializeOnly, 'CoordinateDamper'),
        ('order', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DDamperNode'),
        ('tau', 0.3, FieldType.SFTime, AccessType.inputOutput, 'X3DDamperNode'),
        ('tolerance', -1, FieldType.SFFloat, AccessType.inputOutput, 'X3DDamperNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 initialDestination=[(0, 0, 0)],
                 initialValue=[(0, 0, 0)],
                 order=3,
                 tau=0.3,
                 tolerance=-1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CoordinateDamper __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.initialDestination = initialDestination
        self.initialValue = initialValue
        self.order = order
        self.tau = tau
        self.tolerance = tolerance
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(initialValue)
        self.__initialValue = initialValue
    @property # getter - - - - - - - - - -
    def order(self):
        """[0,5] order defines the number of internal filters (larger means smoother response, longer delay)."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 0)
        assertLessThanEquals('order', order, 5)
        self.__order = order
    @property # getter - - - - - - - - - -
    def tau(self):
        """[0,+infinity) tau is the exponential-decay time constant for filter response in seconds."""
        return self.__tau
    @tau.setter
    def tau(self, tau=None):
        if  tau is None:
            tau = SFTime.DEFAULT_VALUE
        assertValidSFTime(tau)
        assertNonNegative('tau', tau)
        self.__tau = tau
    @property # getter - - - - - - - - - -
    def tolerance(self):
        """[0,+infinity) or -1."""
        return self.__tolerance
    @tolerance.setter
    def tolerance(self, tolerance=None):
        if  tolerance is None:
            tolerance = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(tolerance)
        self.__tolerance = tolerance
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CoordinateDamper.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CoordinateDamper'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.initialDestination != [(0, 0, 0)]:
            result += " initialDestination='" + MFVec3f(self.initialDestination).XML() + "'"
        if self.initialValue != [(0, 0, 0)]:
            result += " initialValue='" + MFVec3f(self.initialValue).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.tau != 0.3:
            result += " tau='" + SFTime(self.tau).XML() + "'"
        if self.tolerance != -1:
            result += " tolerance='" + SFFloat(self.tolerance).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</CoordinateDamper>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CoordinateDouble(_X3DCoordinateNode):
    """
    CoordinateDouble builds geometry by defining a set of 3D coordinate (triplet) point values.
    """
    NAME = 'CoordinateDouble'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CoordinateDouble'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('point', list(), FieldType.MFVec3d, AccessType.inputOutput, 'CoordinateDouble'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 point=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CoordinateDouble __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.point = point
    @property # getter - - - - - - - - - -
    def point(self):
        """point contains a set of 3D coordinate (triplet) point values."""
        return self.__point
    @point.setter
    def point(self, point=None):
        if  point is None:
            point = MFVec3d.DEFAULT_VALUE
        assertValidMFVec3d(point)
        self.__point = point
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CoordinateDouble.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CoordinateDouble'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.point != list():
            result += " point='" + MFVec3d(self.point).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</CoordinateDouble>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CoordinateInterpolator(_X3DInterpolatorNode):
    """
    CoordinateInterpolator linearly interpolates among a list of 3-tuple MFVec3f arrays, producing a single MFVec3f array that is fractional average between two nearest arrays in the list.
    """
    NAME = 'CoordinateInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CoordinateInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFVec3f, AccessType.inputOutput, 'CoordinateInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CoordinateInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CoordinateInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CoordinateInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFVec3f(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</CoordinateInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CoordinateInterpolator2D(_X3DInterpolatorNode):
    """
    CoordinateInterpolator2D generates a series of SFVec2f or MFVec2f 2-tuple float values.
    """
    NAME = 'CoordinateInterpolator2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CoordinateInterpolator2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFVec2f, AccessType.inputOutput, 'CoordinateInterpolator2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CoordinateInterpolator2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CoordinateInterpolator2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CoordinateInterpolator2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFVec2f(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</CoordinateInterpolator2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Cylinder(_X3DGeometryNode):
    """
    Cylinder is a geometry node.
    """
    NAME = 'Cylinder'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Cylinder'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bottom', True, FieldType.SFBool, AccessType.initializeOnly, 'Cylinder'),
        ('height', 2, FieldType.SFFloat, AccessType.initializeOnly, 'Cylinder'),
        ('radius', 1, FieldType.SFFloat, AccessType.initializeOnly, 'Cylinder'),
        ('side', True, FieldType.SFBool, AccessType.initializeOnly, 'Cylinder'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'Cylinder'),
        ('top', True, FieldType.SFBool, AccessType.inputOutput, 'Cylinder'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bottom=True,
                 height=2,
                 radius=1,
                 side=True,
                 solid=True,
                 top=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Cylinder __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bottom = bottom
        self.height = height
        self.radius = radius
        self.side = side
        self.solid = solid
        self.top = top
    @property # getter - - - - - - - - - -
    def bottom(self):
        """Whether to draw bottom (inside faces are never drawn)."""
        return self.__bottom
    @bottom.setter
    def bottom(self, bottom=None):
        if  bottom is None:
            bottom = SFBool.DEFAULT_VALUE
        assertValidSFBool(bottom)
        self.__bottom = bottom
    @property # getter - - - - - - - - - -
    def height(self):
        """(0,+infinity) Size in meters."""
        return self.__height
    @height.setter
    def height(self, height=None):
        if  height is None:
            height = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(height)
        assertPositive('height', height)
        self.__height = height
    @property # getter - - - - - - - - - -
    def radius(self):
        """(0,+infinity) Size in meters."""
        return self.__radius
    @radius.setter
    def radius(self, radius=None):
        if  radius is None:
            radius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(radius)
        assertPositive('radius', radius)
        self.__radius = radius
    @property # getter - - - - - - - - - -
    def side(self):
        """Whether to draw sides (inside faces are never drawn)."""
        return self.__side
    @side.setter
    def side(self, side=None):
        if  side is None:
            side = SFBool.DEFAULT_VALUE
        assertValidSFBool(side)
        self.__side = side
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def top(self):
        """Whether to draw top (inside faces are never drawn)."""
        return self.__top
    @top.setter
    def top(self, top=None):
        if  top is None:
            top = SFBool.DEFAULT_VALUE
        assertValidSFBool(top)
        self.__top = top
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Cylinder.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Cylinder'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bottom != True:
            result += " bottom='" + SFBool(self.bottom).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.height != 2:
            result += " height='" + SFFloat(self.height).XML() + "'"
        if self.radius != 1:
            result += " radius='" + SFFloat(self.radius).XML() + "'"
        if self.side != True:
            result += " side='" + SFBool(self.side).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.top != True:
            result += " top='" + SFBool(self.top).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Cylinder>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class CylinderSensor(_X3DDragSensorNode):
    """
    CylinderSensor converts pointer motion (for example, a mouse or wand) into rotation values using an invisible cylinder aligned with local Y-axis.
    """
    NAME = 'CylinderSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#CylinderSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('autoOffset', True, FieldType.SFBool, AccessType.inputOutput, 'X3DDragSensorNode'),
        ('axisRotation', (0, 1, 0, 0), FieldType.SFRotation, AccessType.inputOutput, 'CylinderSensor'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DPointingDeviceSensorNode'),
        ('diskAngle', 0.26179167, FieldType.SFFloat, AccessType.inputOutput, 'CylinderSensor'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('maxAngle', -1, FieldType.SFFloat, AccessType.inputOutput, 'CylinderSensor'),
        ('minAngle', 0, FieldType.SFFloat, AccessType.inputOutput, 'CylinderSensor'),
        ('offset', 0, FieldType.SFFloat, AccessType.inputOutput, 'CylinderSensor'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 autoOffset=True,
                 axisRotation=(0, 1, 0, 0),
                 description='',
                 diskAngle=0.26179167,
                 enabled=True,
                 maxAngle=-1,
                 minAngle=0,
                 offset=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode CylinderSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.autoOffset = autoOffset
        self.axisRotation = axisRotation
        self.description = description
        self.diskAngle = diskAngle
        self.enabled = enabled
        self.maxAngle = maxAngle
        self.minAngle = minAngle
        self.offset = offset
    @property # getter - - - - - - - - - -
    def autoOffset(self):
        """determines whether previous offset values are remembered/accumulated."""
        return self.__autoOffset
    @autoOffset.setter
    def autoOffset(self, autoOffset=None):
        if  autoOffset is None:
            autoOffset = SFBool.DEFAULT_VALUE
        assertValidSFBool(autoOffset)
        self.__autoOffset = autoOffset
    @property # getter - - - - - - - - - -
    def axisRotation(self):
        """axisRotation determines local sensor coordinate system by rotating the local coordinate system."""
        return self.__axisRotation
    @axisRotation.setter
    def axisRotation(self, axisRotation=None):
        if  axisRotation is None:
            axisRotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(axisRotation)
        self.__axisRotation = axisRotation
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def diskAngle(self):
        """Help decide rotation behavior from initial relative bearing of pointer drag: acute angle whether cylinder sides or end-cap disks of virtual-geometry sensor are used for manipulation."""
        return self.__diskAngle
    @diskAngle.setter
    def diskAngle(self, diskAngle=None):
        if  diskAngle is None:
            diskAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(diskAngle)
        assertGreaterThanEquals('diskAngle', diskAngle, 0)
        assertLessThanEquals('diskAngle', diskAngle, 1.5708)
        self.__diskAngle = diskAngle
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def maxAngle(self):
        """clamps rotation_changed events within range of min/max values Hint: if minAngle > maxAngle, rotation is not clamped."""
        return self.__maxAngle
    @maxAngle.setter
    def maxAngle(self, maxAngle=None):
        if  maxAngle is None:
            maxAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxAngle)
        assertGreaterThan('maxAngle', maxAngle, -6.2832)
        assertLessThan('maxAngle', maxAngle, 6.2832)
        self.__maxAngle = maxAngle
    @property # getter - - - - - - - - - -
    def minAngle(self):
        """clamps rotation_changed events within range of min/max values Hint: if minAngle > maxAngle, rotation is not clamped."""
        return self.__minAngle
    @minAngle.setter
    def minAngle(self, minAngle=None):
        if  minAngle is None:
            minAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(minAngle)
        assertGreaterThan('minAngle', minAngle, -6.2832)
        assertLessThan('minAngle', minAngle, 6.2832)
        self.__minAngle = minAngle
    @property # getter - - - - - - - - - -
    def offset(self):
        """Sends event and remembers last value sensed."""
        return self.__offset
    @offset.setter
    def offset(self, offset=None):
        if  offset is None:
            offset = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(offset)
        self.__offset = offset
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function CylinderSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<CylinderSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.autoOffset != True:
            result += " autoOffset='" + SFBool(self.autoOffset).XML() + "'"
        if self.axisRotation != (0, 1, 0, 0):
            result += " axisRotation='" + SFRotation(self.axisRotation).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.diskAngle != 0.26179167:
            result += " diskAngle='" + SFFloat(self.diskAngle).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.maxAngle != -1:
            result += " maxAngle='" + SFFloat(self.maxAngle).XML() + "'"
        if self.minAngle != 0:
            result += " minAngle='" + SFFloat(self.minAngle).XML() + "'"
        if self.offset != 0:
            result += " offset='" + SFFloat(self.offset).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</CylinderSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class DirectionalLight(_X3DLightNode):
    """
    DirectionalLight might not be scoped by parent Group or Transform at levels 1 or 2.
    """
    NAME = 'DirectionalLight'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#DirectionalLight'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ambientIntensity', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DLightNode'),
        ('color', (1, 1, 1), FieldType.SFColor, AccessType.inputOutput, 'X3DLightNode'),
        ('direction', (0, 0, -1), FieldType.SFVec3f, AccessType.inputOutput, 'DirectionalLight'),
        ('global_', False, FieldType.SFBool, AccessType.inputOutput, 'DirectionalLight'),
        ('intensity', 1, FieldType.SFFloat, AccessType.inputOutput, 'X3DLightNode'),
        ('on', True, FieldType.SFBool, AccessType.inputOutput, 'X3DLightNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ambientIntensity=0,
                 color=(1, 1, 1),
                 direction=(0, 0, -1),
                 global_=False,
                 intensity=1,
                 on=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode DirectionalLight __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ambientIntensity = ambientIntensity
        self.color = color
        self.direction = direction
        self.global_ = global_
        self.intensity = intensity
        self.on = on
    @property # getter - - - - - - - - - -
    def ambientIntensity(self):
        """[0,1] Brightness of ambient (nondirectional background) emission from the light."""
        return self.__ambientIntensity
    @ambientIntensity.setter
    def ambientIntensity(self, ambientIntensity=None):
        if  ambientIntensity is None:
            ambientIntensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(ambientIntensity)
        assertZeroToOne('ambientIntensity', ambientIntensity)
        self.__ambientIntensity = ambientIntensity
    @property # getter - - - - - - - - - -
    def color(self):
        """[0,1] color of light, applied to colors of objects."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFColor.DEFAULT_VALUE
        assertValidSFColor(color)
        assertZeroToOne('color', color)
        self.__color = color
    @property # getter - - - - - - - - - -
    def direction(self):
        """Orientation vector of light relative to local coordinate system."""
        return self.__direction
    @direction.setter
    def direction(self, direction=None):
        if  direction is None:
            direction = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(direction)
        self.__direction = direction
    @property # getter - - - - - - - - - -
    def global_(self):
        return self.__global_
    @global_.setter
    def global_(self, global_=None):
        if  global_ is None:
            global_ = SFBool.DEFAULT_VALUE
        assertValidSFBool(global_)
        self.__global_ = global_
    @property # getter - - - - - - - - - -
    def intensity(self):
        """[0,1] Brightness of direct emission from the light."""
        return self.__intensity
    @intensity.setter
    def intensity(self, intensity=None):
        if  intensity is None:
            intensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(intensity)
        assertZeroToOne('intensity', intensity)
        self.__intensity = intensity
    @property # getter - - - - - - - - - -
    def on(self):
        """Enables/disables this light source."""
        return self.__on
    @on.setter
    def on(self, on=None):
        if  on is None:
            on = SFBool.DEFAULT_VALUE
        assertValidSFBool(on)
        self.__on = on
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function DirectionalLight.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<DirectionalLight'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ambientIntensity != 0:
            result += " ambientIntensity='" + SFFloat(self.ambientIntensity).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.color != (1, 1, 1):
            result += " color='" + SFColor(self.color).XML() + "'"
        if self.direction != (0, 0, -1):
            result += " direction='" + SFVec3f(self.direction).XML() + "'"
        if self.global_ != False:
            result += " global_='" + SFBool(self.global_).XML() + "'"
        if self.intensity != 1:
            result += " intensity='" + SFFloat(self.intensity).XML() + "'"
        if self.on != True:
            result += " on='" + SFBool(self.on).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</DirectionalLight>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class DISEntityManager(_X3DChildNode):
    """
    DISEntityManager notifies a scene when new DIS ESPDU entities arrive or current entities leave.
    """
    NAME = 'DISEntityManager'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#DISEntityManager'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('address', 'localhost', FieldType.SFString, AccessType.inputOutput, 'DISEntityManager'),
        ('applicationID', 0, FieldType.SFInt32, AccessType.inputOutput, 'DISEntityManager'),
        ('port', 0, FieldType.SFInt32, AccessType.inputOutput, 'DISEntityManager'),
        ('siteID', 0, FieldType.SFInt32, AccessType.inputOutput, 'DISEntityManager'),
        ('mapping', list(), FieldType.MFNode, AccessType.inputOutput, 'DISEntityManager'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 address='localhost',
                 applicationID=0,
                 port=0,
                 siteID=0,
                 mapping=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode DISEntityManager __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.address = address
        self.applicationID = applicationID
        self.port = port
        self.siteID = siteID
        self.mapping = mapping
    @property # getter - - - - - - - - - -
    def address(self):
        """Multicast network address, or else "localhost" example: 224."""
        return self.__address
    @address.setter
    def address(self, address=None):
        if  address is None:
            address = SFString.DEFAULT_VALUE
        assertValidSFString(address)
        self.__address = address
    @property # getter - - - - - - - - - -
    def applicationID(self):
        """Each simulation application that can respond to simulation management PDUs needs to have a unique applicationID."""
        return self.__applicationID
    @applicationID.setter
    def applicationID(self, applicationID=None):
        if  applicationID is None:
            applicationID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(applicationID)
        self.__applicationID = applicationID
    @property # getter - - - - - - - - - -
    def port(self):
        """Multicast network port, for example: 3000."""
        return self.__port
    @port.setter
    def port(self, port=None):
        if  port is None:
            port = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(port)
        self.__port = port
    @property # getter - - - - - - - - - -
    def siteID(self):
        """Simulation/exercise siteID of the participating LAN or organization."""
        return self.__siteID
    @siteID.setter
    def siteID(self, siteID=None):
        if  siteID is None:
            siteID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(siteID)
        self.__siteID = siteID
    @property # getter - - - - - - - - - -
    def mapping(self):
        """[DISEntityTypeMapping] mapping field provides a mechanism for automatically creating an X3D model when a new entity arrives over the network."""
        return self.__mapping
    @mapping.setter
    def mapping(self, mapping=None):
        if  mapping is None:
            mapping = MFNode.DEFAULT_VALUE
        assertValidMFNode(mapping)
        self.__mapping = mapping
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.mapping) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function DISEntityManager.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<DISEntityManager'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.address != 'localhost':
            result += " address='" + self.address + "'"
        if self.applicationID != 0:
            result += " applicationID='" + SFInt32(self.applicationID).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.port != 0:
            result += " port='" + SFInt32(self.port).XML() + "'"
        if self.siteID != 0:
            result += " siteID='" + SFInt32(self.siteID).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.mapping: # walk each child node, if any
                for each in self.mapping:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</DISEntityManager>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class DISEntityTypeMapping(_X3DInfoNode, _X3DUrlObject):
    """
    DISEntityTypeMapping provides a best-match mapping from DIS ESPDU entity type information to a specific X3D model, thus providing a visual and behavioral representation that best matches the entity type.
    """
    NAME = 'DISEntityTypeMapping'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#DISEntityTypeMapping'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('category', 0, FieldType.SFInt32, AccessType.initializeOnly, 'DISEntityTypeMapping'),
        ('country', 0, FieldType.SFInt32, AccessType.initializeOnly, 'DISEntityTypeMapping'),
        ('domain', 0, FieldType.SFInt32, AccessType.initializeOnly, 'DISEntityTypeMapping'),
        ('extra', 0, FieldType.SFInt32, AccessType.initializeOnly, 'DISEntityTypeMapping'),
        ('kind', 0, FieldType.SFInt32, AccessType.initializeOnly, 'DISEntityTypeMapping'),
        ('specific', 0, FieldType.SFInt32, AccessType.initializeOnly, 'DISEntityTypeMapping'),
        ('subcategory', 0, FieldType.SFInt32, AccessType.initializeOnly, 'DISEntityTypeMapping'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 category=0,
                 country=0,
                 domain=0,
                 extra=0,
                 kind=0,
                 specific=0,
                 subcategory=0,
                 url=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode DISEntityTypeMapping __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.category = category
        self.country = country
        self.domain = domain
        self.extra = extra
        self.kind = kind
        self.specific = specific
        self.subcategory = subcategory
        self.url = url
    @property # getter - - - - - - - - - -
    def category(self):
        """Integer enumerations value for main category that describes the entity, semantics of each code varies according to domain."""
        return self.__category
    @category.setter
    def category(self, category=None):
        if  category is None:
            category = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(category)
        assertGreaterThanEquals('category', category, 0)
        assertLessThanEquals('category', category, 255)
        self.__category = category
    @property # getter - - - - - - - - - -
    def country(self):
        """Integer enumerations value for country to which the design of the entity or its design specification is attributed."""
        return self.__country
    @country.setter
    def country(self, country=None):
        if  country is None:
            country = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(country)
        assertGreaterThanEquals('country', country, 0)
        assertLessThanEquals('country', country, 65535)
        self.__country = country
    @property # getter - - - - - - - - - -
    def domain(self):
        """Integer enumerations value for domain in which the entity operates: LAND, AIR, SURFACE, SUBSURFACE, SPACE or OTHER."""
        return self.__domain
    @domain.setter
    def domain(self, domain=None):
        if  domain is None:
            domain = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(domain)
        assertGreaterThanEquals('domain', domain, 0)
        assertLessThanEquals('domain', domain, 255)
        self.__domain = domain
    @property # getter - - - - - - - - - -
    def extra(self):
        """Any extra information required to describe a particular entity."""
        return self.__extra
    @extra.setter
    def extra(self, extra=None):
        if  extra is None:
            extra = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(extra)
        assertGreaterThanEquals('extra', extra, 0)
        assertLessThanEquals('extra', extra, 255)
        self.__extra = extra
    @property # getter - - - - - - - - - -
    def kind(self):
        """Integer enumerations value for whether entity is a PLATFORM, MUNITION, LIFE_FORM, ENVIRONMENTAL, CULTURAL_FEATURE, SUPPLY, RADIO, EXPENDABLE, SENSOR_EMITTER or OTHER."""
        return self.__kind
    @kind.setter
    def kind(self, kind=None):
        if  kind is None:
            kind = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(kind)
        assertGreaterThanEquals('kind', kind, 0)
        assertLessThanEquals('kind', kind, 255)
        self.__kind = kind
    @property # getter - - - - - - - - - -
    def specific(self):
        """Specific information about an entity based on the Subcategory field."""
        return self.__specific
    @specific.setter
    def specific(self, specific=None):
        if  specific is None:
            specific = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(specific)
        assertGreaterThanEquals('specific', specific, 0)
        assertLessThanEquals('specific', specific, 255)
        self.__specific = specific
    @property # getter - - - - - - - - - -
    def subcategory(self):
        return self.__subcategory
    @subcategory.setter
    def subcategory(self, subcategory=None):
        if  subcategory is None:
            subcategory = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(subcategory)
        assertGreaterThanEquals('subcategory', subcategory, 0)
        assertLessThanEquals('subcategory', subcategory, 255)
        self.__subcategory = subcategory
    @property # getter - - - - - - - - - -
    def url(self):
        """Local and/or online addresses of X3D model of interest, for example: "ExtrusionExampleShip."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function DISEntityTypeMapping.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<DISEntityTypeMapping'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.category != 0:
            result += " category='" + SFInt32(self.category).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.country != 0:
            result += " country='" + SFInt32(self.country).XML() + "'"
        if self.domain != 0:
            result += " domain='" + SFInt32(self.domain).XML() + "'"
        if self.extra != 0:
            result += " extra='" + SFInt32(self.extra).XML() + "'"
        if self.kind != 0:
            result += " kind='" + SFInt32(self.kind).XML() + "'"
        if self.specific != 0:
            result += " specific='" + SFInt32(self.specific).XML() + "'"
        if self.subcategory != 0:
            result += " subcategory='" + SFInt32(self.subcategory).XML() + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</DISEntityTypeMapping>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Disk2D(_X3DGeometryNode):
    """
    Disk2D is a geometry node that defines a filled (or partially filled) planar circle with center (0,0).
    """
    NAME = 'Disk2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Disk2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('innerRadius', 0, FieldType.SFFloat, AccessType.initializeOnly, 'Disk2D'),
        ('outerRadius', 1, FieldType.SFFloat, AccessType.initializeOnly, 'Disk2D'),
        ('solid', False, FieldType.SFBool, AccessType.initializeOnly, 'Disk2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 innerRadius=0,
                 outerRadius=1,
                 solid=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Disk2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.innerRadius = innerRadius
        self.outerRadius = outerRadius
        self.solid = solid
    @property # getter - - - - - - - - - -
    def innerRadius(self):
        """[0,+infinity) Inner circle radius, greater than or equal to 0."""
        return self.__innerRadius
    @innerRadius.setter
    def innerRadius(self, innerRadius=None):
        if  innerRadius is None:
            innerRadius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(innerRadius)
        assertNonNegative('innerRadius', innerRadius)
        self.__innerRadius = innerRadius
    @property # getter - - - - - - - - - -
    def outerRadius(self):
        """(0,+infinity) Outer radius of circle, greater than or equal to inner radius."""
        return self.__outerRadius
    @outerRadius.setter
    def outerRadius(self, outerRadius=None):
        if  outerRadius is None:
            outerRadius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(outerRadius)
        assertPositive('outerRadius', outerRadius)
        self.__outerRadius = outerRadius
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Disk2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Disk2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.innerRadius != 0:
            result += " innerRadius='" + SFFloat(self.innerRadius).XML() + "'"
        if self.outerRadius != 1:
            result += " outerRadius='" + SFFloat(self.outerRadius).XML() + "'"
        if self.solid != False:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Disk2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class DoubleAxisHingeJoint(_X3DRigidJointNode):
    """
    DoubleAxisHingeJoint has two independent axes located around a common anchor point.
    """
    NAME = 'DoubleAxisHingeJoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#DoubleAxisHingeJoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('anchorPoint', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('axis1', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('axis2', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('desiredAngularVelocity1', 0, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('desiredAngularVelocity2', 0, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('forceOutput', ["NONE"], FieldType.MFString, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('maxAngle1', 3.141592653, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('maxTorque1', 0, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('maxTorque2', 0, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('minAngle1', -3.141592653, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('stop1Bounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('stop1ConstantForceMix', 0.001, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('stop1ErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('suspensionErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('suspensionForce', 0, FieldType.SFFloat, AccessType.inputOutput, 'DoubleAxisHingeJoint'),
        ('body1', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('body2', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 anchorPoint=(0, 0, 0),
                 axis1=(0, 0, 0),
                 axis2=(0, 0, 0),
                 desiredAngularVelocity1=0,
                 desiredAngularVelocity2=0,
                 forceOutput=["NONE"],
                 maxAngle1=3.141592653,
                 maxTorque1=0,
                 maxTorque2=0,
                 minAngle1=-3.141592653,
                 stop1Bounce=0,
                 stop1ConstantForceMix=0.001,
                 stop1ErrorCorrection=0.8,
                 suspensionErrorCorrection=0.8,
                 suspensionForce=0,
                 body1=None,
                 body2=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode DoubleAxisHingeJoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.anchorPoint = anchorPoint
        self.axis1 = axis1
        self.axis2 = axis2
        self.desiredAngularVelocity1 = desiredAngularVelocity1
        self.desiredAngularVelocity2 = desiredAngularVelocity2
        self.forceOutput = forceOutput
        self.maxAngle1 = maxAngle1
        self.maxTorque1 = maxTorque1
        self.maxTorque2 = maxTorque2
        self.minAngle1 = minAngle1
        self.stop1Bounce = stop1Bounce
        self.stop1ConstantForceMix = stop1ConstantForceMix
        self.stop1ErrorCorrection = stop1ErrorCorrection
        self.suspensionErrorCorrection = suspensionErrorCorrection
        self.suspensionForce = suspensionForce
        self.body1 = body1
        self.body2 = body2
    @property # getter - - - - - - - - - -
    def anchorPoint(self):
        """anchorPoint is joint center, specified in world coordinates."""
        return self.__anchorPoint
    @anchorPoint.setter
    def anchorPoint(self, anchorPoint=None):
        if  anchorPoint is None:
            anchorPoint = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(anchorPoint)
        self.__anchorPoint = anchorPoint
    @property # getter - - - - - - - - - -
    def axis1(self):
        """axis1 defines axis vector of joint connection to body1."""
        return self.__axis1
    @axis1.setter
    def axis1(self, axis1=None):
        if  axis1 is None:
            axis1 = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(axis1)
        self.__axis1 = axis1
    @property # getter - - - - - - - - - -
    def axis2(self):
        """axis2 defines axis vector of joint connection to body2."""
        return self.__axis2
    @axis2.setter
    def axis2(self, axis2=None):
        if  axis2 is None:
            axis2 = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(axis2)
        self.__axis2 = axis2
    @property # getter - - - - - - - - - -
    def desiredAngularVelocity1(self):
        """desiredAngularVelocity1 is goal rotation rate for hinge connection to body1."""
        return self.__desiredAngularVelocity1
    @desiredAngularVelocity1.setter
    def desiredAngularVelocity1(self, desiredAngularVelocity1=None):
        if  desiredAngularVelocity1 is None:
            desiredAngularVelocity1 = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(desiredAngularVelocity1)
        self.__desiredAngularVelocity1 = desiredAngularVelocity1
    @property # getter - - - - - - - - - -
    def desiredAngularVelocity2(self):
        """desiredAngularVelocity2 is goal rotation rate for hinge connection to body2."""
        return self.__desiredAngularVelocity2
    @desiredAngularVelocity2.setter
    def desiredAngularVelocity2(self, desiredAngularVelocity2=None):
        if  desiredAngularVelocity2 is None:
            desiredAngularVelocity2 = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(desiredAngularVelocity2)
        self.__desiredAngularVelocity2 = desiredAngularVelocity2
    @property # getter - - - - - - - - - -
    def forceOutput(self):
        """forceOutput controls which output fields are generated for the next frame."""
        return self.__forceOutput
    @forceOutput.setter
    def forceOutput(self, forceOutput=None):
        if  forceOutput is None:
            forceOutput = MFString.DEFAULT_VALUE
        assertValidMFString(forceOutput)
        self.__forceOutput = forceOutput
    @property # getter - - - - - - - - - -
    def maxAngle1(self):
        """[-pi,pi] maxAngle1 is maximum rotation angle for hinge."""
        return self.__maxAngle1
    @maxAngle1.setter
    def maxAngle1(self, maxAngle1=None):
        if  maxAngle1 is None:
            maxAngle1 = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxAngle1)
        self.__maxAngle1 = maxAngle1
    @property # getter - - - - - - - - - -
    def maxTorque1(self):
        """maxTorque1 is maximum rotational torque applied by corresponding motor axis to achieve desiredAngularVelocity1."""
        return self.__maxTorque1
    @maxTorque1.setter
    def maxTorque1(self, maxTorque1=None):
        if  maxTorque1 is None:
            maxTorque1 = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxTorque1)
        self.__maxTorque1 = maxTorque1
    @property # getter - - - - - - - - - -
    def maxTorque2(self):
        """maxTorque2 is maximum rotational torque applied by corresponding motor axis to achieve desiredAngularVelocity2."""
        return self.__maxTorque2
    @maxTorque2.setter
    def maxTorque2(self, maxTorque2=None):
        if  maxTorque2 is None:
            maxTorque2 = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxTorque2)
        self.__maxTorque2 = maxTorque2
    @property # getter - - - - - - - - - -
    def minAngle1(self):
        """[-pi,pi] minAngle1 is minimum rotation angle for hinge."""
        return self.__minAngle1
    @minAngle1.setter
    def minAngle1(self, minAngle1=None):
        if  minAngle1 is None:
            minAngle1 = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(minAngle1)
        self.__minAngle1 = minAngle1
    @property # getter - - - - - - - - - -
    def stop1Bounce(self):
        """[0,1] stop1Bounce is velocity factor for bounce back once stop point is reached."""
        return self.__stop1Bounce
    @stop1Bounce.setter
    def stop1Bounce(self, stop1Bounce=None):
        if  stop1Bounce is None:
            stop1Bounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop1Bounce)
        self.__stop1Bounce = stop1Bounce
    @property # getter - - - - - - - - - -
    def stop1ConstantForceMix(self):
        """[0,1] stop1ConstantForceMix value applies a constant force value to make colliding surfaces appear to be somewhat soft."""
        return self.__stop1ConstantForceMix
    @stop1ConstantForceMix.setter
    def stop1ConstantForceMix(self, stop1ConstantForceMix=None):
        if  stop1ConstantForceMix is None:
            stop1ConstantForceMix = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop1ConstantForceMix)
        self.__stop1ConstantForceMix = stop1ConstantForceMix
    @property # getter - - - - - - - - - -
    def stop1ErrorCorrection(self):
        """[0,1] stop1ErrorCorrection is fraction of error correction performed during time step once stop point is reached."""
        return self.__stop1ErrorCorrection
    @stop1ErrorCorrection.setter
    def stop1ErrorCorrection(self, stop1ErrorCorrection=None):
        if  stop1ErrorCorrection is None:
            stop1ErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop1ErrorCorrection)
        self.__stop1ErrorCorrection = stop1ErrorCorrection
    @property # getter - - - - - - - - - -
    def suspensionErrorCorrection(self):
        """[0,1] suspensionErrorCorrection describes how quickly the system resolves intersection errors due to floating-point inaccuracies."""
        return self.__suspensionErrorCorrection
    @suspensionErrorCorrection.setter
    def suspensionErrorCorrection(self, suspensionErrorCorrection=None):
        if  suspensionErrorCorrection is None:
            suspensionErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(suspensionErrorCorrection)
        self.__suspensionErrorCorrection = suspensionErrorCorrection
    @property # getter - - - - - - - - - -
    def suspensionForce(self):
        """[0,1] suspensionForce describes how quickly the system resolves intersection errors due to floating-point inaccuracies."""
        return self.__suspensionForce
    @suspensionForce.setter
    def suspensionForce(self, suspensionForce=None):
        if  suspensionForce is None:
            suspensionForce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(suspensionForce)
        self.__suspensionForce = suspensionForce
    @property # getter - - - - - - - - - -
    def body1(self):
        return self.__body1
    @body1.setter
    def body1(self, body1=None):
        if  body1 is None:
            body1 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body1)
        if not isinstance(body1, object):
            # print(flush=True)
            raise X3DTypeError(str(body1) + ' does not have a valid node type object')
        self.__body1 = body1
    @property # getter - - - - - - - - - -
    def body2(self):
        return self.__body2
    @body2.setter
    def body2(self, body2=None):
        if  body2 is None:
            body2 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body2)
        if not isinstance(body2, object):
            # print(flush=True)
            raise X3DTypeError(str(body2) + ' does not have a valid node type object')
        self.__body2 = body2
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.body1) or bool(self.body2) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function DoubleAxisHingeJoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<DoubleAxisHingeJoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.anchorPoint != (0, 0, 0):
            result += " anchorPoint='" + SFVec3f(self.anchorPoint).XML() + "'"
        if self.axis1 != (0, 0, 0):
            result += " axis1='" + SFVec3f(self.axis1).XML() + "'"
        if self.axis2 != (0, 0, 0):
            result += " axis2='" + SFVec3f(self.axis2).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.desiredAngularVelocity1 != 0:
            result += " desiredAngularVelocity1='" + SFFloat(self.desiredAngularVelocity1).XML() + "'"
        if self.desiredAngularVelocity2 != 0:
            result += " desiredAngularVelocity2='" + SFFloat(self.desiredAngularVelocity2).XML() + "'"
        if self.forceOutput != ["NONE"]:
            result += " forceOutput='" + MFString(self.forceOutput).XML() + "'"
        if self.maxAngle1 != 3.141592653:
            result += " maxAngle1='" + SFFloat(self.maxAngle1).XML() + "'"
        if self.maxTorque1 != 0:
            result += " maxTorque1='" + SFFloat(self.maxTorque1).XML() + "'"
        if self.maxTorque2 != 0:
            result += " maxTorque2='" + SFFloat(self.maxTorque2).XML() + "'"
        if self.minAngle1 != -3.141592653:
            result += " minAngle1='" + SFFloat(self.minAngle1).XML() + "'"
        if self.stop1Bounce != 0:
            result += " stop1Bounce='" + SFFloat(self.stop1Bounce).XML() + "'"
        if self.stop1ConstantForceMix != 0.001:
            result += " stop1ConstantForceMix='" + SFFloat(self.stop1ConstantForceMix).XML() + "'"
        if self.stop1ErrorCorrection != 0.8:
            result += " stop1ErrorCorrection='" + SFFloat(self.stop1ErrorCorrection).XML() + "'"
        if self.suspensionErrorCorrection != 0.8:
            result += " suspensionErrorCorrection='" + SFFloat(self.suspensionErrorCorrection).XML() + "'"
        if self.suspensionForce != 0:
            result += " suspensionForce='" + SFFloat(self.suspensionForce).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.body1: # output this SFNode
                result += self.body1.XML(indentLevel=indentLevel+1)
            if self.body2: # output this SFNode
                result += self.body2.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</DoubleAxisHingeJoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class EaseInEaseOut(_X3DChildNode):
    """
    EaseInEaseOut enables gradual animation transitions by modifying TimeSensor fraction outputs.
    """
    NAME = 'EaseInEaseOut'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#EaseInEaseOut'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('easeInEaseOut', list(), FieldType.MFVec2f, AccessType.inputOutput, 'EaseInEaseOut'),
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'EaseInEaseOut'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 easeInEaseOut=list(),
                 key=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode EaseInEaseOut __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.easeInEaseOut = easeInEaseOut
        self.key = key
    @property # getter - - - - - - - - - -
    def easeInEaseOut(self):
        """Array of paired values for easeOut fraction and easeIn fraction within each key interval."""
        return self.__easeInEaseOut
    @easeInEaseOut.setter
    def easeInEaseOut(self, easeInEaseOut=None):
        if  easeInEaseOut is None:
            easeInEaseOut = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(easeInEaseOut)
        self.__easeInEaseOut = easeInEaseOut
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to easeInEaseOut array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function EaseInEaseOut.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<EaseInEaseOut'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.easeInEaseOut != list():
            result += " easeInEaseOut='" + MFVec2f(self.easeInEaseOut).XML() + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</EaseInEaseOut>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class EdgeEnhancementVolumeStyle(_X3DComposableVolumeRenderStyleNode):
    """
    EdgeEnhancementVolumeStyle specifies edge enhancement for the volume rendering style.
    """
    NAME = 'EdgeEnhancementVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#EdgeEnhancementVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('edgeColor', (0, 0, 0, 1), FieldType.SFColorRGBA, AccessType.inputOutput, 'EdgeEnhancementVolumeStyle'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('gradientThreshold', 0.4, FieldType.SFFloat, AccessType.inputOutput, 'EdgeEnhancementVolumeStyle'),
        ('surfaceNormals', None, FieldType.SFNode, AccessType.inputOutput, 'EdgeEnhancementVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 edgeColor=(0, 0, 0, 1),
                 enabled=True,
                 gradientThreshold=0.4,
                 surfaceNormals=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode EdgeEnhancementVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.edgeColor = edgeColor
        self.enabled = enabled
        self.gradientThreshold = gradientThreshold
        self.surfaceNormals = surfaceNormals
    @property # getter - - - - - - - - - -
    def edgeColor(self):
        """[0,1] color used to highlight edges."""
        return self.__edgeColor
    @edgeColor.setter
    def edgeColor(self, edgeColor=None):
        if  edgeColor is None:
            edgeColor = SFColorRGBA.DEFAULT_VALUE
        assertValidSFColorRGBA(edgeColor)
        assertZeroToOne('edgeColor', edgeColor)
        self.__edgeColor = edgeColor
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def gradientThreshold(self):
        """[0,1] minimum angle (in radians) away from view-direction vector for surface normal before applying enhancement."""
        return self.__gradientThreshold
    @gradientThreshold.setter
    def gradientThreshold(self, gradientThreshold=None):
        if  gradientThreshold is None:
            gradientThreshold = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(gradientThreshold)
        assertGreaterThanEquals('gradientThreshold', gradientThreshold, 0)
        assertLessThanEquals('gradientThreshold', gradientThreshold, 3.1416)
        self.__gradientThreshold = gradientThreshold
    @property # getter - - - - - - - - - -
    def surfaceNormals(self):
        return self.__surfaceNormals
    @surfaceNormals.setter
    def surfaceNormals(self, surfaceNormals=None):
        if  surfaceNormals is None:
            surfaceNormals = SFNode.DEFAULT_VALUE
        assertValidSFNode(surfaceNormals)
        if not isinstance(surfaceNormals, object):
            # print(flush=True)
            raise X3DTypeError(str(surfaceNormals) + ' does not have a valid node type object')
        self.__surfaceNormals = surfaceNormals
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.surfaceNormals)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function EdgeEnhancementVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<EdgeEnhancementVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.edgeColor != (0, 0, 0, 1):
            result += " edgeColor='" + SFColorRGBA(self.edgeColor).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.gradientThreshold != 0.4:
            result += " gradientThreshold='" + SFFloat(self.gradientThreshold).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.surfaceNormals: # output this SFNode
                result += self.surfaceNormals.XML(indentLevel=indentLevel+1)
            result += indent + '</EdgeEnhancementVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ElevationGrid(_X3DGeometryNode):
    """
    ElevationGrid is a geometry node defining a rectangular height field, with default values for a 1m by 1m square at height 0.
    """
    NAME = 'ElevationGrid'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ElevationGrid'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'ElevationGrid'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'ElevationGrid'),
        ('creaseAngle', 0, FieldType.SFFloat, AccessType.initializeOnly, 'ElevationGrid'),
        ('height', [0, 0, 0, 0], FieldType.MFFloat, AccessType.initializeOnly, 'ElevationGrid'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'ElevationGrid'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'ElevationGrid'),
        ('xDimension', 2, FieldType.SFInt32, AccessType.initializeOnly, 'ElevationGrid'),
        ('xSpacing', 1.0, FieldType.SFFloat, AccessType.initializeOnly, 'ElevationGrid'),
        ('zDimension', 2, FieldType.SFInt32, AccessType.initializeOnly, 'ElevationGrid'),
        ('zSpacing', 1.0, FieldType.SFFloat, AccessType.initializeOnly, 'ElevationGrid'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'ElevationGrid'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'ElevationGrid'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'ElevationGrid'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'ElevationGrid'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'ElevationGrid'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 creaseAngle=0,
                 height=[0, 0, 0, 0],
                 normalPerVertex=True,
                 solid=True,
                 xDimension=2,
                 xSpacing=1.0,
                 zDimension=2,
                 zSpacing=1.0,
                 color=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ElevationGrid __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.creaseAngle = creaseAngle
        self.height = height
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.xDimension = xDimension
        self.xSpacing = xSpacing
        self.zDimension = zDimension
        self.zSpacing = zSpacing
        self.color = color
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color node color values are applied to each point vertex (true) or per quadrilateral (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def creaseAngle(self):
        """[0,+infinity) creaseAngle defines angle (in radians) for determining whether adjacent polygons are drawn with sharp edges or smooth shading."""
        return self.__creaseAngle
    @creaseAngle.setter
    def creaseAngle(self, creaseAngle=None):
        if  creaseAngle is None:
            creaseAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(creaseAngle)
        assertNonNegative('creaseAngle', creaseAngle)
        self.__creaseAngle = creaseAngle
    @property # getter - - - - - - - - - -
    def height(self):
        """Grid array of height vertices with upward direction along +Y axis, with xDimension rows and zDimension columns."""
        return self.__height
    @height.setter
    def height(self, height=None):
        if  height is None:
            height = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(height)
        self.__height = height
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or per quadrilateral (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def xDimension(self):
        """(0,+infinity) Number of elements in the height array along X direction."""
        return self.__xDimension
    @xDimension.setter
    def xDimension(self, xDimension=None):
        if  xDimension is None:
            xDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(xDimension)
        assertNonNegative('xDimension', xDimension)
        self.__xDimension = xDimension
    @property # getter - - - - - - - - - -
    def xSpacing(self):
        """(0,+infinity) Meters distance between grid-array vertices along X direction."""
        return self.__xSpacing
    @xSpacing.setter
    def xSpacing(self, xSpacing=None):
        if  xSpacing is None:
            xSpacing = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(xSpacing)
        assertPositive('xSpacing', xSpacing)
        self.__xSpacing = xSpacing
    @property # getter - - - - - - - - - -
    def zDimension(self):
        """(0,+infinity) Number of elements in the height array along Z direction."""
        return self.__zDimension
    @zDimension.setter
    def zDimension(self, zDimension=None):
        if  zDimension is None:
            zDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(zDimension)
        assertNonNegative('zDimension', zDimension)
        self.__zDimension = zDimension
    @property # getter - - - - - - - - - -
    def zSpacing(self):
        """(0,+infinity) Meters distance between grid-array vertices along Z direction."""
        return self.__zSpacing
    @zSpacing.setter
    def zSpacing(self, zSpacing=None):
        if  zSpacing is None:
            zSpacing = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(zSpacing)
        assertPositive('zSpacing', zSpacing)
        self.__zSpacing = zSpacing
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorPerVertex field."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ElevationGrid.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ElevationGrid'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.creaseAngle != 0:
            result += " creaseAngle='" + SFFloat(self.creaseAngle).XML() + "'"
        if self.height != [0, 0, 0, 0]:
            result += " height='" + MFFloat(self.height).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.xDimension != 2:
            result += " xDimension='" + SFInt32(self.xDimension).XML() + "'"
        if self.xSpacing != 1.0:
            result += " xSpacing='" + SFFloat(self.xSpacing).XML() + "'"
        if self.zDimension != 2:
            result += " zDimension='" + SFInt32(self.zDimension).XML() + "'"
        if self.zSpacing != 1.0:
            result += " zSpacing='" + SFFloat(self.zSpacing).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ElevationGrid>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class EspduTransform(_X3DGroupingNode, _X3DNetworkSensorNode):
    """
    EspduTransform is a networked Transform node that can contain most nodes.
    """
    NAME = 'EspduTransform'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#EspduTransform'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('address', 'localhost', FieldType.SFString, AccessType.inputOutput, 'EspduTransform'),
        ('applicationID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('articulationParameterArray', list(), FieldType.MFFloat, AccessType.inputOutput, 'EspduTransform'),
        ('articulationParameterChangeIndicatorArray', list(), FieldType.MFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('articulationParameterCount', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('articulationParameterDesignatorArray', list(), FieldType.MFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('articulationParameterIdPartAttachedToArray', list(), FieldType.MFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('articulationParameterTypeArray', list(), FieldType.MFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'EspduTransform'),
        ('collisionType', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('deadReckoning', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('detonationLocation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'EspduTransform'),
        ('detonationRelativeLocation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'EspduTransform'),
        ('detonationResult', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'EspduTransform'),
        ('entityCategory', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('entityCountry', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('entityDomain', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('entityExtra', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('entityID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('entityKind', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('entitySpecific', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('entitySubcategory', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('eventApplicationID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('eventEntityID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('eventNumber', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('eventSiteID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('fired1', False, FieldType.SFBool, AccessType.inputOutput, 'EspduTransform'),
        ('fired2', False, FieldType.SFBool, AccessType.inputOutput, 'EspduTransform'),
        ('fireMissionIndex', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('firingRange', 0, FieldType.SFFloat, AccessType.inputOutput, 'EspduTransform'),
        ('firingRate', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('forceID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('fuse', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('geoCoords', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'EspduTransform'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'EspduTransform'),
        ('linearAcceleration', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'EspduTransform'),
        ('linearVelocity', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'EspduTransform'),
        ('marking', '', FieldType.SFString, AccessType.inputOutput, 'EspduTransform'),
        ('multicastRelayHost', '', FieldType.SFString, AccessType.inputOutput, 'EspduTransform'),
        ('multicastRelayPort', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('munitionApplicationID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('munitionEndPoint', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'EspduTransform'),
        ('munitionEntityID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('munitionQuantity', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('munitionSiteID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('munitionStartPoint', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'EspduTransform'),
        ('networkMode', 'standAlone', FieldType.SFString, AccessType.inputOutput, 'EspduTransform'),
        ('port', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('readInterval', 0.1, FieldType.SFTime, AccessType.inputOutput, 'EspduTransform'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'EspduTransform'),
        ('rtpHeaderExpected', False, FieldType.SFBool, AccessType.initializeOnly, 'EspduTransform'),
        ('scale', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'EspduTransform'),
        ('scaleOrientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'EspduTransform'),
        ('siteID', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'EspduTransform'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('warhead', 0, FieldType.SFInt32, AccessType.inputOutput, 'EspduTransform'),
        ('writeInterval', 1.0, FieldType.SFTime, AccessType.inputOutput, 'EspduTransform'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 address='localhost',
                 applicationID=0,
                 articulationParameterArray=list(),
                 articulationParameterChangeIndicatorArray=list(),
                 articulationParameterCount=0,
                 articulationParameterDesignatorArray=list(),
                 articulationParameterIdPartAttachedToArray=list(),
                 articulationParameterTypeArray=list(),
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 center=(0, 0, 0),
                 collisionType=0,
                 deadReckoning=0,
                 detonationLocation=(0, 0, 0),
                 detonationRelativeLocation=(0, 0, 0),
                 detonationResult=0,
                 displayBBox=False,
                 enabled=True,
                 entityCategory=0,
                 entityCountry=0,
                 entityDomain=0,
                 entityExtra=0,
                 entityID=0,
                 entityKind=0,
                 entitySpecific=0,
                 entitySubcategory=0,
                 eventApplicationID=0,
                 eventEntityID=0,
                 eventNumber=0,
                 eventSiteID=0,
                 fired1=False,
                 fired2=False,
                 fireMissionIndex=0,
                 firingRange=0,
                 firingRate=0,
                 forceID=0,
                 fuse=0,
                 geoCoords=(0, 0, 0),
                 geoSystem=["GD", "WE"],
                 linearAcceleration=(0, 0, 0),
                 linearVelocity=(0, 0, 0),
                 marking='',
                 multicastRelayHost='',
                 multicastRelayPort=0,
                 munitionApplicationID=0,
                 munitionEndPoint=(0, 0, 0),
                 munitionEntityID=0,
                 munitionQuantity=0,
                 munitionSiteID=0,
                 munitionStartPoint=(0, 0, 0),
                 networkMode='standAlone',
                 port=0,
                 readInterval=0.1,
                 rotation=(0, 0, 1, 0),
                 rtpHeaderExpected=False,
                 scale=(1, 1, 1),
                 scaleOrientation=(0, 0, 1, 0),
                 siteID=0,
                 translation=(0, 0, 0),
                 visible=True,
                 warhead=0,
                 writeInterval=1.0,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode EspduTransform __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.address = address
        self.applicationID = applicationID
        self.articulationParameterArray = articulationParameterArray
        self.articulationParameterChangeIndicatorArray = articulationParameterChangeIndicatorArray
        self.articulationParameterCount = articulationParameterCount
        self.articulationParameterDesignatorArray = articulationParameterDesignatorArray
        self.articulationParameterIdPartAttachedToArray = articulationParameterIdPartAttachedToArray
        self.articulationParameterTypeArray = articulationParameterTypeArray
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.center = center
        self.collisionType = collisionType
        self.deadReckoning = deadReckoning
        self.detonationLocation = detonationLocation
        self.detonationRelativeLocation = detonationRelativeLocation
        self.detonationResult = detonationResult
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.entityCategory = entityCategory
        self.entityCountry = entityCountry
        self.entityDomain = entityDomain
        self.entityExtra = entityExtra
        self.entityID = entityID
        self.entityKind = entityKind
        self.entitySpecific = entitySpecific
        self.entitySubcategory = entitySubcategory
        self.eventApplicationID = eventApplicationID
        self.eventEntityID = eventEntityID
        self.eventNumber = eventNumber
        self.eventSiteID = eventSiteID
        self.fired1 = fired1
        self.fired2 = fired2
        self.fireMissionIndex = fireMissionIndex
        self.firingRange = firingRange
        self.firingRate = firingRate
        self.forceID = forceID
        self.fuse = fuse
        self.geoCoords = geoCoords
        self.geoSystem = geoSystem
        self.linearAcceleration = linearAcceleration
        self.linearVelocity = linearVelocity
        self.marking = marking
        self.multicastRelayHost = multicastRelayHost
        self.multicastRelayPort = multicastRelayPort
        self.munitionApplicationID = munitionApplicationID
        self.munitionEndPoint = munitionEndPoint
        self.munitionEntityID = munitionEntityID
        self.munitionQuantity = munitionQuantity
        self.munitionSiteID = munitionSiteID
        self.munitionStartPoint = munitionStartPoint
        self.networkMode = networkMode
        self.port = port
        self.readInterval = readInterval
        self.rotation = rotation
        self.rtpHeaderExpected = rtpHeaderExpected
        self.scale = scale
        self.scaleOrientation = scaleOrientation
        self.siteID = siteID
        self.translation = translation
        self.visible = visible
        self.warhead = warhead
        self.writeInterval = writeInterval
        self.children = children
    @property # getter - - - - - - - - - -
    def address(self):
        """Multicast network address, or else "localhost" Example: 224."""
        return self.__address
    @address.setter
    def address(self, address=None):
        if  address is None:
            address = SFString.DEFAULT_VALUE
        assertValidSFString(address)
        self.__address = address
    @property # getter - - - - - - - - - -
    def applicationID(self):
        """Simulation/exercise applicationID is unique for application at that site."""
        return self.__applicationID
    @applicationID.setter
    def applicationID(self, applicationID=None):
        if  applicationID is None:
            applicationID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(applicationID)
        self.__applicationID = applicationID
    @property # getter - - - - - - - - - -
    def articulationParameterArray(self):
        """Information required for representation of the entity's visual appearance and position of its articulated parts."""
        return self.__articulationParameterArray
    @articulationParameterArray.setter
    def articulationParameterArray(self, articulationParameterArray=None):
        if  articulationParameterArray is None:
            articulationParameterArray = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(articulationParameterArray)
        self.__articulationParameterArray = articulationParameterArray
    @property # getter - - - - - - - - - -
    def articulationParameterChangeIndicatorArray(self):
        """Array of change counters, each incremented when an articulated parameter is updated."""
        return self.__articulationParameterChangeIndicatorArray
    @articulationParameterChangeIndicatorArray.setter
    def articulationParameterChangeIndicatorArray(self, articulationParameterChangeIndicatorArray=None):
        if  articulationParameterChangeIndicatorArray is None:
            articulationParameterChangeIndicatorArray = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(articulationParameterChangeIndicatorArray)
        self.__articulationParameterChangeIndicatorArray = articulationParameterChangeIndicatorArray
    @property # getter - - - - - - - - - -
    def articulationParameterCount(self):
        """Number of articulated parameters attached to this entity state PDU."""
        return self.__articulationParameterCount
    @articulationParameterCount.setter
    def articulationParameterCount(self, articulationParameterCount=None):
        if  articulationParameterCount is None:
            articulationParameterCount = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(articulationParameterCount)
        self.__articulationParameterCount = articulationParameterCount
    @property # getter - - - - - - - - - -
    def articulationParameterDesignatorArray(self):
        """Array of designators for each articulated parameter."""
        return self.__articulationParameterDesignatorArray
    @articulationParameterDesignatorArray.setter
    def articulationParameterDesignatorArray(self, articulationParameterDesignatorArray=None):
        if  articulationParameterDesignatorArray is None:
            articulationParameterDesignatorArray = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(articulationParameterDesignatorArray)
        self.__articulationParameterDesignatorArray = articulationParameterDesignatorArray
    @property # getter - - - - - - - - - -
    def articulationParameterIdPartAttachedToArray(self):
        """Array of ID parts that each articulated parameter is attached to."""
        return self.__articulationParameterIdPartAttachedToArray
    @articulationParameterIdPartAttachedToArray.setter
    def articulationParameterIdPartAttachedToArray(self, articulationParameterIdPartAttachedToArray=None):
        if  articulationParameterIdPartAttachedToArray is None:
            articulationParameterIdPartAttachedToArray = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(articulationParameterIdPartAttachedToArray)
        self.__articulationParameterIdPartAttachedToArray = articulationParameterIdPartAttachedToArray
    @property # getter - - - - - - - - - -
    def articulationParameterTypeArray(self):
        """Array of type enumerations for each articulated parameter element."""
        return self.__articulationParameterTypeArray
    @articulationParameterTypeArray.setter
    def articulationParameterTypeArray(self, articulationParameterTypeArray=None):
        if  articulationParameterTypeArray is None:
            articulationParameterTypeArray = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(articulationParameterTypeArray)
        self.__articulationParameterTypeArray = articulationParameterTypeArray
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def center(self):
        """Translation offset from origin of local coordinate system."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def collisionType(self):
        """Integer enumeration for type of collision: ELASTIC or INELASTIC."""
        return self.__collisionType
    @collisionType.setter
    def collisionType(self, collisionType=None):
        if  collisionType is None:
            collisionType = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(collisionType)
        self.__collisionType = collisionType
    @property # getter - - - - - - - - - -
    def deadReckoning(self):
        """Dead reckoning algorithm being used to project position/orientation with velocities/accelerations."""
        return self.__deadReckoning
    @deadReckoning.setter
    def deadReckoning(self, deadReckoning=None):
        if  deadReckoning is None:
            deadReckoning = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(deadReckoning)
        self.__deadReckoning = deadReckoning
    @property # getter - - - - - - - - - -
    def detonationLocation(self):
        """World coordinates for detonationLocation."""
        return self.__detonationLocation
    @detonationLocation.setter
    def detonationLocation(self, detonationLocation=None):
        if  detonationLocation is None:
            detonationLocation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(detonationLocation)
        self.__detonationLocation = detonationLocation
    @property # getter - - - - - - - - - -
    def detonationRelativeLocation(self):
        """Relative coordinates for detonation location."""
        return self.__detonationRelativeLocation
    @detonationRelativeLocation.setter
    def detonationRelativeLocation(self, detonationRelativeLocation=None):
        if  detonationRelativeLocation is None:
            detonationRelativeLocation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(detonationRelativeLocation)
        self.__detonationRelativeLocation = detonationRelativeLocation
    @property # getter - - - - - - - - - -
    def detonationResult(self):
        """Integer enumeration for type of detonation and result that occurred."""
        return self.__detonationResult
    @detonationResult.setter
    def detonationResult(self, detonationResult=None):
        if  detonationResult is None:
            detonationResult = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(detonationResult)
        self.__detonationResult = detonationResult
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables the sensor node."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def entityCategory(self):
        """Integer enumerations value for main category that describes the entity, semantics of each code varies according to domain."""
        return self.__entityCategory
    @entityCategory.setter
    def entityCategory(self, entityCategory=None):
        if  entityCategory is None:
            entityCategory = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entityCategory)
        self.__entityCategory = entityCategory
    @property # getter - - - - - - - - - -
    def entityCountry(self):
        """Integer enumerations value for country to which the design of the entity or its design specification is attributed."""
        return self.__entityCountry
    @entityCountry.setter
    def entityCountry(self, entityCountry=None):
        if  entityCountry is None:
            entityCountry = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entityCountry)
        self.__entityCountry = entityCountry
    @property # getter - - - - - - - - - -
    def entityDomain(self):
        """Integer enumerations value for domain in which the entity operates: LAND, AIR, SURFACE, SUBSURFACE, SPACE or OTHER."""
        return self.__entityDomain
    @entityDomain.setter
    def entityDomain(self, entityDomain=None):
        if  entityDomain is None:
            entityDomain = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entityDomain)
        self.__entityDomain = entityDomain
    @property # getter - - - - - - - - - -
    def entityExtra(self):
        """Any extra information required to describe a particular entity."""
        return self.__entityExtra
    @entityExtra.setter
    def entityExtra(self, entityExtra=None):
        if  entityExtra is None:
            entityExtra = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entityExtra)
        self.__entityExtra = entityExtra
    @property # getter - - - - - - - - - -
    def entityID(self):
        """Simulation/exercise entityID is a unique ID for a single entity within that application."""
        return self.__entityID
    @entityID.setter
    def entityID(self, entityID=None):
        if  entityID is None:
            entityID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entityID)
        self.__entityID = entityID
    @property # getter - - - - - - - - - -
    def entityKind(self):
        """Integer enumerations value for whether entity is a PLATFORM, MUNITION, LIFE_FORM, ENVIRONMENTAL, CULTURAL_FEATURE, SUPPLY, RADIO, EXPENDABLE, SENSOR_EMITTER or OTHER."""
        return self.__entityKind
    @entityKind.setter
    def entityKind(self, entityKind=None):
        if  entityKind is None:
            entityKind = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entityKind)
        self.__entityKind = entityKind
    @property # getter - - - - - - - - - -
    def entitySpecific(self):
        """Specific information about an entity based on the Subcategory field."""
        return self.__entitySpecific
    @entitySpecific.setter
    def entitySpecific(self, entitySpecific=None):
        if  entitySpecific is None:
            entitySpecific = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entitySpecific)
        self.__entitySpecific = entitySpecific
    @property # getter - - - - - - - - - -
    def entitySubcategory(self):
        return self.__entitySubcategory
    @entitySubcategory.setter
    def entitySubcategory(self, entitySubcategory=None):
        if  entitySubcategory is None:
            entitySubcategory = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entitySubcategory)
        self.__entitySubcategory = entitySubcategory
    @property # getter - - - - - - - - - -
    def eventApplicationID(self):
        """Simulation/exercise eventApplicationID is unique for events generated from application at that site."""
        return self.__eventApplicationID
    @eventApplicationID.setter
    def eventApplicationID(self, eventApplicationID=None):
        if  eventApplicationID is None:
            eventApplicationID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(eventApplicationID)
        self.__eventApplicationID = eventApplicationID
    @property # getter - - - - - - - - - -
    def eventEntityID(self):
        """For a given event, simulation/exercise entityID is a unique ID for a single entity within that application."""
        return self.__eventEntityID
    @eventEntityID.setter
    def eventEntityID(self, eventEntityID=None):
        if  eventEntityID is None:
            eventEntityID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(eventEntityID)
        self.__eventEntityID = eventEntityID
    @property # getter - - - - - - - - - -
    def eventNumber(self):
        """Sequential number of each event issued by an application."""
        return self.__eventNumber
    @eventNumber.setter
    def eventNumber(self, eventNumber=None):
        if  eventNumber is None:
            eventNumber = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(eventNumber)
        self.__eventNumber = eventNumber
    @property # getter - - - - - - - - - -
    def eventSiteID(self):
        """Simulation/exercise siteID of the participating LAN or organization."""
        return self.__eventSiteID
    @eventSiteID.setter
    def eventSiteID(self, eventSiteID=None):
        if  eventSiteID is None:
            eventSiteID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(eventSiteID)
        self.__eventSiteID = eventSiteID
    @property # getter - - - - - - - - - -
    def fired1(self):
        """Has the primary weapon (Fire PDU) been fired?."""
        return self.__fired1
    @fired1.setter
    def fired1(self, fired1=None):
        if  fired1 is None:
            fired1 = SFBool.DEFAULT_VALUE
        assertValidSFBool(fired1)
        self.__fired1 = fired1
    @property # getter - - - - - - - - - -
    def fired2(self):
        """Has the secondary weapon (Fire PDU) been fired?."""
        return self.__fired2
    @fired2.setter
    def fired2(self, fired2=None):
        if  fired2 is None:
            fired2 = SFBool.DEFAULT_VALUE
        assertValidSFBool(fired2)
        self.__fired2 = fired2
    @property # getter - - - - - - - - - -
    def fireMissionIndex(self):
        """."""
        return self.__fireMissionIndex
    @fireMissionIndex.setter
    def fireMissionIndex(self, fireMissionIndex=None):
        if  fireMissionIndex is None:
            fireMissionIndex = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(fireMissionIndex)
        self.__fireMissionIndex = fireMissionIndex
    @property # getter - - - - - - - - - -
    def firingRange(self):
        """Range (three dimension, straight-line distance) that the firing entity's fire control system has assumed for computing the fire control solution if a weapon and if the value is known."""
        return self.__firingRange
    @firingRange.setter
    def firingRange(self, firingRange=None):
        if  firingRange is None:
            firingRange = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(firingRange)
        self.__firingRange = firingRange
    @property # getter - - - - - - - - - -
    def firingRate(self):
        """Rate at which munitions are fired."""
        return self.__firingRate
    @firingRate.setter
    def firingRate(self, firingRate=None):
        if  firingRate is None:
            firingRate = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(firingRate)
        self.__firingRate = firingRate
    @property # getter - - - - - - - - - -
    def forceID(self):
        """forceID determines the team membership of the issuing entity, and whether FRIENDLY OPPOSING or NEUTRAL or OTHER."""
        return self.__forceID
    @forceID.setter
    def forceID(self, forceID=None):
        if  forceID is None:
            forceID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(forceID)
        self.__forceID = forceID
    @property # getter - - - - - - - - - -
    def fuse(self):
        """Integer enumerations value for type of fuse on the munition."""
        return self.__fuse
    @fuse.setter
    def fuse(self, fuse=None):
        if  fuse is None:
            fuse = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(fuse)
        self.__fuse = fuse
    @property # getter - - - - - - - - - -
    def geoCoords(self):
        """Geographic location (specified in current geoSystem coordinates) for children geometry (specified in relative coordinate system, in meters)."""
        return self.__geoCoords
    @geoCoords.setter
    def geoCoords(self, geoCoords=None):
        if  geoCoords is None:
            geoCoords = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(geoCoords)
        self.__geoCoords = geoCoords
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def linearAcceleration(self):
        """Acceleration of the entity relative to the rotating Earth in either world or entity coordinates, depending on the dead reckoning algorithm used."""
        return self.__linearAcceleration
    @linearAcceleration.setter
    def linearAcceleration(self, linearAcceleration=None):
        if  linearAcceleration is None:
            linearAcceleration = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(linearAcceleration)
        self.__linearAcceleration = linearAcceleration
    @property # getter - - - - - - - - - -
    def linearVelocity(self):
        """Velocity of the entity relative to the rotating Earth in either world or entity coordinates, depending on the dead reckoning algorithm used."""
        return self.__linearVelocity
    @linearVelocity.setter
    def linearVelocity(self, linearVelocity=None):
        if  linearVelocity is None:
            linearVelocity = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(linearVelocity)
        self.__linearVelocity = linearVelocity
    @property # getter - - - - - - - - - -
    def marking(self):
        """Maximum of 11 characters for simple entity label."""
        return self.__marking
    @marking.setter
    def marking(self, marking=None):
        if  marking is None:
            marking = SFString.DEFAULT_VALUE
        assertValidSFString(marking)
        self.__marking = marking
    @property # getter - - - - - - - - - -
    def multicastRelayHost(self):
        """Fallback server address if multicast not available locally."""
        return self.__multicastRelayHost
    @multicastRelayHost.setter
    def multicastRelayHost(self, multicastRelayHost=None):
        if  multicastRelayHost is None:
            multicastRelayHost = SFString.DEFAULT_VALUE
        assertValidSFString(multicastRelayHost)
        self.__multicastRelayHost = multicastRelayHost
    @property # getter - - - - - - - - - -
    def multicastRelayPort(self):
        """Fallback server port if multicast not available locally."""
        return self.__multicastRelayPort
    @multicastRelayPort.setter
    def multicastRelayPort(self, multicastRelayPort=None):
        if  multicastRelayPort is None:
            multicastRelayPort = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(multicastRelayPort)
        self.__multicastRelayPort = multicastRelayPort
    @property # getter - - - - - - - - - -
    def munitionApplicationID(self):
        """munitionApplicationID, unique for application at that site."""
        return self.__munitionApplicationID
    @munitionApplicationID.setter
    def munitionApplicationID(self, munitionApplicationID=None):
        if  munitionApplicationID is None:
            munitionApplicationID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(munitionApplicationID)
        self.__munitionApplicationID = munitionApplicationID
    @property # getter - - - - - - - - - -
    def munitionEndPoint(self):
        """Final point of the munition path from firing weapon to detonation or impact, in exercise coordinates."""
        return self.__munitionEndPoint
    @munitionEndPoint.setter
    def munitionEndPoint(self, munitionEndPoint=None):
        if  munitionEndPoint is None:
            munitionEndPoint = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(munitionEndPoint)
        self.__munitionEndPoint = munitionEndPoint
    @property # getter - - - - - - - - - -
    def munitionEntityID(self):
        """munitionEntityID is unique ID for entity firing munition within that application."""
        return self.__munitionEntityID
    @munitionEntityID.setter
    def munitionEntityID(self, munitionEntityID=None):
        if  munitionEntityID is None:
            munitionEntityID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(munitionEntityID)
        self.__munitionEntityID = munitionEntityID
    @property # getter - - - - - - - - - -
    def munitionQuantity(self):
        """Quantity of munitions fired."""
        return self.__munitionQuantity
    @munitionQuantity.setter
    def munitionQuantity(self, munitionQuantity=None):
        if  munitionQuantity is None:
            munitionQuantity = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(munitionQuantity)
        self.__munitionQuantity = munitionQuantity
    @property # getter - - - - - - - - - -
    def munitionSiteID(self):
        """Munition siteID of the participating LAN or organization."""
        return self.__munitionSiteID
    @munitionSiteID.setter
    def munitionSiteID(self, munitionSiteID=None):
        if  munitionSiteID is None:
            munitionSiteID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(munitionSiteID)
        self.__munitionSiteID = munitionSiteID
    @property # getter - - - - - - - - - -
    def munitionStartPoint(self):
        """Initial point of the munition path from firing weapon to detonation or impact, in exercise coordinates."""
        return self.__munitionStartPoint
    @munitionStartPoint.setter
    def munitionStartPoint(self, munitionStartPoint=None):
        if  munitionStartPoint is None:
            munitionStartPoint = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(munitionStartPoint)
        self.__munitionStartPoint = munitionStartPoint
    @property # getter - - - - - - - - - -
    def networkMode(self):
        """Whether this entity is ignoring the network, sending DIS packets to the network, or receiving DIS packets from the network."""
        return self.__networkMode
    @networkMode.setter
    def networkMode(self, networkMode=None):
        if  networkMode is None:
            networkMode = SFString.DEFAULT_VALUE
        assertValidSFString(networkMode)
        self.__networkMode = networkMode
    @property # getter - - - - - - - - - -
    def port(self):
        """Network connection port number (EXAMPLE 3000) for sending or receiving DIS messages."""
        return self.__port
    @port.setter
    def port(self, port=None):
        if  port is None:
            port = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(port)
        self.__port = port
    @property # getter - - - - - - - - - -
    def readInterval(self):
        """[0,+infinity) Seconds between read updates, 0 means no reading."""
        return self.__readInterval
    @readInterval.setter
    def readInterval(self, readInterval=None):
        if  readInterval is None:
            readInterval = SFTime.DEFAULT_VALUE
        assertValidSFTime(readInterval)
        assertNonNegative('readInterval', readInterval)
        self.__readInterval = readInterval
    @property # getter - - - - - - - - - -
    def rotation(self):
        """Orientation of children relative to local coordinate system, usually read from (or written to) remote, networked EspduTransform nodes."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def rtpHeaderExpected(self):
        """Whether RTP headers are prepended to DIS PDUs."""
        return self.__rtpHeaderExpected
    @rtpHeaderExpected.setter
    def rtpHeaderExpected(self, rtpHeaderExpected=None):
        if  rtpHeaderExpected is None:
            rtpHeaderExpected = SFBool.DEFAULT_VALUE
        assertValidSFBool(rtpHeaderExpected)
        self.__rtpHeaderExpected = rtpHeaderExpected
    @property # getter - - - - - - - - - -
    def scale(self):
        """Non-uniform x-y-z scale of child coordinate system, adjusted by center and scaleOrientation."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def scaleOrientation(self):
        """Preliminary rotation of coordinate system before scaling (to allow scaling around arbitrary orientations)."""
        return self.__scaleOrientation
    @scaleOrientation.setter
    def scaleOrientation(self, scaleOrientation=None):
        if  scaleOrientation is None:
            scaleOrientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(scaleOrientation)
        self.__scaleOrientation = scaleOrientation
    @property # getter - - - - - - - - - -
    def siteID(self):
        """Simulation/exercise siteID of the participating LAN or organization."""
        return self.__siteID
    @siteID.setter
    def siteID(self, siteID=None):
        if  siteID is None:
            siteID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(siteID)
        self.__siteID = siteID
    @property # getter - - - - - - - - - -
    def translation(self):
        """Position of children relative to local coordinate system, usually read from (or written to) remote, networked EspduTransform nodes."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def warhead(self):
        """Integer enumerations value for type of warhead on the munition."""
        return self.__warhead
    @warhead.setter
    def warhead(self, warhead=None):
        if  warhead is None:
            warhead = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(warhead)
        self.__warhead = warhead
    @property # getter - - - - - - - - - -
    def writeInterval(self):
        """[0,+infinity) Seconds between write updates, 0 means no writing (sending)."""
        return self.__writeInterval
    @writeInterval.setter
    def writeInterval(self, writeInterval=None):
        if  writeInterval is None:
            writeInterval = SFTime.DEFAULT_VALUE
        assertValidSFTime(writeInterval)
        assertNonNegative('writeInterval', writeInterval)
        self.__writeInterval = writeInterval
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function EspduTransform.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<EspduTransform'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.address != 'localhost':
            result += " address='" + self.address + "'"
        if self.applicationID != 0:
            result += " applicationID='" + SFInt32(self.applicationID).XML() + "'"
        if self.articulationParameterArray != list():
            result += " articulationParameterArray='" + MFFloat(self.articulationParameterArray).XML() + "'"
        if self.articulationParameterChangeIndicatorArray != list():
            result += " articulationParameterChangeIndicatorArray='" + MFInt32(self.articulationParameterChangeIndicatorArray).XML() + "'"
        if self.articulationParameterCount != 0:
            result += " articulationParameterCount='" + SFInt32(self.articulationParameterCount).XML() + "'"
        if self.articulationParameterDesignatorArray != list():
            result += " articulationParameterDesignatorArray='" + MFInt32(self.articulationParameterDesignatorArray).XML() + "'"
        if self.articulationParameterIdPartAttachedToArray != list():
            result += " articulationParameterIdPartAttachedToArray='" + MFInt32(self.articulationParameterIdPartAttachedToArray).XML() + "'"
        if self.articulationParameterTypeArray != list():
            result += " articulationParameterTypeArray='" + MFInt32(self.articulationParameterTypeArray).XML() + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.collisionType != 0:
            result += " collisionType='" + SFInt32(self.collisionType).XML() + "'"
        if self.deadReckoning != 0:
            result += " deadReckoning='" + SFInt32(self.deadReckoning).XML() + "'"
        if self.detonationLocation != (0, 0, 0):
            result += " detonationLocation='" + SFVec3f(self.detonationLocation).XML() + "'"
        if self.detonationRelativeLocation != (0, 0, 0):
            result += " detonationRelativeLocation='" + SFVec3f(self.detonationRelativeLocation).XML() + "'"
        if self.detonationResult != 0:
            result += " detonationResult='" + SFInt32(self.detonationResult).XML() + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.entityCategory != 0:
            result += " entityCategory='" + SFInt32(self.entityCategory).XML() + "'"
        if self.entityCountry != 0:
            result += " entityCountry='" + SFInt32(self.entityCountry).XML() + "'"
        if self.entityDomain != 0:
            result += " entityDomain='" + SFInt32(self.entityDomain).XML() + "'"
        if self.entityExtra != 0:
            result += " entityExtra='" + SFInt32(self.entityExtra).XML() + "'"
        if self.entityID != 0:
            result += " entityID='" + SFInt32(self.entityID).XML() + "'"
        if self.entityKind != 0:
            result += " entityKind='" + SFInt32(self.entityKind).XML() + "'"
        if self.entitySpecific != 0:
            result += " entitySpecific='" + SFInt32(self.entitySpecific).XML() + "'"
        if self.entitySubcategory != 0:
            result += " entitySubcategory='" + SFInt32(self.entitySubcategory).XML() + "'"
        if self.eventApplicationID != 0:
            result += " eventApplicationID='" + SFInt32(self.eventApplicationID).XML() + "'"
        if self.eventEntityID != 0:
            result += " eventEntityID='" + SFInt32(self.eventEntityID).XML() + "'"
        if self.eventNumber != 0:
            result += " eventNumber='" + SFInt32(self.eventNumber).XML() + "'"
        if self.eventSiteID != 0:
            result += " eventSiteID='" + SFInt32(self.eventSiteID).XML() + "'"
        if self.fireMissionIndex != 0:
            result += " fireMissionIndex='" + SFInt32(self.fireMissionIndex).XML() + "'"
        if self.fired1 != False:
            result += " fired1='" + SFBool(self.fired1).XML() + "'"
        if self.fired2 != False:
            result += " fired2='" + SFBool(self.fired2).XML() + "'"
        if self.firingRange != 0:
            result += " firingRange='" + SFFloat(self.firingRange).XML() + "'"
        if self.firingRate != 0:
            result += " firingRate='" + SFInt32(self.firingRate).XML() + "'"
        if self.forceID != 0:
            result += " forceID='" + SFInt32(self.forceID).XML() + "'"
        if self.fuse != 0:
            result += " fuse='" + SFInt32(self.fuse).XML() + "'"
        if self.geoCoords != (0, 0, 0):
            result += " geoCoords='" + SFVec3d(self.geoCoords).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.linearAcceleration != (0, 0, 0):
            result += " linearAcceleration='" + SFVec3f(self.linearAcceleration).XML() + "'"
        if self.linearVelocity != (0, 0, 0):
            result += " linearVelocity='" + SFVec3f(self.linearVelocity).XML() + "'"
        if self.marking:
            result += " marking='" + self.marking + "'"
        if self.multicastRelayHost:
            result += " multicastRelayHost='" + self.multicastRelayHost + "'"
        if self.multicastRelayPort != 0:
            result += " multicastRelayPort='" + SFInt32(self.multicastRelayPort).XML() + "'"
        if self.munitionApplicationID != 0:
            result += " munitionApplicationID='" + SFInt32(self.munitionApplicationID).XML() + "'"
        if self.munitionEndPoint != (0, 0, 0):
            result += " munitionEndPoint='" + SFVec3f(self.munitionEndPoint).XML() + "'"
        if self.munitionEntityID != 0:
            result += " munitionEntityID='" + SFInt32(self.munitionEntityID).XML() + "'"
        if self.munitionQuantity != 0:
            result += " munitionQuantity='" + SFInt32(self.munitionQuantity).XML() + "'"
        if self.munitionSiteID != 0:
            result += " munitionSiteID='" + SFInt32(self.munitionSiteID).XML() + "'"
        if self.munitionStartPoint != (0, 0, 0):
            result += " munitionStartPoint='" + SFVec3f(self.munitionStartPoint).XML() + "'"
        if self.networkMode != 'standAlone':
            result += " networkMode='" + self.networkMode + "'"
        if self.port != 0:
            result += " port='" + SFInt32(self.port).XML() + "'"
        if self.readInterval != 0.1:
            result += " readInterval='" + SFTime(self.readInterval).XML() + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.rtpHeaderExpected != False:
            result += " rtpHeaderExpected='" + SFBool(self.rtpHeaderExpected).XML() + "'"
        if self.scale != (1, 1, 1):
            result += " scale='" + SFVec3f(self.scale).XML() + "'"
        if self.scaleOrientation != (0, 0, 1, 0):
            result += " scaleOrientation='" + SFRotation(self.scaleOrientation).XML() + "'"
        if self.siteID != 0:
            result += " siteID='" + SFInt32(self.siteID).XML() + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if self.warhead != 0:
            result += " warhead='" + SFInt32(self.warhead).XML() + "'"
        if self.writeInterval != 1.0:
            result += " writeInterval='" + SFTime(self.writeInterval).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</EspduTransform>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ExplosionEmitter(_X3DParticleEmitterNode):
    """
    ExplosionEmitter generates all particles from a specific point in space at the initial time enabled.
    """
    NAME = 'ExplosionEmitter'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ExplosionEmitter'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('mass', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('position', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'ExplosionEmitter'),
        ('speed', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('surfaceArea', 0, FieldType.SFFloat, AccessType.initializeOnly, 'X3DParticleEmitterNode'),
        ('variation', 0.25, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 mass=0,
                 position=(0, 0, 0),
                 speed=0,
                 surfaceArea=0,
                 variation=0.25,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ExplosionEmitter __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.mass = mass
        self.position = position
        self.speed = speed
        self.surfaceArea = surfaceArea
        self.variation = variation
    @property # getter - - - - - - - - - -
    def mass(self):
        """[0,+infinity) Basic mass of each particle, defined in mass base units (default is kilograms)."""
        return self.__mass
    @mass.setter
    def mass(self, mass=None):
        if  mass is None:
            mass = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(mass)
        assertNonNegative('mass', mass)
        self.__mass = mass
    @property # getter - - - - - - - - - -
    def position(self):
        """Point from which particles emanate."""
        return self.__position
    @position.setter
    def position(self, position=None):
        if  position is None:
            position = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(position)
        self.__position = position
    @property # getter - - - - - - - - - -
    def speed(self):
        """[0,+infinity) Initial linear speed (default is m/s) imparted to all particles along their direction of movement."""
        return self.__speed
    @speed.setter
    def speed(self, speed=None):
        if  speed is None:
            speed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speed)
        assertNonNegative('speed', speed)
        self.__speed = speed
    @property # getter - - - - - - - - - -
    def surfaceArea(self):
        """[0,+infinity) Particle surface area in area base units (default is meters squared)."""
        return self.__surfaceArea
    @surfaceArea.setter
    def surfaceArea(self, surfaceArea=None):
        if  surfaceArea is None:
            surfaceArea = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(surfaceArea)
        assertNonNegative('surfaceArea', surfaceArea)
        self.__surfaceArea = surfaceArea
    @property # getter - - - - - - - - - -
    def variation(self):
        """[0,+infinity) Multiplier for the randomness used to control the range of possible output values."""
        return self.__variation
    @variation.setter
    def variation(self, variation=None):
        if  variation is None:
            variation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(variation)
        assertNonNegative('variation', variation)
        self.__variation = variation
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ExplosionEmitter.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ExplosionEmitter'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.mass != 0:
            result += " mass='" + SFFloat(self.mass).XML() + "'"
        if self.position != (0, 0, 0):
            result += " position='" + SFVec3f(self.position).XML() + "'"
        if self.speed != 0:
            result += " speed='" + SFFloat(self.speed).XML() + "'"
        if self.surfaceArea != 0:
            result += " surfaceArea='" + SFFloat(self.surfaceArea).XML() + "'"
        if self.variation != 0.25:
            result += " variation='" + SFFloat(self.variation).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ExplosionEmitter>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Extrusion(_X3DGeometryNode):
    """
    Extrusion is a geometry node that sequentially stretches a 2D cross section along a 3D-spine path in the local coordinate system, creating an outer hull.
    """
    NAME = 'Extrusion'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Extrusion'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('beginCap', True, FieldType.SFBool, AccessType.initializeOnly, 'Extrusion'),
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'Extrusion'),
        ('convex', True, FieldType.SFBool, AccessType.initializeOnly, 'Extrusion'),
        ('creaseAngle', 0.0, FieldType.SFFloat, AccessType.initializeOnly, 'Extrusion'),
        ('crossSection', [(1, 1, 1, -1, -1, -1, -1, 1, 1, 1)], FieldType.MFVec2f, AccessType.initializeOnly, 'Extrusion'),
        ('endCap', True, FieldType.SFBool, AccessType.initializeOnly, 'Extrusion'),
        ('orientation', [(0, 0, 1, 0)], FieldType.MFRotation, AccessType.inputOutput, 'Extrusion'),
        ('scale', [(1, 1)], FieldType.MFVec2f, AccessType.inputOutput, 'Extrusion'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'Extrusion'),
        ('spine', [(0, 0, 0, 0, 1, 0)], FieldType.MFVec3f, AccessType.initializeOnly, 'Extrusion'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 beginCap=True,
                 ccw=True,
                 convex=True,
                 creaseAngle=0.0,
                 crossSection=[(1, 1, 1, -1, -1, -1, -1, 1, 1, 1)],
                 endCap=True,
                 orientation=[(0, 0, 1, 0)],
                 scale=[(1, 1)],
                 solid=True,
                 spine=[(0, 0, 0, 0, 1, 0)],
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Extrusion __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.beginCap = beginCap
        self.ccw = ccw
        self.convex = convex
        self.creaseAngle = creaseAngle
        self.crossSection = crossSection
        self.endCap = endCap
        self.orientation = orientation
        self.scale = scale
        self.solid = solid
        self.spine = spine
    @property # getter - - - - - - - - - -
    def beginCap(self):
        """Whether beginning cap is drawn (similar to Cylinder top cap)."""
        return self.__beginCap
    @beginCap.setter
    def beginCap(self, beginCap=None):
        if  beginCap is None:
            beginCap = SFBool.DEFAULT_VALUE
        assertValidSFBool(beginCap)
        self.__beginCap = beginCap
    @property # getter - - - - - - - - - -
    def ccw(self):
        """The ccw field indicates counterclockwise ordering of vertex-coordinates orientation."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def convex(self):
        """The convex field is a hint to renderers whether all polygons in a shape are convex (true), or possibly concave (false)."""
        return self.__convex
    @convex.setter
    def convex(self, convex=None):
        if  convex is None:
            convex = SFBool.DEFAULT_VALUE
        assertValidSFBool(convex)
        self.__convex = convex
    @property # getter - - - - - - - - - -
    def creaseAngle(self):
        """[0,+infinity) creaseAngle defines angle (in radians) where adjacent polygons are drawn with sharp edges or smooth shading."""
        return self.__creaseAngle
    @creaseAngle.setter
    def creaseAngle(self, creaseAngle=None):
        if  creaseAngle is None:
            creaseAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(creaseAngle)
        assertNonNegative('creaseAngle', creaseAngle)
        self.__creaseAngle = creaseAngle
    @property # getter - - - - - - - - - -
    def crossSection(self):
        """The crossSection array defines a silhouette outline of the outer Extrusion surface."""
        return self.__crossSection
    @crossSection.setter
    def crossSection(self, crossSection=None):
        if  crossSection is None:
            crossSection = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(crossSection)
        self.__crossSection = crossSection
    @property # getter - - - - - - - - - -
    def endCap(self):
        """Whether end cap is drawn (similar to Cylinder bottom cap)."""
        return self.__endCap
    @endCap.setter
    def endCap(self, endCap=None):
        if  endCap is None:
            endCap = SFBool.DEFAULT_VALUE
        assertValidSFBool(endCap)
        self.__endCap = endCap
    @property # getter - - - - - - - - - -
    def orientation(self):
        """The orientation array is a list of axis-angle 4-tuple values applied at each spine-aligned cross-section plane."""
        return self.__orientation
    @orientation.setter
    def orientation(self, orientation=None):
        if  orientation is None:
            orientation = MFRotation.DEFAULT_VALUE
        assertValidMFRotation(orientation)
        self.__orientation = orientation
    @property # getter - - - - - - - - - -
    def scale(self):
        """(0,+infinity) scale is a list of 2D-scale parameters applied at each spine-aligned cross-section plane."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def spine(self):
        """The spine array defines a center-line sequence of 3D points that define a piecewise-linear curve forming a series of connected vertices."""
        return self.__spine
    @spine.setter
    def spine(self, spine=None):
        if  spine is None:
            spine = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(spine)
        self.__spine = spine
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Extrusion.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Extrusion'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.beginCap != True:
            result += " beginCap='" + SFBool(self.beginCap).XML() + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.convex != True:
            result += " convex='" + SFBool(self.convex).XML() + "'"
        if self.creaseAngle != 0.0:
            result += " creaseAngle='" + SFFloat(self.creaseAngle).XML() + "'"
        if self.crossSection != [(1, 1, 1, -1, -1, -1, -1, 1, 1, 1)]:
            result += " crossSection='" + MFVec2f(self.crossSection).XML() + "'"
        if self.endCap != True:
            result += " endCap='" + SFBool(self.endCap).XML() + "'"
        if self.orientation != [(0, 0, 1, 0)]:
            result += " orientation='" + MFRotation(self.orientation).XML() + "'"
        if self.scale != [(1, 1)]:
            result += " scale='" + MFVec2f(self.scale).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.spine != [(0, 0, 0, 0, 1, 0)]:
            result += " spine='" + MFVec3f(self.spine).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Extrusion>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class FillProperties(_X3DAppearanceChildNode):
    """
    FillProperties indicates whether appearance is filled or hatched for associated geometry nodes inside the same Shape.
    """
    NAME = 'FillProperties'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#FillProperties'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('filled', True, FieldType.SFBool, AccessType.inputOutput, 'FillProperties'),
        ('hatchColor', (1, 1, 1), FieldType.SFColor, AccessType.inputOutput, 'FillProperties'),
        ('hatched', True, FieldType.SFBool, AccessType.inputOutput, 'FillProperties'),
        ('hatchStyle', 1, FieldType.SFInt32, AccessType.inputOutput, 'FillProperties'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 filled=True,
                 hatchColor=(1, 1, 1),
                 hatched=True,
                 hatchStyle=1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode FillProperties __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.filled = filled
        self.hatchColor = hatchColor
        self.hatched = hatched
        self.hatchStyle = hatchStyle
    @property # getter - - - - - - - - - -
    def filled(self):
        """Whether or not associated geometry is filled."""
        return self.__filled
    @filled.setter
    def filled(self, filled=None):
        if  filled is None:
            filled = SFBool.DEFAULT_VALUE
        assertValidSFBool(filled)
        self.__filled = filled
    @property # getter - - - - - - - - - -
    def hatchColor(self):
        """[0,1] Color of the hatch pattern."""
        return self.__hatchColor
    @hatchColor.setter
    def hatchColor(self, hatchColor=None):
        if  hatchColor is None:
            hatchColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(hatchColor)
        assertZeroToOne('hatchColor', hatchColor)
        self.__hatchColor = hatchColor
    @property # getter - - - - - - - - - -
    def hatched(self):
        """Whether or not associated geometry is hatched."""
        return self.__hatched
    @hatched.setter
    def hatched(self, hatched=None):
        if  hatched is None:
            hatched = SFBool.DEFAULT_VALUE
        assertValidSFBool(hatched)
        self.__hatched = hatched
    @property # getter - - - - - - - - - -
    def hatchStyle(self):
        """hatchStyle selects a hatch pattern from International Register of Graphical Items."""
        return self.__hatchStyle
    @hatchStyle.setter
    def hatchStyle(self, hatchStyle=None):
        if  hatchStyle is None:
            hatchStyle = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(hatchStyle)
        self.__hatchStyle = hatchStyle
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function FillProperties.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<FillProperties'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.filled != True:
            result += " filled='" + SFBool(self.filled).XML() + "'"
        if self.hatchColor != (1, 1, 1):
            result += " hatchColor='" + SFColor(self.hatchColor).XML() + "'"
        if self.hatchStyle != 1:
            result += " hatchStyle='" + SFInt32(self.hatchStyle).XML() + "'"
        if self.hatched != True:
            result += " hatched='" + SFBool(self.hatched).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</FillProperties>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class FloatVertexAttribute(_X3DVertexAttributeNode):
    """
    FloatVertexAttribute defines a set of per-vertex single-precision floating-point attributes.
    """
    NAME = 'FloatVertexAttribute'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#FloatVertexAttribute'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DVertexAttributeNode'),
        ('numComponents', 4, FieldType.SFInt32, AccessType.initializeOnly, 'FloatVertexAttribute'),
        ('value', list(), FieldType.MFFloat, AccessType.inputOutput, 'FloatVertexAttribute'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 name='',
                 numComponents=4,
                 value=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode FloatVertexAttribute __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.numComponents = numComponents
        self.value = value
    @property # getter - - - - - - - - - -
    def name(self):
        """Required name for this particular VertexAttribute instance."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def numComponents(self):
        """numComponents pecifies how many consecutive floating-point values should be grouped together per vertex."""
        return self.__numComponents
    @numComponents.setter
    def numComponents(self, numComponents=None):
        if  numComponents is None:
            numComponents = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(numComponents)
        assertGreaterThanEquals('numComponents', numComponents, 1)
        assertLessThanEquals('numComponents', numComponents, 4)
        self.__numComponents = numComponents
    @property # getter - - - - - - - - - -
    def value(self):
        """value specifies an arbitrary collection of floating-point values that will be passed to the shader as per-vertex information."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(value)
        self.__value = value
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function FloatVertexAttribute.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<FloatVertexAttribute'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.numComponents != 4:
            result += " numComponents='" + SFInt32(self.numComponents).XML() + "'"
        if self.value != list():
            result += " value='" + MFFloat(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</FloatVertexAttribute>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Fog(_X3DBindableNode, _X3DFogObject):
    """
    Fog simulates atmospheric effects by blending distant objects with fog color.
    """
    NAME = 'Fog'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Fog'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('color', (1, 1, 1), FieldType.SFColor, AccessType.inputOutput, 'X3DFogObject'),
        ('fogType', 'LINEAR', FieldType.SFString, AccessType.inputOutput, 'X3DFogObject'),
        ('visibilityRange', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DFogObject'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 color=(1, 1, 1),
                 fogType='LINEAR',
                 visibilityRange=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Fog __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.color = color
        self.fogType = fogType
        self.visibilityRange = visibilityRange
    @property # getter - - - - - - - - - -
    def color(self):
        """[0,1] Fog color."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFColor.DEFAULT_VALUE
        assertValidSFColor(color)
        assertZeroToOne('color', color)
        self.__color = color
    @property # getter - - - - - - - - - -
    def fogType(self):
        """Specifies algorithm for rate of increasing Fog, either LINEAR or EXPONENTIAL."""
        return self.__fogType
    @fogType.setter
    def fogType(self, fogType=None):
        if  fogType is None:
            fogType = SFString.DEFAULT_VALUE
        assertValidSFString(fogType)
        self.__fogType = fogType
    @property # getter - - - - - - - - - -
    def visibilityRange(self):
        """Distance in meters where objects are totally obscured by the fog, using local coordinate system."""
        return self.__visibilityRange
    @visibilityRange.setter
    def visibilityRange(self, visibilityRange=None):
        if  visibilityRange is None:
            visibilityRange = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(visibilityRange)
        assertNonNegative('visibilityRange', visibilityRange)
        self.__visibilityRange = visibilityRange
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Fog.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Fog'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.color != (1, 1, 1):
            result += " color='" + SFColor(self.color).XML() + "'"
        if self.fogType != 'LINEAR':
            result += " fogType='" + self.fogType + "'"
        if self.visibilityRange != 0:
            result += " visibilityRange='" + SFFloat(self.visibilityRange).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Fog>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class FogCoordinate(_X3DGeometricPropertyNode):
    """
    FogCoordinate defines a set of explicit fog depths on a per-vertex basis, overriding Fog visibilityRange.
    """
    NAME = 'FogCoordinate'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#FogCoordinate'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('depth', list(), FieldType.MFFloat, AccessType.inputOutput, 'FogCoordinate'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 depth=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode FogCoordinate __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.depth = depth
    @property # getter - - - - - - - - - -
    def depth(self):
        """depth contains a set of 3D coordinate (triplet) point values."""
        return self.__depth
    @depth.setter
    def depth(self, depth=None):
        if  depth is None:
            depth = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(depth)
        assertZeroToOne('depth', depth)
        self.__depth = depth
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function FogCoordinate.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<FogCoordinate'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.depth != list():
            result += " depth='" + MFFloat(self.depth).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</FogCoordinate>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class FontStyle(_X3DFontStyleNode):
    """
    FontStyle is an X3DFontStyleNode that defines the size, family, justification, and other styles used by Text nodes.
    """
    NAME = 'FontStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#FontStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('family', ["SERIF"], FieldType.MFString, AccessType.initializeOnly, 'FontStyle'),
        ('horizontal', True, FieldType.SFBool, AccessType.initializeOnly, 'FontStyle'),
        ('justify', ["BEGIN"], FieldType.MFString, AccessType.initializeOnly, 'FontStyle'),
        ('language', '', FieldType.SFString, AccessType.initializeOnly, 'FontStyle'),
        ('leftToRight', True, FieldType.SFBool, AccessType.initializeOnly, 'FontStyle'),
        ('size', 1.0, FieldType.SFFloat, AccessType.initializeOnly, 'FontStyle'),
        ('spacing', 1.0, FieldType.SFFloat, AccessType.initializeOnly, 'FontStyle'),
        ('style', 'PLAIN', FieldType.SFString, AccessType.initializeOnly, 'FontStyle'),
        ('topToBottom', True, FieldType.SFBool, AccessType.initializeOnly, 'FontStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 family=["SERIF"],
                 horizontal=True,
                 justify=["BEGIN"],
                 language='',
                 leftToRight=True,
                 size=1.0,
                 spacing=1.0,
                 style='PLAIN',
                 topToBottom=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode FontStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.family = family
        self.horizontal = horizontal
        self.justify = justify
        self.language = language
        self.leftToRight = leftToRight
        self.size = size
        self.spacing = spacing
        self.style = style
        self.topToBottom = topToBottom
    @property # getter - - - - - - - - - -
    def family(self):
        """Array of quoted font family names in preference order, browsers use the first supported family."""
        return self.__family
    @family.setter
    def family(self, family=None):
        if  family is None:
            family = MFString.DEFAULT_VALUE
        assertValidMFString(family)
        self.__family = family
    @property # getter - - - - - - - - - -
    def horizontal(self):
        """Whether text direction is horizontal (true) or vertical (false)."""
        return self.__horizontal
    @horizontal.setter
    def horizontal(self, horizontal=None):
        if  horizontal is None:
            horizontal = SFBool.DEFAULT_VALUE
        assertValidSFBool(horizontal)
        self.__horizontal = horizontal
    @property # getter - - - - - - - - - -
    def justify(self):
        """The justify field determines alignment of the above text layout relative to the origin of the object coordinate system."""
        return self.__justify
    @justify.setter
    def justify(self, justify=None):
        if  justify is None:
            justify = MFString.DEFAULT_VALUE
        assertValidMFString(justify)
        self.__justify = justify
    @property # getter - - - - - - - - - -
    def language(self):
        """Language codes consist of a primary code and a (possibly empty) series of subcodes."""
        return self.__language
    @language.setter
    def language(self, language=None):
        if  language is None:
            language = SFString.DEFAULT_VALUE
        assertValidSFString(language)
        self.__language = language
    @property # getter - - - - - - - - - -
    def leftToRight(self):
        return self.__leftToRight
    @leftToRight.setter
    def leftToRight(self, leftToRight=None):
        if  leftToRight is None:
            leftToRight = SFBool.DEFAULT_VALUE
        assertValidSFBool(leftToRight)
        self.__leftToRight = leftToRight
    @property # getter - - - - - - - - - -
    def size(self):
        """(0,+infinity) Nominal height (in local coordinate system) of text glyphs Also sets default spacing between adjacent lines of text."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(size)
        assertPositive('size', size)
        self.__size = size
    @property # getter - - - - - - - - - -
    def spacing(self):
        """[0,+infinity) Adjustment factor for line spacing between adjacent lines of text."""
        return self.__spacing
    @spacing.setter
    def spacing(self, spacing=None):
        if  spacing is None:
            spacing = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(spacing)
        assertNonNegative('spacing', spacing)
        self.__spacing = spacing
    @property # getter - - - - - - - - - -
    def style(self):
        """Pick one of four values for text style."""
        return self.__style
    @style.setter
    def style(self, style=None):
        if  style is None:
            style = SFString.DEFAULT_VALUE
        assertValidSFString(style)
        self.__style = style
    @property # getter - - - - - - - - - -
    def topToBottom(self):
        """Whether text direction is top-to-bottom (true) or bottom-to-top (false)."""
        return self.__topToBottom
    @topToBottom.setter
    def topToBottom(self, topToBottom=None):
        if  topToBottom is None:
            topToBottom = SFBool.DEFAULT_VALUE
        assertValidSFBool(topToBottom)
        self.__topToBottom = topToBottom
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function FontStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<FontStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.family != ["SERIF"]:
            result += " family='" + MFString(self.family).XML() + "'"
        if self.horizontal != True:
            result += " horizontal='" + SFBool(self.horizontal).XML() + "'"
        if self.justify != ["BEGIN"]:
            result += " justify='" + MFString(self.justify).XML() + "'"
        if self.language:
            result += " language='" + self.language + "'"
        if self.leftToRight != True:
            result += " leftToRight='" + SFBool(self.leftToRight).XML() + "'"
        if self.size != 1.0:
            result += " size='" + SFFloat(self.size).XML() + "'"
        if self.spacing != 1.0:
            result += " spacing='" + SFFloat(self.spacing).XML() + "'"
        if self.style != 'PLAIN':
            result += " style='" + self.style + "'"
        if self.topToBottom != True:
            result += " topToBottom='" + SFBool(self.topToBottom).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</FontStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ForcePhysicsModel(_X3DParticlePhysicsModelNode):
    """
    ForcePhysicsModel applies a constant force value to the particles.
    """
    NAME = 'ForcePhysicsModel'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ForcePhysicsModel'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DParticlePhysicsModelNode'),
        ('force', (0, -9.8, 0), FieldType.SFVec3f, AccessType.inputOutput, 'ForcePhysicsModel'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 force=(0, -9.8, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ForcePhysicsModel __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.force = force
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def force(self):
        """(-infinity,+infinity) force field indicates strength and direction of the propelling force on the particles (e."""
        return self.__force
    @force.setter
    def force(self, force=None):
        if  force is None:
            force = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(force)
        self.__force = force
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ForcePhysicsModel.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ForcePhysicsModel'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.force != (0, -9.8, 0):
            result += " force='" + SFVec3f(self.force).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ForcePhysicsModel>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeneratedCubeMapTexture(_X3DEnvironmentTextureNode):
    """
    GeneratedCubeMapTexture is a texture node that defines a cubic environment map that sources its data from internally generated images.
    """
    NAME = 'GeneratedCubeMapTexture'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeneratedCubeMapTexture'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('size', 128, FieldType.SFInt32, AccessType.initializeOnly, 'GeneratedCubeMapTexture'),
        ('update', 'NONE', FieldType.SFString, AccessType.inputOutput, 'GeneratedCubeMapTexture'),
        ('textureProperties', None, FieldType.SFNode, AccessType.initializeOnly, 'GeneratedCubeMapTexture'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 size=128,
                 update='NONE',
                 textureProperties=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeneratedCubeMapTexture __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.size = size
        self.update = update
        self.textureProperties = textureProperties
    @property # getter - - - - - - - - - -
    def size(self):
        """(0,+infinity) size indicates the resolution of the generated images in number of pixels per side."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(size)
        assertPositive('size', size)
        self.__size = size
    @property # getter - - - - - - - - - -
    def update(self):
        """update controls regeneration of the texture."""
        return self.__update
    @update.setter
    def update(self, update=None):
        if  update is None:
            update = SFString.DEFAULT_VALUE
        assertValidSFString(update)
        self.__update = update
    @property # getter - - - - - - - - - -
    def textureProperties(self):
        return self.__textureProperties
    @textureProperties.setter
    def textureProperties(self, textureProperties=None):
        if  textureProperties is None:
            textureProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(textureProperties)
        if not isinstance(textureProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(textureProperties) + ' does not have a valid node type object')
        self.__textureProperties = textureProperties
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.textureProperties)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeneratedCubeMapTexture.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeneratedCubeMapTexture'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.size != 128:
            result += " size='" + SFInt32(self.size).XML() + "'"
        if self.update != 'NONE':
            result += " update='" + self.update + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.textureProperties: # output this SFNode
                result += self.textureProperties.XML(indentLevel=indentLevel+1)
            result += indent + '</GeneratedCubeMapTexture>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoCoordinate(_X3DCoordinateNode):
    """
    GeoCoordinate builds geometry as a set of geographic 3D coordinates.
    """
    NAME = 'GeoCoordinate'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoCoordinate'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoCoordinate'),
        ('point', list(), FieldType.MFVec3d, AccessType.inputOutput, 'GeoCoordinate'),
        ('geoOrigin', None, FieldType.SFNode, AccessType.initializeOnly, 'GeoCoordinate'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 geoSystem=["GD", "WE"],
                 point=list(),
                 geoOrigin=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoCoordinate __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.geoSystem = geoSystem
        self.point = point
        self.geoOrigin = geoOrigin
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def point(self):
        """point contains a set of actual 3D geographic coordinates, provided in geoSystem format can split strings if desired: "x1 y1 z1 x2 y2 z2" or "x1 y1 z1", "x2 y2 z2"."""
        return self.__point
    @point.setter
    def point(self, point=None):
        if  point is None:
            point = MFVec3d.DEFAULT_VALUE
        assertValidMFVec3d(point)
        self.__point = point
    @property # getter - - - - - - - - - -
    def geoOrigin(self):
        return self.__geoOrigin
    @geoOrigin.setter
    def geoOrigin(self, geoOrigin=None):
        if  geoOrigin is None:
            geoOrigin = SFNode.DEFAULT_VALUE
        assertValidSFNode(geoOrigin)
        if not isinstance(geoOrigin, object):
            # print(flush=True)
            raise X3DTypeError(str(geoOrigin) + ' does not have a valid node type object')
        self.__geoOrigin = geoOrigin
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.geoOrigin) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoCoordinate.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoCoordinate'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.point != list():
            result += " point='" + MFVec3d(self.point).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.geoOrigin: # output this SFNode
                result += self.geoOrigin.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoCoordinate>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoElevationGrid(_X3DGeometryNode):
    """
    GeoElevationGrid is a geometry node defining a rectangular height field, with default values for a 1m by 1m square at height 0.
    """
    NAME = 'GeoElevationGrid'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoElevationGrid'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('creaseAngle', 0, FieldType.SFDouble, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('geoGridOrigin', (0, 0, 0), FieldType.SFVec3d, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('height', [0, 0, 0, 0], FieldType.MFDouble, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('xDimension', 2, FieldType.SFInt32, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('xSpacing', 1.0, FieldType.SFDouble, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('yScale', 1, FieldType.SFFloat, AccessType.inputOutput, 'GeoElevationGrid'),
        ('zDimension', 2, FieldType.SFInt32, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('zSpacing', 1.0, FieldType.SFDouble, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'GeoElevationGrid'),
        ('geoOrigin', None, FieldType.SFNode, AccessType.initializeOnly, 'GeoElevationGrid'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'GeoElevationGrid'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'GeoElevationGrid'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 creaseAngle=0,
                 geoGridOrigin=(0, 0, 0),
                 geoSystem=["GD", "WE"],
                 height=[0, 0, 0, 0],
                 normalPerVertex=True,
                 solid=True,
                 xDimension=2,
                 xSpacing=1.0,
                 yScale=1,
                 zDimension=2,
                 zSpacing=1.0,
                 color=None,
                 geoOrigin=None,
                 normal=None,
                 texCoord=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoElevationGrid __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.creaseAngle = creaseAngle
        self.geoGridOrigin = geoGridOrigin
        self.geoSystem = geoSystem
        self.height = height
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.xDimension = xDimension
        self.xSpacing = xSpacing
        self.yScale = yScale
        self.zDimension = zDimension
        self.zSpacing = zSpacing
        self.color = color
        self.geoOrigin = geoOrigin
        self.normal = normal
        self.texCoord = texCoord
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color node color values are applied to each point vertex (true) or per quadrilateral (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def creaseAngle(self):
        """(0,+infinity) creaseAngle defines angle (in radians) for determining whether adjacent polygons are drawn with sharp edges or smooth shading."""
        return self.__creaseAngle
    @creaseAngle.setter
    def creaseAngle(self, creaseAngle=None):
        if  creaseAngle is None:
            creaseAngle = SFDouble.DEFAULT_VALUE
        assertValidSFDouble(creaseAngle)
        assertNonNegative('creaseAngle', creaseAngle)
        self.__creaseAngle = creaseAngle
    @property # getter - - - - - - - - - -
    def geoGridOrigin(self):
        """Geographic coordinate for southwest (lower-left) corner of height dataset."""
        return self.__geoGridOrigin
    @geoGridOrigin.setter
    def geoGridOrigin(self, geoGridOrigin=None):
        if  geoGridOrigin is None:
            geoGridOrigin = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(geoGridOrigin)
        self.__geoGridOrigin = geoGridOrigin
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def height(self):
        """Contains xDimension rows * zDimension columns floating-point values for elevation above ellipsoid."""
        return self.__height
    @height.setter
    def height(self, height=None):
        if  height is None:
            height = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(height)
        self.__height = height
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or per quadrilateral (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def xDimension(self):
        """(0,+infinity) Number of elements in the height array along east-west X direction."""
        return self.__xDimension
    @xDimension.setter
    def xDimension(self, xDimension=None):
        if  xDimension is None:
            xDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(xDimension)
        assertNonNegative('xDimension', xDimension)
        self.__xDimension = xDimension
    @property # getter - - - - - - - - - -
    def xSpacing(self):
        """(0,+infinity) Distance between grid-array vertices along east-west X direction."""
        return self.__xSpacing
    @xSpacing.setter
    def xSpacing(self, xSpacing=None):
        if  xSpacing is None:
            xSpacing = SFDouble.DEFAULT_VALUE
        assertValidSFDouble(xSpacing)
        assertPositive('xSpacing', xSpacing)
        self.__xSpacing = xSpacing
    @property # getter - - - - - - - - - -
    def yScale(self):
        """[0,+infinity) Vertical exaggeration of displayed data produced from the height array."""
        return self.__yScale
    @yScale.setter
    def yScale(self, yScale=None):
        if  yScale is None:
            yScale = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(yScale)
        assertNonNegative('yScale', yScale)
        self.__yScale = yScale
    @property # getter - - - - - - - - - -
    def zDimension(self):
        """(0,+infinity) Number of elements in the height array along north-south Z direction."""
        return self.__zDimension
    @zDimension.setter
    def zDimension(self, zDimension=None):
        if  zDimension is None:
            zDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(zDimension)
        assertNonNegative('zDimension', zDimension)
        self.__zDimension = zDimension
    @property # getter - - - - - - - - - -
    def zSpacing(self):
        """(0,+infinity) Distance between grid-array vertices along north-south Z direction."""
        return self.__zSpacing
    @zSpacing.setter
    def zSpacing(self, zSpacing=None):
        if  zSpacing is None:
            zSpacing = SFDouble.DEFAULT_VALUE
        assertValidSFDouble(zSpacing)
        assertPositive('zSpacing', zSpacing)
        self.__zSpacing = zSpacing
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorPerVertex field."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def geoOrigin(self):
        return self.__geoOrigin
    @geoOrigin.setter
    def geoOrigin(self, geoOrigin=None):
        if  geoOrigin is None:
            geoOrigin = SFNode.DEFAULT_VALUE
        assertValidSFNode(geoOrigin)
        if not isinstance(geoOrigin, object):
            # print(flush=True)
            raise X3DTypeError(str(geoOrigin) + ' does not have a valid node type object')
        self.__geoOrigin = geoOrigin
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.color) or bool(self.geoOrigin) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoElevationGrid.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoElevationGrid'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.creaseAngle != 0:
            result += " creaseAngle='" + SFDouble(self.creaseAngle).XML() + "'"
        if self.geoGridOrigin != (0, 0, 0):
            result += " geoGridOrigin='" + SFVec3d(self.geoGridOrigin).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.height != [0, 0, 0, 0]:
            result += " height='" + MFDouble(self.height).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.xDimension != 2:
            result += " xDimension='" + SFInt32(self.xDimension).XML() + "'"
        if self.xSpacing != 1.0:
            result += " xSpacing='" + SFDouble(self.xSpacing).XML() + "'"
        if self.yScale != 1:
            result += " yScale='" + SFFloat(self.yScale).XML() + "'"
        if self.zDimension != 2:
            result += " zDimension='" + SFInt32(self.zDimension).XML() + "'"
        if self.zSpacing != 1.0:
            result += " zSpacing='" + SFDouble(self.zSpacing).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.geoOrigin: # output this SFNode
                result += self.geoOrigin.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoElevationGrid>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoLocation(_X3DGroupingNode):
    """
    GeoLocation positions a regular X3D model onto earth's surface.
    """
    NAME = 'GeoLocation'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoLocation'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('geoCoords', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'GeoLocation'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoLocation'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('geoOrigin', None, FieldType.SFNode, AccessType.initializeOnly, 'GeoLocation'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 geoCoords=(0, 0, 0),
                 geoSystem=["GD", "WE"],
                 visible=True,
                 geoOrigin=None,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoLocation __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.geoCoords = geoCoords
        self.geoSystem = geoSystem
        self.visible = visible
        self.geoOrigin = geoOrigin
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def geoCoords(self):
        """Geographic location (specified in current geoSystem coordinates) for children geometry (specified in relative coordinate system, in meters)."""
        return self.__geoCoords
    @geoCoords.setter
    def geoCoords(self, geoCoords=None):
        if  geoCoords is None:
            geoCoords = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(geoCoords)
        self.__geoCoords = geoCoords
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def geoOrigin(self):
        return self.__geoOrigin
    @geoOrigin.setter
    def geoOrigin(self, geoOrigin=None):
        if  geoOrigin is None:
            geoOrigin = SFNode.DEFAULT_VALUE
        assertValidSFNode(geoOrigin)
        if not isinstance(geoOrigin, object):
            # print(flush=True)
            raise X3DTypeError(str(geoOrigin) + ' does not have a valid node type object')
        self.__geoOrigin = geoOrigin
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.geoOrigin) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoLocation.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoLocation'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.geoCoords != (0, 0, 0):
            result += " geoCoords='" + SFVec3d(self.geoCoords).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.geoOrigin: # output this SFNode
                result += self.geoOrigin.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoLocation>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoLOD(_X3DChildNode, _X3DBoundedObject):
    """
    Note that MFNode rootNode field can contain multiple nodes and has accessType inputOutput. Meanwhile MFNode children field is outputOnly, unlike other X3DGroupingNode exemplars.
    """
    NAME = 'GeoLOD'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoLOD'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('center', (0, 0, 0), FieldType.SFVec3d, AccessType.initializeOnly, 'GeoLOD'),
        ('child1Url', list(), FieldType.MFString, AccessType.initializeOnly, 'GeoLOD'),
        ('child2Url', list(), FieldType.MFString, AccessType.initializeOnly, 'GeoLOD'),
        ('child3Url', list(), FieldType.MFString, AccessType.initializeOnly, 'GeoLOD'),
        ('child4Url', list(), FieldType.MFString, AccessType.initializeOnly, 'GeoLOD'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoLOD'),
        ('range', 10, FieldType.SFFloat, AccessType.initializeOnly, 'GeoLOD'),
        ('rootUrl', list(), FieldType.MFString, AccessType.initializeOnly, 'GeoLOD'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('geoOrigin', None, FieldType.SFNode, AccessType.initializeOnly, 'GeoLOD'),
        ('rootNode', list(), FieldType.MFNode, AccessType.initializeOnly, 'GeoLOD'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 center=(0, 0, 0),
                 child1Url=list(),
                 child2Url=list(),
                 child3Url=list(),
                 child4Url=list(),
                 displayBBox=False,
                 geoSystem=["GD", "WE"],
                 range=10,
                 rootUrl=list(),
                 visible=True,
                 geoOrigin=None,
                 rootNode=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoLOD __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.center = center
        self.child1Url = child1Url
        self.child2Url = child2Url
        self.child3Url = child3Url
        self.child4Url = child4Url
        self.displayBBox = displayBBox
        self.geoSystem = geoSystem
        self.range = range
        self.rootUrl = rootUrl
        self.visible = visible
        self.geoOrigin = geoOrigin
        self.rootNode = rootNode
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def center(self):
        """Viewer range from geographic-coordinates center triggers quadtree loading/unloading."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def child1Url(self):
        """quadtree geometry loaded when viewer is within range."""
        return self.__child1Url
    @child1Url.setter
    def child1Url(self, child1Url=None):
        if  child1Url is None:
            child1Url = MFString.DEFAULT_VALUE
        assertValidMFString(child1Url)
        self.__child1Url = child1Url
    @property # getter - - - - - - - - - -
    def child2Url(self):
        """quadtree geometry loaded when viewer is within range."""
        return self.__child2Url
    @child2Url.setter
    def child2Url(self, child2Url=None):
        if  child2Url is None:
            child2Url = MFString.DEFAULT_VALUE
        assertValidMFString(child2Url)
        self.__child2Url = child2Url
    @property # getter - - - - - - - - - -
    def child3Url(self):
        """quadtree geometry loaded when viewer is within range."""
        return self.__child3Url
    @child3Url.setter
    def child3Url(self, child3Url=None):
        if  child3Url is None:
            child3Url = MFString.DEFAULT_VALUE
        assertValidMFString(child3Url)
        self.__child3Url = child3Url
    @property # getter - - - - - - - - - -
    def child4Url(self):
        """quadtree geometry loaded when viewer is within range."""
        return self.__child4Url
    @child4Url.setter
    def child4Url(self, child4Url=None):
        if  child4Url is None:
            child4Url = MFString.DEFAULT_VALUE
        assertValidMFString(child4Url)
        self.__child4Url = child4Url
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def range(self):
        """(0,+infinity) Viewer range from geographic-coordinates center triggers quadtree loading/unloading."""
        return self.__range
    @range.setter
    def range(self, range=None):
        if  range is None:
            range = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(range)
        assertNonNegative('range', range)
        self.__range = range
    @property # getter - - - - - - - - - -
    def rootUrl(self):
        """url for scene providing geometry for the root tile."""
        return self.__rootUrl
    @rootUrl.setter
    def rootUrl(self, rootUrl=None):
        if  rootUrl is None:
            rootUrl = MFString.DEFAULT_VALUE
        assertValidMFString(rootUrl)
        self.__rootUrl = rootUrl
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def geoOrigin(self):
        return self.__geoOrigin
    @geoOrigin.setter
    def geoOrigin(self, geoOrigin=None):
        if  geoOrigin is None:
            geoOrigin = SFNode.DEFAULT_VALUE
        assertValidSFNode(geoOrigin)
        if not isinstance(geoOrigin, object):
            # print(flush=True)
            raise X3DTypeError(str(geoOrigin) + ' does not have a valid node type object')
        self.__geoOrigin = geoOrigin
    @property # getter - - - - - - - - - -
    def rootNode(self):
        """Geometry for the root tile."""
        return self.__rootNode
    @rootNode.setter
    def rootNode(self, rootNode=None):
        if  rootNode is None:
            rootNode = MFNode.DEFAULT_VALUE
        assertValidMFNode(rootNode)
        self.__rootNode = rootNode
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.rootNode) or bool(self.geoOrigin) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoLOD.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoLOD'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3d(self.center).XML() + "'"
        if self.child1Url != list():
            result += " child1Url='" + MFString(self.child1Url).XML() + "'"
        if self.child2Url != list():
            result += " child2Url='" + MFString(self.child2Url).XML() + "'"
        if self.child3Url != list():
            result += " child3Url='" + MFString(self.child3Url).XML() + "'"
        if self.child4Url != list():
            result += " child4Url='" + MFString(self.child4Url).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.range != 10:
            result += " range='" + SFFloat(self.range).XML() + "'"
        if self.rootUrl != list():
            result += " rootUrl='" + MFString(self.rootUrl).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.geoOrigin: # output this SFNode
                result += self.geoOrigin.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.rootNode: # walk each child node, if any
                for each in self.rootNode:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoLOD>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoMetadata(_X3DInfoNode, _X3DUrlObject):
    """
    GeoMetadata includes a generic subset of metadata about the geographic data.
    """
    NAME = 'GeoMetadata'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoMetadata'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('summary', list(), FieldType.MFString, AccessType.inputOutput, 'GeoMetadata'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('data', list(), FieldType.MFNode, AccessType.inputOutput, 'GeoMetadata'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 summary=list(),
                 url=list(),
                 data=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoMetadata __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.summary = summary
        self.url = url
        self.data = data
    @property # getter - - - - - - - - - -
    def summary(self):
        """The summary string array contains a set of keyword/value pairs, with each keyword and its subsequent value contained in separate strings."""
        return self.__summary
    @summary.setter
    def summary(self, summary=None):
        if  summary is None:
            summary = MFString.DEFAULT_VALUE
        assertValidMFString(summary)
        self.__summary = summary
    @property # getter - - - - - - - - - -
    def url(self):
        """Hypertext link to an external, complete metadata description."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def data(self):
        """DEF list of all nodes that implement this data."""
        return self.__data
    @data.setter
    def data(self, data=None):
        if  data is None:
            data = MFNode.DEFAULT_VALUE
        assertValidMFNode(data)
        self.__data = data
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.data) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoMetadata.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoMetadata'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.summary != list():
            result += " summary='" + MFString(self.summary).XML() + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.data: # walk each child node, if any
                for each in self.data:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoMetadata>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoOrigin(_X3DNode):
    """
    GeoOrigin is deprecated and discouraged (but nevertheless allowed) in X3D version 3.3. GeoOrigin is restored in X3D version 4.0 for special use on devices with limited floating-point resolution.
    """
    NAME = 'GeoOrigin'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoOrigin'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('geoCoords', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'GeoOrigin'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoOrigin'),
        ('rotateYUp', False, FieldType.SFBool, AccessType.initializeOnly, 'GeoOrigin'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 geoCoords=(0, 0, 0),
                 geoSystem=["GD", "WE"],
                 rotateYUp=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoOrigin __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.geoCoords = geoCoords
        self.geoSystem = geoSystem
        self.rotateYUp = rotateYUp
    @property # getter - - - - - - - - - -
    def geoCoords(self):
        """Defines absolute geographic location (and implicit local coordinate frame)."""
        return self.__geoCoords
    @geoCoords.setter
    def geoCoords(self, geoCoords=None):
        if  geoCoords is None:
            geoCoords = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(geoCoords)
        self.__geoCoords = geoCoords
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def rotateYUp(self):
        """Whether to rotate coordinates of nodes using this GeoOrigin so that local-up direction aligns with VRML Y axis rotateYUp false means local up-direction is relative to planet surface rotateYUp true allows proper operation of NavigationInfo modes FLY, WALK."""
        return self.__rotateYUp
    @rotateYUp.setter
    def rotateYUp(self, rotateYUp=None):
        if  rotateYUp is None:
            rotateYUp = SFBool.DEFAULT_VALUE
        assertValidSFBool(rotateYUp)
        self.__rotateYUp = rotateYUp
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoOrigin.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoOrigin'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.geoCoords != (0, 0, 0):
            result += " geoCoords='" + SFVec3d(self.geoCoords).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.rotateYUp != False:
            result += " rotateYUp='" + SFBool(self.rotateYUp).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoOrigin>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoPositionInterpolator(_X3DInterpolatorNode):
    """
    GeoPositionInterpolator animates objects within a geographic coordinate system.
    """
    NAME = 'GeoPositionInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoPositionInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoPositionInterpolator'),
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFVec3d, AccessType.inputOutput, 'GeoPositionInterpolator'),
        ('geoOrigin', None, FieldType.SFNode, AccessType.initializeOnly, 'GeoPositionInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 geoSystem=["GD", "WE"],
                 key=list(),
                 keyValue=list(),
                 geoOrigin=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoPositionInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.geoSystem = geoSystem
        self.key = key
        self.keyValue = keyValue
        self.geoOrigin = geoOrigin
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFVec3d.DEFAULT_VALUE
        assertValidMFVec3d(keyValue)
        self.__keyValue = keyValue
    @property # getter - - - - - - - - - -
    def geoOrigin(self):
        return self.__geoOrigin
    @geoOrigin.setter
    def geoOrigin(self, geoOrigin=None):
        if  geoOrigin is None:
            geoOrigin = SFNode.DEFAULT_VALUE
        assertValidSFNode(geoOrigin)
        if not isinstance(geoOrigin, object):
            # print(flush=True)
            raise X3DTypeError(str(geoOrigin) + ' does not have a valid node type object')
        self.__geoOrigin = geoOrigin
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.geoOrigin) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoPositionInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoPositionInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFVec3d(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.geoOrigin: # output this SFNode
                result += self.geoOrigin.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoPositionInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoProximitySensor(_X3DEnvironmentalSensorNode):
    """
    GeoProximitySensor generates events when the viewer enters, exits and moves within a region of space (defined by a box).
    """
    NAME = 'GeoProximitySensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoProximitySensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('center', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'GeoProximitySensor'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('geoCenter', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'GeoProximitySensor'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoProximitySensor'),
        ('size', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DEnvironmentalSensorNode'),
        ('geoOrigin', None, FieldType.SFNode, AccessType.initializeOnly, 'GeoProximitySensor'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 center=(0, 0, 0),
                 enabled=True,
                 geoCenter=(0, 0, 0),
                 geoSystem=["GD", "WE"],
                 size=(0, 0, 0),
                 geoOrigin=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoProximitySensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.center = center
        self.enabled = enabled
        self.geoCenter = geoCenter
        self.geoSystem = geoSystem
        self.size = size
        self.geoOrigin = geoOrigin
    @property # getter - - - - - - - - - -
    def center(self):
        """(starting with v3."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def geoCenter(self):
        """(deprecated as of v3."""
        return self.__geoCenter
    @geoCenter.setter
    def geoCenter(self, geoCenter=None):
        if  geoCenter is None:
            geoCenter = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(geoCenter)
        self.__geoCenter = geoCenter
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def size(self):
        """[0,+infinity) size of Proximity box."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(size)
        assertNonNegative('size', size)
        self.__size = size
    @property # getter - - - - - - - - - -
    def geoOrigin(self):
        return self.__geoOrigin
    @geoOrigin.setter
    def geoOrigin(self, geoOrigin=None):
        if  geoOrigin is None:
            geoOrigin = SFNode.DEFAULT_VALUE
        assertValidSFNode(geoOrigin)
        if not isinstance(geoOrigin, object):
            # print(flush=True)
            raise X3DTypeError(str(geoOrigin) + ' does not have a valid node type object')
        self.__geoOrigin = geoOrigin
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.geoOrigin) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoProximitySensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoProximitySensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3d(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.geoCenter != (0, 0, 0):
            result += " geoCenter='" + SFVec3d(self.geoCenter).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.size != (0, 0, 0):
            result += " size='" + SFVec3f(self.size).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.geoOrigin: # output this SFNode
                result += self.geoOrigin.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoProximitySensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoTouchSensor(_X3DTouchSensorNode):
    """
    GeoTouchSensor returns geographic coordinates for the object being selected.
    """
    NAME = 'GeoTouchSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoTouchSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DPointingDeviceSensorNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoTouchSensor'),
        ('geoOrigin', None, FieldType.SFNode, AccessType.initializeOnly, 'GeoTouchSensor'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 description='',
                 enabled=True,
                 geoSystem=["GD", "WE"],
                 geoOrigin=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoTouchSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.description = description
        self.enabled = enabled
        self.geoSystem = geoSystem
        self.geoOrigin = geoOrigin
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (G D), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def geoOrigin(self):
        return self.__geoOrigin
    @geoOrigin.setter
    def geoOrigin(self, geoOrigin=None):
        if  geoOrigin is None:
            geoOrigin = SFNode.DEFAULT_VALUE
        assertValidSFNode(geoOrigin)
        if not isinstance(geoOrigin, object):
            # print(flush=True)
            raise X3DTypeError(str(geoOrigin) + ' does not have a valid node type object')
        self.__geoOrigin = geoOrigin
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.geoOrigin) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoTouchSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoTouchSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.geoOrigin: # output this SFNode
                result += self.geoOrigin.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoTouchSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoTransform(_X3DGroupingNode):
    """
    GeoTransform is a Grouping node that can contain most nodes.
    """
    NAME = 'GeoTransform'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoTransform'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('geoCenter', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'GeoTransform'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoTransform'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'GeoTransform'),
        ('scale', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'GeoTransform'),
        ('scaleOrientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'GeoTransform'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'GeoTransform'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('geoOrigin', None, FieldType.SFNode, AccessType.initializeOnly, 'GeoTransform'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 geoCenter=(0, 0, 0),
                 geoSystem=["GD", "WE"],
                 rotation=(0, 0, 1, 0),
                 scale=(1, 1, 1),
                 scaleOrientation=(0, 0, 1, 0),
                 translation=(0, 0, 0),
                 visible=True,
                 geoOrigin=None,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoTransform __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.geoCenter = geoCenter
        self.geoSystem = geoSystem
        self.rotation = rotation
        self.scale = scale
        self.scaleOrientation = scaleOrientation
        self.translation = translation
        self.visible = visible
        self.geoOrigin = geoOrigin
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def geoCenter(self):
        """Translation offset from origin of local coordinate system, applied prior to rotation or scaling."""
        return self.__geoCenter
    @geoCenter.setter
    def geoCenter(self, geoCenter=None):
        if  geoCenter is None:
            geoCenter = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(geoCenter)
        self.__geoCenter = geoCenter
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def rotation(self):
        """Orientation (axis, angle in radians) of children relative to local coordinate system."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def scale(self):
        """Non-uniform x-y-z scale of child coordinate system, adjusted by center and scaleOrientation."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(scale)
        assertPositive('scale', scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def scaleOrientation(self):
        """Preliminary rotation of coordinate sys tem before scaling (to allow scaling around arbitrary orientations)."""
        return self.__scaleOrientation
    @scaleOrientation.setter
    def scaleOrientation(self, scaleOrientation=None):
        if  scaleOrientation is None:
            scaleOrientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(scaleOrientation)
        self.__scaleOrientation = scaleOrientation
    @property # getter - - - - - - - - - -
    def translation(self):
        """Position (x, y, z in meters) of children relative to local coordinate system."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def geoOrigin(self):
        return self.__geoOrigin
    @geoOrigin.setter
    def geoOrigin(self, geoOrigin=None):
        if  geoOrigin is None:
            geoOrigin = SFNode.DEFAULT_VALUE
        assertValidSFNode(geoOrigin)
        if not isinstance(geoOrigin, object):
            # print(flush=True)
            raise X3DTypeError(str(geoOrigin) + ' does not have a valid node type object')
        self.__geoOrigin = geoOrigin
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.geoOrigin) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoTransform.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoTransform'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.geoCenter != (0, 0, 0):
            result += " geoCenter='" + SFVec3d(self.geoCenter).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.scale != (1, 1, 1):
            result += " scale='" + SFVec3f(self.scale).XML() + "'"
        if self.scaleOrientation != (0, 0, 1, 0):
            result += " scaleOrientation='" + SFRotation(self.scaleOrientation).XML() + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.geoOrigin: # output this SFNode
                result += self.geoOrigin.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoTransform>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class GeoViewpoint(_X3DViewpointNode):
    """
    GeoViewpoint specifies viewpoints using geographic coordinates.
    """
    NAME = 'GeoViewpoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#GeoViewpoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('centerOfRotation', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'GeoViewpoint'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DViewpointNode'),
        ('fieldOfView', 0.7854, FieldType.SFFloat, AccessType.inputOutput, 'GeoViewpoint'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'GeoViewpoint'),
        ('jump', True, FieldType.SFBool, AccessType.inputOutput, 'X3DViewpointNode'),
        ('orientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'X3DViewpointNode'),
        ('position', (0, 0, 100000), FieldType.SFVec3d, AccessType.inputOutput, 'GeoViewpoint'),
        ('retainUserOffsets', False, FieldType.SFBool, AccessType.inputOutput, 'X3DViewpointNode'),
        ('speedFactor', 1.0, FieldType.SFFloat, AccessType.initializeOnly, 'GeoViewpoint'),
        ('geoOrigin', None, FieldType.SFNode, AccessType.initializeOnly, 'GeoViewpoint'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 centerOfRotation=(0, 0, 0),
                 description='',
                 fieldOfView=0.7854,
                 geoSystem=["GD", "WE"],
                 jump=True,
                 orientation=(0, 0, 1, 0),
                 position=(0, 0, 100000),
                 retainUserOffsets=False,
                 speedFactor=1.0,
                 geoOrigin=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode GeoViewpoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.centerOfRotation = centerOfRotation
        self.description = description
        self.fieldOfView = fieldOfView
        self.geoSystem = geoSystem
        self.jump = jump
        self.orientation = orientation
        self.position = position
        self.retainUserOffsets = retainUserOffsets
        self.speedFactor = speedFactor
        self.geoOrigin = geoOrigin
    @property # getter - - - - - - - - - -
    def centerOfRotation(self):
        """centerOfRotation specifies center point about which to rotate user's eyepoint when in EXAMINE or LOOKAT mode."""
        return self.__centerOfRotation
    @centerOfRotation.setter
    def centerOfRotation(self, centerOfRotation=None):
        if  centerOfRotation is None:
            centerOfRotation = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(centerOfRotation)
        self.__centerOfRotation = centerOfRotation
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def fieldOfView(self):
        """Preferred minimum viewing angle from this viewpoint in radians, providing minimum height or minimum width (whichever is smaller)."""
        return self.__fieldOfView
    @fieldOfView.setter
    def fieldOfView(self, fieldOfView=None):
        if  fieldOfView is None:
            fieldOfView = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(fieldOfView)
        assertGreaterThan('fieldOfView', fieldOfView, 0)
        assertLessThan('fieldOfView', fieldOfView, 3.1416)
        self.__fieldOfView = fieldOfView
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def jump(self):
        """Whether to transition instantly by jumping, or else smoothly animate to this Viewpoint."""
        return self.__jump
    @jump.setter
    def jump(self, jump=None):
        if  jump is None:
            jump = SFBool.DEFAULT_VALUE
        assertValidSFBool(jump)
        self.__jump = jump
    @property # getter - - - - - - - - - -
    def orientation(self):
        """Rotation of Viewpoint, relative to default -Z axis direction in local coordinate system."""
        return self.__orientation
    @orientation.setter
    def orientation(self, orientation=None):
        if  orientation is None:
            orientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(orientation)
        self.__orientation = orientation
    @property # getter - - - - - - - - - -
    def position(self):
        """position relative to local georeferenced coordinate system, in proper format."""
        return self.__position
    @position.setter
    def position(self, position=None):
        if  position is None:
            position = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(position)
        self.__position = position
    @property # getter - - - - - - - - - -
    def retainUserOffsets(self):
        """Retain (true) or reset to zero (false) any prior user navigation offsets from defined viewpoint position, orientation."""
        return self.__retainUserOffsets
    @retainUserOffsets.setter
    def retainUserOffsets(self, retainUserOffsets=None):
        if  retainUserOffsets is None:
            retainUserOffsets = SFBool.DEFAULT_VALUE
        assertValidSFBool(retainUserOffsets)
        self.__retainUserOffsets = retainUserOffsets
    @property # getter - - - - - - - - - -
    def speedFactor(self):
        """[0,+infinity) speedFactor is a multiplier to modify the original elevation-based speed that is set automatically by the browser."""
        return self.__speedFactor
    @speedFactor.setter
    def speedFactor(self, speedFactor=None):
        if  speedFactor is None:
            speedFactor = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speedFactor)
        assertNonNegative('speedFactor', speedFactor)
        self.__speedFactor = speedFactor
    @property # getter - - - - - - - - - -
    def geoOrigin(self):
        return self.__geoOrigin
    @geoOrigin.setter
    def geoOrigin(self, geoOrigin=None):
        if  geoOrigin is None:
            geoOrigin = SFNode.DEFAULT_VALUE
        assertValidSFNode(geoOrigin)
        if not isinstance(geoOrigin, object):
            # print(flush=True)
            raise X3DTypeError(str(geoOrigin) + ' does not have a valid node type object')
        self.__geoOrigin = geoOrigin
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.geoOrigin) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function GeoViewpoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<GeoViewpoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.centerOfRotation != (0, 0, 0):
            result += " centerOfRotation='" + SFVec3d(self.centerOfRotation).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.fieldOfView != 0.7854:
            result += " fieldOfView='" + SFFloat(self.fieldOfView).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.jump != True:
            result += " jump='" + SFBool(self.jump).XML() + "'"
        if self.orientation != (0, 0, 1, 0):
            result += " orientation='" + SFRotation(self.orientation).XML() + "'"
        if self.position != (0, 0, 100000):
            result += " position='" + SFVec3d(self.position).XML() + "'"
        if self.retainUserOffsets != False:
            result += " retainUserOffsets='" + SFBool(self.retainUserOffsets).XML() + "'"
        if self.speedFactor != 1.0:
            result += " speedFactor='" + SFFloat(self.speedFactor).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.geoOrigin: # output this SFNode
                result += self.geoOrigin.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</GeoViewpoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Group(_X3DGroupingNode):
    """
    Group is a Grouping node that can contain most nodes.
    """
    NAME = 'Group'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Group'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Group __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Group.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Group'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Group>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class HAnimDisplacer(_X3DGeometricPropertyNode):
    """
    HAnimDisplacer nodes alter the shape of coordinate-based geometry within parent HAnimJoint or HAnimSegment nodes.
    """
    NAME = 'HAnimDisplacer'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#HAnimDisplacer'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('coordIndex', list(), FieldType.MFInt32, AccessType.initializeOnly, 'HAnimDisplacer'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'HAnimDisplacer'),
        ('displacements', list(), FieldType.MFVec3f, AccessType.inputOutput, 'HAnimDisplacer'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'HAnimDisplacer'),
        ('weight', 0.0, FieldType.SFFloat, AccessType.inputOutput, 'HAnimDisplacer'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 coordIndex=list(),
                 description='',
                 displacements=list(),
                 name='',
                 weight=0.0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode HAnimDisplacer __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.coordIndex = coordIndex
        self.description = description
        self.displacements = displacements
        self.name = name
        self.weight = weight
    @property # getter - - - - - - - - - -
    def coordIndex(self):
        """[0,+infinity) Defines index values into the parent HAnimSegment or HAnimBody/HAnimHumanoid coordinate array for the mesh of vertices affected by this HAnimDisplacer."""
        return self.__coordIndex
    @coordIndex.setter
    def coordIndex(self, coordIndex=None):
        if  coordIndex is None:
            coordIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(coordIndex)
        assertNonNegative('coordIndex', coordIndex)
        self.__coordIndex = coordIndex
    @property # getter - - - - - - - - - -
    def description(self):
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def displacements(self):
        """displacements are a set of SFVec3f values added to neutral/resting position of each of the corresponding HAnimSegment vertices (or HAnimJoint/HAnimHumanoid vertices) referenced by coordIndex field."""
        return self.__displacements
    @displacements.setter
    def displacements(self, displacements=None):
        if  displacements is None:
            displacements = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(displacements)
        self.__displacements = displacements
    @property # getter - - - - - - - - - -
    def name(self):
        """Unique name attribute must be defined so that HAnimDisplacer node can be identified at run time for animation purposes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def weight(self):
        """The weigh factor has typical range [0,1] and defines the scale factor applied to displacement values before adding them to neutral vertex positions."""
        return self.__weight
    @weight.setter
    def weight(self, weight=None):
        if  weight is None:
            weight = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(weight)
        self.__weight = weight
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function HAnimDisplacer.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<HAnimDisplacer'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.coordIndex != list():
            result += " coordIndex='" + MFInt32(self.coordIndex).XML() + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.displacements != list():
            result += " displacements='" + MFVec3f(self.displacements).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.weight != 0.0:
            result += " weight='" + SFFloat(self.weight).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</HAnimDisplacer>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class HAnimHumanoid(_X3DChildNode, _X3DBoundedObject):
    """
    The HAnimHumanoid node is used to: (a) store references to the joints, segments, sites, skeleton, optional skin, and fixed viewpoints, (b) serve as a container for the entire humanoid, (c) provide a convenient way of moving the humanoid through its environment, and (d) store human-readable metadata such as name, version, author, copyright, age, gender and other information.
    """
    NAME = 'HAnimHumanoid'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#HAnimHumanoid'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimHumanoid'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'HAnimHumanoid'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('info', list(), FieldType.MFString, AccessType.inputOutput, 'HAnimHumanoid'),
        ('jointBindingPositions', [(0, 0, 0)], FieldType.MFVec3f, AccessType.inputOutput, 'HAnimHumanoid'),
        ('jointBindingRotations', [(0, 0, 1, 0)], FieldType.MFRotation, AccessType.inputOutput, 'HAnimHumanoid'),
        ('jointBindingScales', [(0, 0, 0)], FieldType.MFVec3f, AccessType.inputOutput, 'HAnimHumanoid'),
        ('loa', -1, FieldType.SFInt32, AccessType.inputOutput, 'HAnimHumanoid'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'HAnimHumanoid'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'HAnimHumanoid'),
        ('scale', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimHumanoid'),
        ('scaleOrientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'HAnimHumanoid'),
        ('skeletalConfiguration', 'BASIC', FieldType.SFString, AccessType.inputOutput, 'HAnimHumanoid'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimHumanoid'),
        ('version', '2.0', FieldType.SFString, AccessType.inputOutput, 'HAnimHumanoid'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('skinBindingCoords', None, FieldType.SFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('skinBindingNormals', None, FieldType.SFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('skinCoord', None, FieldType.SFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('skinNormal', None, FieldType.SFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('joints', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('motions', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('segments', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('sites', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('skeleton', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('skin', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('viewpoints', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimHumanoid'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 center=(0, 0, 0),
                 description='',
                 displayBBox=False,
                 info=list(),
                 jointBindingPositions=[(0, 0, 0)],
                 jointBindingRotations=[(0, 0, 1, 0)],
                 jointBindingScales=[(0, 0, 0)],
                 loa=-1,
                 name='',
                 rotation=(0, 0, 1, 0),
                 scale=(1, 1, 1),
                 scaleOrientation=(0, 0, 1, 0),
                 skeletalConfiguration='BASIC',
                 translation=(0, 0, 0),
                 version='2.0',
                 visible=True,
                 skinBindingCoords=None,
                 skinBindingNormals=None,
                 skinCoord=None,
                 skinNormal=None,
                 joints=list(),
                 motions=list(),
                 segments=list(),
                 sites=list(),
                 skeleton=list(),
                 skin=list(),
                 viewpoints=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode HAnimHumanoid __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.center = center
        self.description = description
        self.displayBBox = displayBBox
        self.info = info
        self.jointBindingPositions = jointBindingPositions
        self.jointBindingRotations = jointBindingRotations
        self.jointBindingScales = jointBindingScales
        self.loa = loa
        self.name = name
        self.rotation = rotation
        self.scale = scale
        self.scaleOrientation = scaleOrientation
        self.skeletalConfiguration = skeletalConfiguration
        self.translation = translation
        self.version = version
        self.visible = visible
        self.skinBindingCoords = skinBindingCoords
        self.skinBindingNormals = skinBindingNormals
        self.skinCoord = skinCoord
        self.skinNormal = skinNormal
        self.joints = joints
        self.motions = motions
        self.segments = segments
        self.sites = sites
        self.skeleton = skeleton
        self.skin = skin
        self.viewpoints = viewpoints
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def center(self):
        """Translation offset from origin of local coordinate system."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def description(self):
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def info(self):
        """Contains metadata keyword=value pairs, where approved keyword terms are humanoidVersion authorName authorEmail copyright creationDate usageRestrictions age gender height and weight."""
        return self.__info
    @info.setter
    def info(self, info=None):
        if  info is None:
            info = MFString.DEFAULT_VALUE
        assertValidMFString(info)
        self.__info = info
    @property # getter - - - - - - - - - -
    def jointBindingPositions(self):
        """Specifies an array of position values for each HAnimJoint node in the joints field, in order, corresponding to each binding pose."""
        return self.__jointBindingPositions
    @jointBindingPositions.setter
    def jointBindingPositions(self, jointBindingPositions=None):
        if  jointBindingPositions is None:
            jointBindingPositions = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(jointBindingPositions)
        self.__jointBindingPositions = jointBindingPositions
    @property # getter - - - - - - - - - -
    def jointBindingRotations(self):
        """Specifies an array of rotation values for each HAnimJoint node in the joints field, in order, corresponding to each binding pose."""
        return self.__jointBindingRotations
    @jointBindingRotations.setter
    def jointBindingRotations(self, jointBindingRotations=None):
        if  jointBindingRotations is None:
            jointBindingRotations = MFRotation.DEFAULT_VALUE
        assertValidMFRotation(jointBindingRotations)
        self.__jointBindingRotations = jointBindingRotations
    @property # getter - - - - - - - - - -
    def jointBindingScales(self):
        """Specifies an array of scale values for each HAnimJoint node in the joints field, in order, corresponding to each binding pose."""
        return self.__jointBindingScales
    @jointBindingScales.setter
    def jointBindingScales(self, jointBindingScales=None):
        if  jointBindingScales is None:
            jointBindingScales = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(jointBindingScales)
        self.__jointBindingScales = jointBindingScales
    @property # getter - - - - - - - - - -
    def loa(self):
        """[-1,4] Level Of Articulation 0."""
        return self.__loa
    @loa.setter
    def loa(self, loa=None):
        if  loa is None:
            loa = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(loa)
        assertGreaterThanEquals('loa', loa, -1)
        assertLessThanEquals('loa', loa, 4)
        self.__loa = loa
    @property # getter - - - - - - - - - -
    def name(self):
        """Unique name attribute must be defined so that each HAnimHumanoid node in a scene can be identified at run time for animation purposes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def rotation(self):
        """Orientation of children relative to local coordinate system."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def scale(self):
        """Non-uniform x-y-z scale of child coordinate system, adjusted by center and scaleOrientation."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(scale)
        assertPositive('scale', scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def scaleOrientation(self):
        """Preliminary rotation of coordinate system before scaling (to allow scaling around arbitrary orientations)."""
        return self.__scaleOrientation
    @scaleOrientation.setter
    def scaleOrientation(self, scaleOrientation=None):
        if  scaleOrientation is None:
            scaleOrientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(scaleOrientation)
        self.__scaleOrientation = scaleOrientation
    @property # getter - - - - - - - - - -
    def skeletalConfiguration(self):
        """Models sharing a common skeletal configuration can share animations and binding poses."""
        return self.__skeletalConfiguration
    @skeletalConfiguration.setter
    def skeletalConfiguration(self, skeletalConfiguration=None):
        if  skeletalConfiguration is None:
            skeletalConfiguration = SFString.DEFAULT_VALUE
        assertValidSFString(skeletalConfiguration)
        self.__skeletalConfiguration = skeletalConfiguration
    @property # getter - - - - - - - - - -
    def translation(self):
        """Position of children relative to local coordinate system."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    @property # getter - - - - - - - - - -
    def version(self):
        """HAnimHumanoid version, where value is 2."""
        return self.__version
    @version.setter
    def version(self, version=None):
        if  version is None:
            version = SFString.DEFAULT_VALUE
        assertValidSFString(version)
        self.__version = version
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def skinBindingCoords(self):
        """[X3DCoordinateNode] Array of Coordinate nodes to handle non-default source pose so that both skin and skeleton can be in same binding pose."""
        return self.__skinBindingCoords
    @skinBindingCoords.setter
    def skinBindingCoords(self, skinBindingCoords=None):
        if  skinBindingCoords is None:
            skinBindingCoords = SFNode.DEFAULT_VALUE
        assertValidSFNode(skinBindingCoords)
        if not isinstance(skinBindingCoords, object):
            # print(flush=True)
            raise X3DTypeError(str(skinBindingCoords) + ' does not have a valid node type object')
        self.__skinBindingCoords = skinBindingCoords
    @property # getter - - - - - - - - - -
    def skinBindingNormals(self):
        """[X3DNormalNode] Array of Normal nodes to handle non-default source pose so that both skin and skeleton can be in same binding pose."""
        return self.__skinBindingNormals
    @skinBindingNormals.setter
    def skinBindingNormals(self, skinBindingNormals=None):
        if  skinBindingNormals is None:
            skinBindingNormals = SFNode.DEFAULT_VALUE
        assertValidSFNode(skinBindingNormals)
        if not isinstance(skinBindingNormals, object):
            # print(flush=True)
            raise X3DTypeError(str(skinBindingNormals) + ' does not have a valid node type object')
        self.__skinBindingNormals = skinBindingNormals
    @property # getter - - - - - - - - - -
    def skinCoord(self):
        """[X3DCoordinateNode] Coordinate node utilized by indexed mesh definitions for skin."""
        return self.__skinCoord
    @skinCoord.setter
    def skinCoord(self, skinCoord=None):
        if  skinCoord is None:
            skinCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(skinCoord)
        if not isinstance(skinCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(skinCoord) + ' does not have a valid node type object')
        self.__skinCoord = skinCoord
    @property # getter - - - - - - - - - -
    def skinNormal(self):
        """[X3DNormalNode] Single Normal node utilized by indexed mesh definitions for skin."""
        return self.__skinNormal
    @skinNormal.setter
    def skinNormal(self, skinNormal=None):
        if  skinNormal is None:
            skinNormal = SFNode.DEFAULT_VALUE
        assertValidSFNode(skinNormal)
        if not isinstance(skinNormal, object):
            # print(flush=True)
            raise X3DTypeError(str(skinNormal) + ' does not have a valid node type object')
        self.__skinNormal = skinNormal
    @property # getter - - - - - - - - - -
    def joints(self):
        """[HAnimJoint] The joints field contains a list of USE references for all HAnimJoint node instances found within the preceding skeleton hierarchy."""
        return self.__joints
    @joints.setter
    def joints(self, joints=None):
        if  joints is None:
            joints = MFNode.DEFAULT_VALUE
        assertValidMFNode(joints)
        self.__joints = joints
    @property # getter - - - - - - - - - -
    def motions(self):
        """[HAnimMotion] Contains any HAnimMotion nodes that can animate the HAnimHumanoid."""
        return self.__motions
    @motions.setter
    def motions(self, motions=None):
        if  motions is None:
            motions = MFNode.DEFAULT_VALUE
        assertValidMFNode(motions)
        self.__motions = motions
    @property # getter - - - - - - - - - -
    def segments(self):
        """[HAnimSegment] The segments field contains a list of USE references for all HAnimSegment node instances found within the preceding skeleton hierarchy."""
        return self.__segments
    @segments.setter
    def segments(self, segments=None):
        if  segments is None:
            segments = MFNode.DEFAULT_VALUE
        assertValidMFNode(segments)
        self.__segments = segments
    @property # getter - - - - - - - - - -
    def sites(self):
        """[HAnimSite] sites field contains a list of USE references for all HAnimSite node instances found within the preceding skeleton hierarchy."""
        return self.__sites
    @sites.setter
    def sites(self, sites=None):
        if  sites is None:
            sites = MFNode.DEFAULT_VALUE
        assertValidMFNode(sites)
        self.__sites = sites
    @property # getter - - - - - - - - - -
    def skeleton(self):
        """[HAnimJoint|HAnimSite] List of top-level HAnimJoint and HAnimSite nodes that create the skeleton model."""
        return self.__skeleton
    @skeleton.setter
    def skeleton(self, skeleton=None):
        if  skeleton is None:
            skeleton = MFNode.DEFAULT_VALUE
        assertValidMFNode(skeleton)
        self.__skeleton = skeleton
    @property # getter - - - - - - - - - -
    def skin(self):
        """[IndexedFaceSet|Group|Transform|Shape] List of one or more indexed mesh definitions (such as IndexedFaceSet) that utilize skinCoord point and skinNormal normal data."""
        return self.__skin
    @skin.setter
    def skin(self, skin=None):
        if  skin is None:
            skin = MFNode.DEFAULT_VALUE
        assertValidMFNode(skin)
        self.__skin = skin
    @property # getter - - - - - - - - - -
    def viewpoints(self):
        """[HAnimSite] List of HAnimSite nodes containing Viewpoint nodes that appear in the skeleton model, usually as USE node references."""
        return self.__viewpoints
    @viewpoints.setter
    def viewpoints(self, viewpoints=None):
        if  viewpoints is None:
            viewpoints = MFNode.DEFAULT_VALUE
        assertValidMFNode(viewpoints)
        self.__viewpoints = viewpoints
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.joints) or bool(self.motions) or bool(self.segments) or bool(self.sites) or bool(self.skeleton) or bool(self.skin) or bool(self.viewpoints) or bool(self.IS) or bool(self.metadata) or bool(self.skinBindingCoords) or bool(self.skinBindingNormals) or bool(self.skinCoord) or bool(self.skinNormal)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function HAnimHumanoid.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<HAnimHumanoid'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.info != list():
            result += " info='" + MFString(self.info).XML() + "'"
        if self.jointBindingPositions != [(0, 0, 0)]:
            result += " jointBindingPositions='" + MFVec3f(self.jointBindingPositions).XML() + "'"
        if self.jointBindingRotations != [(0, 0, 1, 0)]:
            result += " jointBindingRotations='" + MFRotation(self.jointBindingRotations).XML() + "'"
        if self.jointBindingScales != [(0, 0, 0)]:
            result += " jointBindingScales='" + MFVec3f(self.jointBindingScales).XML() + "'"
        if self.loa != -1:
            result += " loa='" + SFInt32(self.loa).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.scale != (1, 1, 1):
            result += " scale='" + SFVec3f(self.scale).XML() + "'"
        if self.scaleOrientation != (0, 0, 1, 0):
            result += " scaleOrientation='" + SFRotation(self.scaleOrientation).XML() + "'"
        if self.skeletalConfiguration != 'BASIC':
            result += " skeletalConfiguration='" + self.skeletalConfiguration + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if self.version != '2.0':
            result += " version='" + self.version + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.skinBindingCoords: # output this SFNode
                result += self.skinBindingCoords.XML(indentLevel=indentLevel+1)
            if self.skinBindingNormals: # output this SFNode
                result += self.skinBindingNormals.XML(indentLevel=indentLevel+1)
            if self.skinCoord: # output this SFNode
                result += self.skinCoord.XML(indentLevel=indentLevel+1)
            if self.skinNormal: # output this SFNode
                result += self.skinNormal.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.joints: # walk each child node, if any
                for each in self.joints:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.motions: # walk each child node, if any
                for each in self.motions:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.segments: # walk each child node, if any
                for each in self.segments:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.sites: # walk each child node, if any
                for each in self.sites:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.skeleton: # walk each child node, if any
                for each in self.skeleton:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.skin: # walk each child node, if any
                for each in self.skin:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.viewpoints: # walk each child node, if any
                for each in self.viewpoints:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</HAnimHumanoid>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class HAnimJoint(_X3DChildNode, _X3DBoundedObject):
    """
    HAnimJoint node can represent each joint in a body.
    """
    NAME = 'HAnimJoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#HAnimJoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimJoint'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'HAnimJoint'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('limitOrientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'HAnimJoint'),
        ('llimit', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimJoint'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'HAnimJoint'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'HAnimJoint'),
        ('scale', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimJoint'),
        ('scaleOrientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'HAnimJoint'),
        ('skinCoordIndex', list(), FieldType.MFInt32, AccessType.inputOutput, 'HAnimJoint'),
        ('skinCoordWeight', list(), FieldType.MFFloat, AccessType.inputOutput, 'HAnimJoint'),
        ('stiffness', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimJoint'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimJoint'),
        ('ulimit', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimJoint'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimJoint'),
        ('displacers', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimJoint'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 center=(0, 0, 0),
                 description='',
                 displayBBox=False,
                 limitOrientation=(0, 0, 1, 0),
                 llimit=(0, 0, 0),
                 name='',
                 rotation=(0, 0, 1, 0),
                 scale=(1, 1, 1),
                 scaleOrientation=(0, 0, 1, 0),
                 skinCoordIndex=list(),
                 skinCoordWeight=list(),
                 stiffness=(1, 1, 1),
                 translation=(0, 0, 0),
                 ulimit=(0, 0, 0),
                 visible=True,
                 children=list(),
                 displacers=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode HAnimJoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.center = center
        self.description = description
        self.displayBBox = displayBBox
        self.limitOrientation = limitOrientation
        self.llimit = llimit
        self.name = name
        self.rotation = rotation
        self.scale = scale
        self.scaleOrientation = scaleOrientation
        self.skinCoordIndex = skinCoordIndex
        self.skinCoordWeight = skinCoordWeight
        self.stiffness = stiffness
        self.translation = translation
        self.ulimit = ulimit
        self.visible = visible
        self.children = children
        self.displacers = displacers
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def center(self):
        """Translation offset from origin of local coordinate system."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def description(self):
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def limitOrientation(self):
        """Orientation of upper/lower rotation limits, relative to HAnimJoint center."""
        return self.__limitOrientation
    @limitOrientation.setter
    def limitOrientation(self, limitOrientation=None):
        if  limitOrientation is None:
            limitOrientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(limitOrientation)
        self.__limitOrientation = limitOrientation
    @property # getter - - - - - - - - - -
    def llimit(self):
        """Lower limit for minimum joint rotation in radians."""
        return self.__llimit
    @llimit.setter
    def llimit(self, llimit=None):
        if  llimit is None:
            llimit = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(llimit)
        self.__llimit = llimit
    @property # getter - - - - - - - - - -
    def name(self):
        """Unique name attribute must be defined so that HAnimJoint node can be identified at run time for animation purposes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def rotation(self):
        """Orientation of children relative to local coordinate system."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def scale(self):
        """Non-uniform x-y-z scale of child coordinate system, adjusted by center and scaleOrientation."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(scale)
        assertPositive('scale', scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def scaleOrientation(self):
        """Preliminary rotation of coordinate system before scaling (to allow scaling around arbitrary orientations)."""
        return self.__scaleOrientation
    @scaleOrientation.setter
    def scaleOrientation(self, scaleOrientation=None):
        if  scaleOrientation is None:
            scaleOrientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(scaleOrientation)
        self.__scaleOrientation = scaleOrientation
    @property # getter - - - - - - - - - -
    def skinCoordIndex(self):
        """[0,+infinity) Coordinate index values referencing which vertices are influenced by the HAnimJoint."""
        return self.__skinCoordIndex
    @skinCoordIndex.setter
    def skinCoordIndex(self, skinCoordIndex=None):
        if  skinCoordIndex is None:
            skinCoordIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(skinCoordIndex)
        assertNonNegative('skinCoordIndex', skinCoordIndex)
        self.__skinCoordIndex = skinCoordIndex
    @property # getter - - - - - - - - - -
    def skinCoordWeight(self):
        """Weight deformation values for the corresponding values in the skinCoordIndex field."""
        return self.__skinCoordWeight
    @skinCoordWeight.setter
    def skinCoordWeight(self, skinCoordWeight=None):
        if  skinCoordWeight is None:
            skinCoordWeight = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(skinCoordWeight)
        self.__skinCoordWeight = skinCoordWeight
    @property # getter - - - - - - - - - -
    def stiffness(self):
        """[0,1] A scale factor of (1 - stiffness) is applied around the corresponding axis (X, Y, or Z for entries 0, 1 and 2 of the stiffness field)."""
        return self.__stiffness
    @stiffness.setter
    def stiffness(self, stiffness=None):
        if  stiffness is None:
            stiffness = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(stiffness)
        assertZeroToOne('stiffness', stiffness)
        self.__stiffness = stiffness
    @property # getter - - - - - - - - - -
    def translation(self):
        """Position of children relative to local coordinate system."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    @property # getter - - - - - - - - - -
    def ulimit(self):
        """Upper limit for maximum joint rotation in radians."""
        return self.__ulimit
    @ulimit.setter
    def ulimit(self, ulimit=None):
        if  ulimit is None:
            ulimit = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(ulimit)
        self.__ulimit = ulimit
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[HAnimJoint|HAnimSegment|HAnimSite] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    @property # getter - - - - - - - - - -
    def displacers(self):
        """[HAnimDisplacer] the displacers field stores HAnimDisplacer objects for a particular HAnimJoint object."""
        return self.__displacers
    @displacers.setter
    def displacers(self, displacers=None):
        if  displacers is None:
            displacers = MFNode.DEFAULT_VALUE
        assertValidMFNode(displacers)
        self.__displacers = displacers
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.displacers) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function HAnimJoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<HAnimJoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.limitOrientation != (0, 0, 1, 0):
            result += " limitOrientation='" + SFRotation(self.limitOrientation).XML() + "'"
        if self.llimit != (0, 0, 0):
            result += " llimit='" + SFVec3f(self.llimit).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.scale != (1, 1, 1):
            result += " scale='" + SFVec3f(self.scale).XML() + "'"
        if self.scaleOrientation != (0, 0, 1, 0):
            result += " scaleOrientation='" + SFRotation(self.scaleOrientation).XML() + "'"
        if self.skinCoordIndex != list():
            result += " skinCoordIndex='" + MFInt32(self.skinCoordIndex).XML() + "'"
        if self.skinCoordWeight != list():
            result += " skinCoordWeight='" + MFFloat(self.skinCoordWeight).XML() + "'"
        if self.stiffness != (1, 1, 1):
            result += " stiffness='" + SFVec3f(self.stiffness).XML() + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if self.ulimit != (0, 0, 0):
            result += " ulimit='" + SFVec3f(self.ulimit).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.displacers: # walk each child node, if any
                for each in self.displacers:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</HAnimJoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class HAnimMotion(_X3DChildNode):
    """
    An HAnimMotion node supports discrete frame-by-frame playback for H-Anim motion data animation.
    """
    NAME = 'HAnimMotion'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#HAnimMotion'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('channels', list(), FieldType.MFString, AccessType.inputOutput, 'HAnimMotion'),
        ('channelsEnabled', list(), FieldType.MFBool, AccessType.inputOutput, 'HAnimMotion'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'HAnimMotion'),
        ('enabled', False, FieldType.SFBool, AccessType.inputOutput, 'HAnimMotion'),
        ('endFrame', -1, FieldType.SFInt32, AccessType.inputOutput, 'HAnimMotion'),
        ('frameDuration', 0.1, FieldType.SFTime, AccessType.inputOutput, 'HAnimMotion'),
        ('frameIncrement', 1, FieldType.SFInt32, AccessType.inputOutput, 'HAnimMotion'),
        ('frameIndex', 0, FieldType.SFInt32, AccessType.inputOutput, 'HAnimMotion'),
        ('joints', list(), FieldType.MFString, AccessType.inputOutput, 'HAnimMotion'),
        ('loa', -1, FieldType.SFInt32, AccessType.inputOutput, 'HAnimMotion'),
        ('loop', False, FieldType.SFBool, AccessType.inputOutput, 'HAnimMotion'),
        ('startFrame', 0, FieldType.SFInt32, AccessType.inputOutput, 'HAnimMotion'),
        ('values', list(), FieldType.MFFloat, AccessType.inputOutput, 'HAnimMotion'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 channels=list(),
                 channelsEnabled=list(),
                 description='',
                 enabled=False,
                 endFrame=-1,
                 frameDuration=0.1,
                 frameIncrement=1,
                 frameIndex=0,
                 joints=list(),
                 loa=-1,
                 loop=False,
                 startFrame=0,
                 values=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode HAnimMotion __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.channels = channels
        self.channelsEnabled = channelsEnabled
        self.description = description
        self.enabled = enabled
        self.endFrame = endFrame
        self.frameDuration = frameDuration
        self.frameIncrement = frameIncrement
        self.frameIndex = frameIndex
        self.joints = joints
        self.loa = loa
        self.loop = loop
        self.startFrame = startFrame
        self.values = values
    @property # getter - - - - - - - - - -
    def channels(self):
        """list of number of channels for transformation, followed by transformation type of each channel of data."""
        return self.__channels
    @channels.setter
    def channels(self, channels=None):
        if  channels is None:
            channels = MFString.DEFAULT_VALUE
        assertValidMFString(channels)
        self.__channels = channels
    @property # getter - - - - - - - - - -
    def channelsEnabled(self):
        """boolean values for each channels indicating whether enabled."""
        return self.__channelsEnabled
    @channelsEnabled.setter
    def channelsEnabled(self, channelsEnabled=None):
        if  channelsEnabled is None:
            channelsEnabled = MFBool.DEFAULT_VALUE
        assertValidMFBool(channelsEnabled)
        self.__channelsEnabled = channelsEnabled
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def endFrame(self):
        return self.__endFrame
    @endFrame.setter
    def endFrame(self, endFrame=None):
        if  endFrame is None:
            endFrame = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(endFrame)
        assertGreaterThanEquals('endFrame', endFrame, -1)
        self.__endFrame = endFrame
    @property # getter - - - - - - - - - -
    def frameDuration(self):
        """(0,+infinity) frameDuration specifies the duration of each frame in seconds."""
        return self.__frameDuration
    @frameDuration.setter
    def frameDuration(self, frameDuration=None):
        if  frameDuration is None:
            frameDuration = SFTime.DEFAULT_VALUE
        assertValidSFTime(frameDuration)
        assertPositive('frameDuration', frameDuration)
        self.__frameDuration = frameDuration
    @property # getter - - - - - - - - - -
    def frameIncrement(self):
        """[-infinity,+infinity) frameIncrement field controls whether playback direction is forwards or backwards, and also whether frames are skipped (e."""
        return self.__frameIncrement
    @frameIncrement.setter
    def frameIncrement(self, frameIncrement=None):
        if  frameIncrement is None:
            frameIncrement = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(frameIncrement)
        self.__frameIncrement = frameIncrement
    @property # getter - - - - - - - - - -
    def frameIndex(self):
        """[0,+infinity) frameIndex indicates index of current frame."""
        return self.__frameIndex
    @frameIndex.setter
    def frameIndex(self, frameIndex=None):
        if  frameIndex is None:
            frameIndex = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(frameIndex)
        assertNonNegative('frameIndex', frameIndex)
        self.__frameIndex = frameIndex
    @property # getter - - - - - - - - - -
    def joints(self):
        """joints field lists names of joints that raw motion data is to be applied to."""
        return self.__joints
    @joints.setter
    def joints(self, joints=None):
        if  joints is None:
            joints = MFString.DEFAULT_VALUE
        assertValidMFString(joints)
        self.__joints = joints
    @property # getter - - - - - - - - - -
    def loa(self):
        """[-1,4] Level Of Articulation 0."""
        return self.__loa
    @loa.setter
    def loa(self, loa=None):
        if  loa is None:
            loa = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(loa)
        assertGreaterThanEquals('loa', loa, -1)
        assertLessThanEquals('loa', loa, 4)
        self.__loa = loa
    @property # getter - - - - - - - - - -
    def loop(self):
        """Repeat indefinitely when loop=true, repeat only once when loop=false."""
        return self.__loop
    @loop.setter
    def loop(self, loop=None):
        if  loop is None:
            loop = SFBool.DEFAULT_VALUE
        assertValidSFBool(loop)
        self.__loop = loop
    @property # getter - - - - - - - - - -
    def startFrame(self):
        return self.__startFrame
    @startFrame.setter
    def startFrame(self, startFrame=None):
        if  startFrame is None:
            startFrame = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(startFrame)
        assertNonNegative('startFrame', startFrame)
        self.__startFrame = startFrame
    @property # getter - - - - - - - - - -
    def values(self):
        """values field contains all transformation values, ordered first by frame, then by joint, and then by transformation Sets of floats in the values array matching the order listed in joints and channels fields."""
        return self.__values
    @values.setter
    def values(self, values=None):
        if  values is None:
            values = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(values)
        self.__values = values
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function HAnimMotion.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<HAnimMotion'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.channels != list():
            result += " channels='" + MFString(self.channels).XML() + "'"
        if self.channelsEnabled != list():
            result += " channelsEnabled='" + MFBool(self.channelsEnabled).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.enabled != False:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.endFrame != -1:
            result += " endFrame='" + SFInt32(self.endFrame).XML() + "'"
        if self.frameDuration != 0.1:
            result += " frameDuration='" + SFTime(self.frameDuration).XML() + "'"
        if self.frameIncrement != 1:
            result += " frameIncrement='" + SFInt32(self.frameIncrement).XML() + "'"
        if self.frameIndex != 0:
            result += " frameIndex='" + SFInt32(self.frameIndex).XML() + "'"
        if self.joints != list():
            result += " joints='" + MFString(self.joints).XML() + "'"
        if self.loa != -1:
            result += " loa='" + SFInt32(self.loa).XML() + "'"
        if self.loop != False:
            result += " loop='" + SFBool(self.loop).XML() + "'"
        if self.startFrame != 0:
            result += " startFrame='" + SFInt32(self.startFrame).XML() + "'"
        if self.values != list():
            result += " values='" + MFFloat(self.values).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</HAnimMotion>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class HAnimSegment(_X3DGroupingNode):
    """
    HAnimSegment node contains Shape geometry for each body segment.
    """
    NAME = 'HAnimSegment'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#HAnimSegment'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('centerOfMass', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimSegment'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'HAnimSegment'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('mass', 0, FieldType.SFFloat, AccessType.inputOutput, 'HAnimSegment'),
        ('momentsOfInertia', [0, 0, 0, 0, 0, 0, 0, 0, 0], FieldType.MFFloat, AccessType.inputOutput, 'HAnimSegment'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'HAnimSegment'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'HAnimSegment'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('displacers', list(), FieldType.MFNode, AccessType.inputOutput, 'HAnimSegment'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 centerOfMass=(0, 0, 0),
                 description='',
                 displayBBox=False,
                 mass=0,
                 momentsOfInertia=[0, 0, 0, 0, 0, 0, 0, 0, 0],
                 name='',
                 visible=True,
                 coord=None,
                 children=list(),
                 displacers=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode HAnimSegment __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.centerOfMass = centerOfMass
        self.description = description
        self.displayBBox = displayBBox
        self.mass = mass
        self.momentsOfInertia = momentsOfInertia
        self.name = name
        self.visible = visible
        self.coord = coord
        self.children = children
        self.displacers = displacers
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def centerOfMass(self):
        """Location within segment of center of mass."""
        return self.__centerOfMass
    @centerOfMass.setter
    def centerOfMass(self, centerOfMass=None):
        if  centerOfMass is None:
            centerOfMass = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(centerOfMass)
        self.__centerOfMass = centerOfMass
    @property # getter - - - - - - - - - -
    def description(self):
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def mass(self):
        """Total mass of the segment, 0 if not available, defined in mass base units (default is kilograms)."""
        return self.__mass
    @mass.setter
    def mass(self, mass=None):
        if  mass is None:
            mass = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(mass)
        assertNonNegative('mass', mass)
        self.__mass = mass
    @property # getter - - - - - - - - - -
    def momentsOfInertia(self):
        """3x3 moments of inertia matrix."""
        return self.__momentsOfInertia
    @momentsOfInertia.setter
    def momentsOfInertia(self, momentsOfInertia=None):
        if  momentsOfInertia is None:
            momentsOfInertia = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(momentsOfInertia)
        assertNonNegative('momentsOfInertia', momentsOfInertia)
        self.__momentsOfInertia = momentsOfInertia
    @property # getter - - - - - - - - - -
    def name(self):
        """Unique name attribute must be defined so that HAnimSegment node can be identified at run time for animation purposes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] the coord field is used for HAnimSegment objects that have deformable meshes and shall contain coordinates referenced from the IndexedFaceSet for the paarent HAnimSegment object."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    @property # getter - - - - - - - - - -
    def displacers(self):
        """[HAnimDisplacer] the displacers field stores HAnimDisplacer objects for a particular HAnimSegment object."""
        return self.__displacers
    @displacers.setter
    def displacers(self, displacers=None):
        if  displacers is None:
            displacers = MFNode.DEFAULT_VALUE
        assertValidMFNode(displacers)
        self.__displacers = displacers
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.displacers) or bool(self.coord) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function HAnimSegment.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<HAnimSegment'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.centerOfMass != (0, 0, 0):
            result += " centerOfMass='" + SFVec3f(self.centerOfMass).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.mass != 0:
            result += " mass='" + SFFloat(self.mass).XML() + "'"
        if self.momentsOfInertia != [0, 0, 0, 0, 0, 0, 0, 0, 0]:
            result += " momentsOfInertia='" + MFFloat(self.momentsOfInertia).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.displacers: # walk each child node, if any
                for each in self.displacers:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</HAnimSegment>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class HAnimSite(_X3DGroupingNode):
    """
    An HAnimSite node serves three purposes: (a) define an "end effector" location which can be used by an inverse kinematics system, (b) define an attachment point for accessories such as jewelry and clothing, and (c) define a location for a Viewpoint virtual camera in the reference frame of an HAnimSegment (such as a view "through the eyes" of the humanoid for use in multi-user worlds).
    """
    NAME = 'HAnimSite'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#HAnimSite'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimSite'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'HAnimSite'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'HAnimSite'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'HAnimSite'),
        ('scale', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimSite'),
        ('scaleOrientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'HAnimSite'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'HAnimSite'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 center=(0, 0, 0),
                 description='',
                 displayBBox=False,
                 name='',
                 rotation=(0, 0, 1, 0),
                 scale=(1, 1, 1),
                 scaleOrientation=(0, 0, 1, 0),
                 translation=(0, 0, 0),
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode HAnimSite __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.center = center
        self.description = description
        self.displayBBox = displayBBox
        self.name = name
        self.rotation = rotation
        self.scale = scale
        self.scaleOrientation = scaleOrientation
        self.translation = translation
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def center(self):
        """Default location of this HAnimSite, i."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def description(self):
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def name(self):
        """Unique name attribute must be defined so that HAnimSite node can be identified at run time for animation purposes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def rotation(self):
        """Orientation of children relative to local coordinate system."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def scale(self):
        """Non-uniform x-y-z scale of child coordinate system, adjusted by center and scaleOrientation."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(scale)
        assertPositive('scale', scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def scaleOrientation(self):
        """Preliminary rotation of coordinate system before scaling (to allow scaling around arbitrary orientations)."""
        return self.__scaleOrientation
    @scaleOrientation.setter
    def scaleOrientation(self, scaleOrientation=None):
        if  scaleOrientation is None:
            scaleOrientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(scaleOrientation)
        self.__scaleOrientation = scaleOrientation
    @property # getter - - - - - - - - - -
    def translation(self):
        """Position of children relative to local coordinate system."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function HAnimSite.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<HAnimSite'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.scale != (1, 1, 1):
            result += " scale='" + SFVec3f(self.scale).XML() + "'"
        if self.scaleOrientation != (0, 0, 1, 0):
            result += " scaleOrientation='" + SFRotation(self.scaleOrientation).XML() + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</HAnimSite>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ImageCubeMapTexture(_X3DEnvironmentTextureNode, _X3DUrlObject):
    """
    ImageCubeMapTexture is a texture node that defines a cubic environment map source as a single file format that contains multiple images, one for each side.
    """
    NAME = 'ImageCubeMapTexture'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ImageCubeMapTexture'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('textureProperties', None, FieldType.SFNode, AccessType.initializeOnly, 'ImageCubeMapTexture'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 url=list(),
                 textureProperties=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ImageCubeMapTexture __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.url = url
        self.textureProperties = textureProperties
    @property # getter - - - - - - - - - -
    def url(self):
        """Location and filename of image."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def textureProperties(self):
        return self.__textureProperties
    @textureProperties.setter
    def textureProperties(self, textureProperties=None):
        if  textureProperties is None:
            textureProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(textureProperties)
        if not isinstance(textureProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(textureProperties) + ' does not have a valid node type object')
        self.__textureProperties = textureProperties
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.textureProperties)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ImageCubeMapTexture.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ImageCubeMapTexture'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.textureProperties: # output this SFNode
                result += self.textureProperties.XML(indentLevel=indentLevel+1)
            result += indent + '</ImageCubeMapTexture>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ImageTexture(_X3DTexture2DNode, _X3DUrlObject):
    """
    ImageTexture maps a 2D-image file onto a geometric shape.
    """
    NAME = 'ImageTexture'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ImageTexture'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('repeatS', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture2DNode'),
        ('repeatT', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture2DNode'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('textureProperties', None, FieldType.SFNode, AccessType.initializeOnly, 'X3DTexture2DNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 repeatS=True,
                 repeatT=True,
                 url=list(),
                 textureProperties=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ImageTexture __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.repeatS = repeatS
        self.repeatT = repeatT
        self.url = url
        self.textureProperties = textureProperties
    @property # getter - - - - - - - - - -
    def repeatS(self):
        """Whether to horizontally repeat texture along S axis."""
        return self.__repeatS
    @repeatS.setter
    def repeatS(self, repeatS=None):
        if  repeatS is None:
            repeatS = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatS)
        self.__repeatS = repeatS
    @property # getter - - - - - - - - - -
    def repeatT(self):
        """Whether to vertically repeat texture along T axis."""
        return self.__repeatT
    @repeatT.setter
    def repeatT(self, repeatT=None):
        if  repeatT is None:
            repeatT = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatT)
        self.__repeatT = repeatT
    @property # getter - - - - - - - - - -
    def url(self):
        """Location and filename of image."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def textureProperties(self):
        return self.__textureProperties
    @textureProperties.setter
    def textureProperties(self, textureProperties=None):
        if  textureProperties is None:
            textureProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(textureProperties)
        if not isinstance(textureProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(textureProperties) + ' does not have a valid node type object')
        self.__textureProperties = textureProperties
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.textureProperties)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ImageTexture.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ImageTexture'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.repeatS != True:
            result += " repeatS='" + SFBool(self.repeatS).XML() + "'"
        if self.repeatT != True:
            result += " repeatT='" + SFBool(self.repeatT).XML() + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.textureProperties: # output this SFNode
                result += self.textureProperties.XML(indentLevel=indentLevel+1)
            result += indent + '</ImageTexture>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ImageTexture3D(_X3DTexture3DNode, _X3DUrlObject):
    """
    ImageTexture3D defines a 3D image-based texture map by specifying a single image file that contains complete 3D data.
    """
    NAME = 'ImageTexture3D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ImageTexture3D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('repeatR', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('repeatS', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('repeatT', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('textureProperties', None, FieldType.SFNode, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 repeatR=False,
                 repeatS=False,
                 repeatT=False,
                 url=list(),
                 textureProperties=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ImageTexture3D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.repeatR = repeatR
        self.repeatS = repeatS
        self.repeatT = repeatT
        self.url = url
        self.textureProperties = textureProperties
    @property # getter - - - - - - - - - -
    def repeatR(self):
        """Whether to vertically repeat texture along R axis."""
        return self.__repeatR
    @repeatR.setter
    def repeatR(self, repeatR=None):
        if  repeatR is None:
            repeatR = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatR)
        self.__repeatR = repeatR
    @property # getter - - - - - - - - - -
    def repeatS(self):
        """Whether to horizontally repeat texture along S axis."""
        return self.__repeatS
    @repeatS.setter
    def repeatS(self, repeatS=None):
        if  repeatS is None:
            repeatS = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatS)
        self.__repeatS = repeatS
    @property # getter - - - - - - - - - -
    def repeatT(self):
        """Whether to vertically repeat texture along T axis."""
        return self.__repeatT
    @repeatT.setter
    def repeatT(self, repeatT=None):
        if  repeatT is None:
            repeatT = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatT)
        self.__repeatT = repeatT
    @property # getter - - - - - - - - - -
    def url(self):
        """Location and filename of image."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def textureProperties(self):
        return self.__textureProperties
    @textureProperties.setter
    def textureProperties(self, textureProperties=None):
        if  textureProperties is None:
            textureProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(textureProperties)
        if not isinstance(textureProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(textureProperties) + ' does not have a valid node type object')
        self.__textureProperties = textureProperties
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.textureProperties)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ImageTexture3D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ImageTexture3D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.repeatR != False:
            result += " repeatR='" + SFBool(self.repeatR).XML() + "'"
        if self.repeatS != False:
            result += " repeatS='" + SFBool(self.repeatS).XML() + "'"
        if self.repeatT != False:
            result += " repeatT='" + SFBool(self.repeatT).XML() + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.textureProperties: # output this SFNode
                result += self.textureProperties.XML(indentLevel=indentLevel+1)
            result += indent + '</ImageTexture3D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IndexedFaceSet(_X3DComposedGeometryNode):
    """
    IndexedFaceSet defines polygons using index lists corresponding to vertex coordinates.
    """
    NAME = 'IndexedFaceSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IndexedFaceSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('colorIndex', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedFaceSet'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('convex', True, FieldType.SFBool, AccessType.initializeOnly, 'IndexedFaceSet'),
        ('coordIndex', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedFaceSet'),
        ('creaseAngle', 0, FieldType.SFFloat, AccessType.initializeOnly, 'IndexedFaceSet'),
        ('normalIndex', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedFaceSet'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('texCoordIndex', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedFaceSet'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorIndex=list(),
                 colorPerVertex=True,
                 convex=True,
                 coordIndex=list(),
                 creaseAngle=0,
                 normalIndex=list(),
                 normalPerVertex=True,
                 solid=True,
                 texCoordIndex=list(),
                 color=None,
                 coord=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode IndexedFaceSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorIndex = colorIndex
        self.colorPerVertex = colorPerVertex
        self.convex = convex
        self.coordIndex = coordIndex
        self.creaseAngle = creaseAngle
        self.normalIndex = normalIndex
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.texCoordIndex = texCoordIndex
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorIndex(self):
        """[-1,+infinity) colorIndex values define the order in which Color|ColorRGBA values are applied to polygons (or vertices)."""
        return self.__colorIndex
    @colorIndex.setter
    def colorIndex(self, colorIndex=None):
        if  colorIndex is None:
            colorIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(colorIndex)
        assertGreaterThanEquals('colorIndex', colorIndex, -1)
        self.__colorIndex = colorIndex
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color|ColorRGBA values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def convex(self):
        """The convex field is a hint to renderers whether all polygons in a shape are convex (true), or possibly concave (false)."""
        return self.__convex
    @convex.setter
    def convex(self, convex=None):
        if  convex is None:
            convex = SFBool.DEFAULT_VALUE
        assertValidSFBool(convex)
        self.__convex = convex
    @property # getter - - - - - - - - - -
    def coordIndex(self):
        """[-1,+infinity) coordIndex indices provide the order in which coordinates are applied to construct each polygon face."""
        return self.__coordIndex
    @coordIndex.setter
    def coordIndex(self, coordIndex=None):
        if  coordIndex is None:
            coordIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(coordIndex)
        assertGreaterThanEquals('coordIndex', coordIndex, -1)
        self.__coordIndex = coordIndex
    @property # getter - - - - - - - - - -
    def creaseAngle(self):
        """[0,+infinity) creaseAngle defines angle (in radians) for determining whether adjacent polygons are drawn with sharp edges or smooth shading."""
        return self.__creaseAngle
    @creaseAngle.setter
    def creaseAngle(self, creaseAngle=None):
        if  creaseAngle is None:
            creaseAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(creaseAngle)
        assertNonNegative('creaseAngle', creaseAngle)
        self.__creaseAngle = creaseAngle
    @property # getter - - - - - - - - - -
    def normalIndex(self):
        """[-1,+infinity) normalIndex values define the order in which normal vectors are applied to polygons (or vertices)."""
        return self.__normalIndex
    @normalIndex.setter
    def normalIndex(self, normalIndex=None):
        if  normalIndex is None:
            normalIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(normalIndex)
        assertGreaterThanEquals('normalIndex', normalIndex, -1)
        self.__normalIndex = normalIndex
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def texCoordIndex(self):
        """[-1,+infinity) List of texture-coordinate indices mapping attached texture to corresponding coordinates."""
        return self.__texCoordIndex
    @texCoordIndex.setter
    def texCoordIndex(self, texCoordIndex=None):
        if  texCoordIndex is None:
            texCoordIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(texCoordIndex)
        assertGreaterThanEquals('texCoordIndex', texCoordIndex, -1)
        self.__texCoordIndex = texCoordIndex
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IndexedFaceSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IndexedFaceSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorIndex != list():
            result += " colorIndex='" + MFInt32(self.colorIndex).XML() + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.convex != True:
            result += " convex='" + SFBool(self.convex).XML() + "'"
        if self.coordIndex != list():
            result += " coordIndex='" + MFInt32(self.coordIndex).XML() + "'"
        if self.creaseAngle != 0:
            result += " creaseAngle='" + SFFloat(self.creaseAngle).XML() + "'"
        if self.normalIndex != list():
            result += " normalIndex='" + MFInt32(self.normalIndex).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.texCoordIndex != list():
            result += " texCoordIndex='" + MFInt32(self.texCoordIndex).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</IndexedFaceSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IndexedLineSet(_X3DGeometryNode):
    """
    IndexedLineSet defines polyline segments using index lists corresponding to vertex coordinates.
    """
    NAME = 'IndexedLineSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IndexedLineSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('colorIndex', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedLineSet'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'IndexedLineSet'),
        ('coordIndex', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedLineSet'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'IndexedLineSet'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'IndexedLineSet'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'IndexedLineSet'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'IndexedLineSet'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 colorIndex=list(),
                 colorPerVertex=True,
                 coordIndex=list(),
                 color=None,
                 coord=None,
                 fogCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode IndexedLineSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.colorIndex = colorIndex
        self.colorPerVertex = colorPerVertex
        self.coordIndex = coordIndex
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def colorIndex(self):
        """[-1,+infinity) colorIndex values define the order in which Color|ColorRGBA values are applied to polygons (or vertices)."""
        return self.__colorIndex
    @colorIndex.setter
    def colorIndex(self, colorIndex=None):
        if  colorIndex is None:
            colorIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(colorIndex)
        assertGreaterThanEquals('colorIndex', colorIndex, -1)
        self.__colorIndex = colorIndex
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color node color values are applied to each point vertex (true) or per polyline (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def coordIndex(self):
        """[-1,+infinity) coordIndex indices provide the order in which coordinates are applied to construct each polygon face."""
        return self.__coordIndex
    @coordIndex.setter
    def coordIndex(self, coordIndex=None):
        if  coordIndex is None:
            coordIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(coordIndex)
        assertGreaterThanEquals('coordIndex', coordIndex, -1)
        self.__coordIndex = coordIndex
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IndexedLineSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IndexedLineSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorIndex != list():
            result += " colorIndex='" + MFInt32(self.colorIndex).XML() + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.coordIndex != list():
            result += " coordIndex='" + MFInt32(self.coordIndex).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</IndexedLineSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IndexedQuadSet(_X3DComposedGeometryNode):
    """
    IndexedQuadSet is a geometry node that defines quadrilaterals.
    """
    NAME = 'IndexedQuadSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IndexedQuadSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('index', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedQuadSet'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 index=list(),
                 normalPerVertex=True,
                 solid=True,
                 color=None,
                 coord=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode IndexedQuadSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.index = index
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color|ColorRGBA values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def index(self):
        """[0,+infinity) index values provide order in which coordinates are applied."""
        return self.__index
    @index.setter
    def index(self, index=None):
        if  index is None:
            index = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(index)
        assertNonNegative('index', index)
        self.__index = index
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IndexedQuadSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IndexedQuadSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.index != list():
            result += " index='" + MFInt32(self.index).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</IndexedQuadSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IndexedTriangleFanSet(_X3DComposedGeometryNode):
    """
    IndexedTriangleFanSet is a geometry node containing a Coordinate|CoordinateDouble node, and can also contain Color|ColorRGBA, Normal and TextureCoordinate nodes.
    """
    NAME = 'IndexedTriangleFanSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IndexedTriangleFanSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('index', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedTriangleFanSet'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 index=list(),
                 normalPerVertex=True,
                 solid=True,
                 color=None,
                 coord=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode IndexedTriangleFanSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.index = index
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color|ColorRGBA values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def index(self):
        """[-1,+infinity) index list specifies triangles by connecting Coordinate vertices, each individual fan separated by -1 sentinel value."""
        return self.__index
    @index.setter
    def index(self, index=None):
        if  index is None:
            index = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(index)
        assertGreaterThanEquals('index', index, -1)
        self.__index = index
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IndexedTriangleFanSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IndexedTriangleFanSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.index != list():
            result += " index='" + MFInt32(self.index).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</IndexedTriangleFanSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IndexedTriangleSet(_X3DComposedGeometryNode):
    """
    IndexedTriangleSet is a geometry node containing a Coordinate|CoordinateDouble node, and can also contain Color|ColorRGBA, Normal and TextureCoordinate nodes.
    """
    NAME = 'IndexedTriangleSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IndexedTriangleSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('index', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedTriangleSet'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 index=list(),
                 normalPerVertex=True,
                 solid=True,
                 color=None,
                 coord=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode IndexedTriangleSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.index = index
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color|ColorRGBA values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def index(self):
        """[0,+infinity) index list specifies triangles by connecting Coordinate vertices."""
        return self.__index
    @index.setter
    def index(self, index=None):
        if  index is None:
            index = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(index)
        assertNonNegative('index', index)
        self.__index = index
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IndexedTriangleSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IndexedTriangleSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.index != list():
            result += " index='" + MFInt32(self.index).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</IndexedTriangleSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IndexedTriangleStripSet(_X3DComposedGeometryNode):
    """
    IndexedTriangleStripSet is a geometry node containing a Coordinate|CoordinateDouble node, and can also contain Color|ColorRGBA, Normal and TextureCoordinate nodes.
    """
    NAME = 'IndexedTriangleStripSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IndexedTriangleStripSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('index', list(), FieldType.MFInt32, AccessType.initializeOnly, 'IndexedTriangleStripSet'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 index=list(),
                 normalPerVertex=True,
                 solid=True,
                 color=None,
                 coord=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode IndexedTriangleStripSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.index = index
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color|ColorRGBA values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def index(self):
        """[-1,+infinity) index list specifies triangles by connecting Coordinate vertices for each individual strip, separated by -1 sentinel values."""
        return self.__index
    @index.setter
    def index(self, index=None):
        if  index is None:
            index = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(index)
        assertGreaterThanEquals('index', index, -1)
        self.__index = index
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IndexedTriangleStripSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IndexedTriangleStripSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.index != list():
            result += " index='" + MFInt32(self.index).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</IndexedTriangleStripSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Inline(_X3DChildNode, _X3DBoundedObject, _X3DUrlObject):
    """
    Inline can load another X3D or VRML model into the current scene via url.
    """
    NAME = 'Inline'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Inline'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('load', True, FieldType.SFBool, AccessType.inputOutput, 'Inline'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 load=True,
                 url=list(),
                 visible=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Inline __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.load = load
        self.url = url
        self.visible = visible
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def load(self):
        """load=true means load immediately, load=false means defer loading or else unload a previously loaded scene."""
        return self.__load
    @load.setter
    def load(self, load=None):
        if  load is None:
            load = SFBool.DEFAULT_VALUE
        assertValidSFBool(load)
        self.__load = load
    @property # getter - - - - - - - - - -
    def url(self):
        """Address of X3D world to load into current scene."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Inline.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Inline'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.load != True:
            result += " load='" + SFBool(self.load).XML() + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Inline>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IntegerSequencer(_X3DSequencerNode):
    """
    IntegerSequencer generates periodic discrete integer values.
    """
    NAME = 'IntegerSequencer'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IntegerSequencer'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DSequencerNode'),
        ('keyValue', list(), FieldType.MFInt32, AccessType.inputOutput, 'IntegerSequencer'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode IntegerSequencer __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear sequencing, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IntegerSequencer.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IntegerSequencer'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFInt32(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</IntegerSequencer>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IntegerTrigger(_X3DTriggerNode):
    """
    IntegerTrigger converts set_boolean true input events to an integer value (for example, useful when animating whichChoice in a Switch node).
    """
    NAME = 'IntegerTrigger'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IntegerTrigger'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('integerKey', -1, FieldType.SFInt32, AccessType.inputOutput, 'IntegerTrigger'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 integerKey=-1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode IntegerTrigger __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.integerKey = integerKey
    @property # getter - - - - - - - - - -
    def integerKey(self):
        """integerKey is value for output when triggered."""
        return self.__integerKey
    @integerKey.setter
    def integerKey(self, integerKey=None):
        if  integerKey is None:
            integerKey = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(integerKey)
        self.__integerKey = integerKey
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IntegerTrigger.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IntegerTrigger'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.integerKey != -1:
            result += " integerKey='" + SFInt32(self.integerKey).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</IntegerTrigger>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class IsoSurfaceVolumeData(_X3DVolumeDataNode):
    """
    IsoSurfaceVolumeData displays one or more surfaces extracted from a voxel dataset.
    """
    NAME = 'IsoSurfaceVolumeData'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#IsoSurfaceVolumeData'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DVolumeDataNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DVolumeDataNode'),
        ('contourStepSize', 0, FieldType.SFFloat, AccessType.inputOutput, 'IsoSurfaceVolumeData'),
        ('dimensions', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'X3DVolumeDataNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeDataNode'),
        ('surfaceTolerance', 0, FieldType.SFFloat, AccessType.inputOutput, 'IsoSurfaceVolumeData'),
        ('surfaceValues', list(), FieldType.MFFloat, AccessType.inputOutput, 'IsoSurfaceVolumeData'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeDataNode'),
        ('gradients', None, FieldType.SFNode, AccessType.inputOutput, 'IsoSurfaceVolumeData'),
        ('voxels', None, FieldType.SFNode, AccessType.inputOutput, 'IsoSurfaceVolumeData'),
        ('renderStyle', list(), FieldType.MFNode, AccessType.inputOutput, 'IsoSurfaceVolumeData'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 contourStepSize=0,
                 dimensions=(1, 1, 1),
                 displayBBox=False,
                 surfaceTolerance=0,
                 surfaceValues=list(),
                 visible=True,
                 gradients=None,
                 voxels=None,
                 renderStyle=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode IsoSurfaceVolumeData __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.contourStepSize = contourStepSize
        self.dimensions = dimensions
        self.displayBBox = displayBBox
        self.surfaceTolerance = surfaceTolerance
        self.surfaceValues = surfaceValues
        self.visible = visible
        self.gradients = gradients
        self.voxels = voxels
        self.renderStyle = renderStyle
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def contourStepSize(self):
        """If contourStepSize is non-zero, also render all isosurfaces that are multiples of that step size from initial surface value."""
        return self.__contourStepSize
    @contourStepSize.setter
    def contourStepSize(self, contourStepSize=None):
        if  contourStepSize is None:
            contourStepSize = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(contourStepSize)
        self.__contourStepSize = contourStepSize
    @property # getter - - - - - - - - - -
    def dimensions(self):
        """Actual-size X-Y-Z dimensions of volume data in local coordinate system."""
        return self.__dimensions
    @dimensions.setter
    def dimensions(self, dimensions=None):
        if  dimensions is None:
            dimensions = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(dimensions)
        assertPositive('dimensions', dimensions)
        self.__dimensions = dimensions
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def surfaceTolerance(self):
        """[0,+infinity) Threshold for gradient magnitude for voxel inolusion in isosurface."""
        return self.__surfaceTolerance
    @surfaceTolerance.setter
    def surfaceTolerance(self, surfaceTolerance=None):
        if  surfaceTolerance is None:
            surfaceTolerance = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(surfaceTolerance)
        assertNonNegative('surfaceTolerance', surfaceTolerance)
        self.__surfaceTolerance = surfaceTolerance
    @property # getter - - - - - - - - - -
    def surfaceValues(self):
        """If surfaceValues has one value defined, render corresponding isosurface plus any isosurfaces based on contourStepSize."""
        return self.__surfaceValues
    @surfaceValues.setter
    def surfaceValues(self, surfaceValues=None):
        if  surfaceValues is None:
            surfaceValues = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(surfaceValues)
        self.__surfaceValues = surfaceValues
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def gradients(self):
        """[X3DTexture3DNode] Single contained X3DTexture3DNode (ComposedTexture3D, ImageTexture3D, PixelTexture3D) that provides explicit per-voxel gradient direction information for determining surface boundaries, rather than having it implicitly calculated by the implementation."""
        return self.__gradients
    @gradients.setter
    def gradients(self, gradients=None):
        if  gradients is None:
            gradients = SFNode.DEFAULT_VALUE
        assertValidSFNode(gradients)
        if not isinstance(gradients, object):
            # print(flush=True)
            raise X3DTypeError(str(gradients) + ' does not have a valid node type object')
        self.__gradients = gradients
    @property # getter - - - - - - - - - -
    def voxels(self):
        """[X3DTexture3DNode] Single contained X3DTexture3DNode (ComposedTexture3D, ImageTexture3D, PixelTexture3D) that provides raw voxel information utilized by corresponding rendering styles."""
        return self.__voxels
    @voxels.setter
    def voxels(self, voxels=None):
        if  voxels is None:
            voxels = SFNode.DEFAULT_VALUE
        assertValidSFNode(voxels)
        if not isinstance(voxels, object):
            # print(flush=True)
            raise X3DTypeError(str(voxels) + ' does not have a valid node type object')
        self.__voxels = voxels
    @property # getter - - - - - - - - - -
    def renderStyle(self):
        """[X3DVolumeRenderStyleNode] Multiple contained X3DVolumeRenderStyleNode nodes corresponding to each isosurface that define specific rendering technique for this volumetric object."""
        return self.__renderStyle
    @renderStyle.setter
    def renderStyle(self, renderStyle=None):
        if  renderStyle is None:
            renderStyle = MFNode.DEFAULT_VALUE
        assertValidMFNode(renderStyle)
        self.__renderStyle = renderStyle
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.renderStyle) or bool(self.gradients) or bool(self.IS) or bool(self.metadata) or bool(self.voxels)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function IsoSurfaceVolumeData.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<IsoSurfaceVolumeData'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.contourStepSize != 0:
            result += " contourStepSize='" + SFFloat(self.contourStepSize).XML() + "'"
        if self.dimensions != (1, 1, 1):
            result += " dimensions='" + SFVec3f(self.dimensions).XML() + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.surfaceTolerance != 0:
            result += " surfaceTolerance='" + SFFloat(self.surfaceTolerance).XML() + "'"
        if self.surfaceValues != list():
            result += " surfaceValues='" + MFFloat(self.surfaceValues).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.gradients: # output this SFNode
                result += self.gradients.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.voxels: # output this SFNode
                result += self.voxels.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.renderStyle: # walk each child node, if any
                for each in self.renderStyle:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</IsoSurfaceVolumeData>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class KeySensor(_X3DKeyDeviceSensorNode):
    """
    KeySensor generates events as the user presses keys on the keyboard.
    """
    NAME = 'KeySensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#KeySensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode KeySensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function KeySensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<KeySensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</KeySensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Layer(_X3DLayerNode):
    """
    Layer contains a list of children nodes that define the contents of the layer.
    """
    NAME = 'Layer'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Layer'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('objectType', ["ALL"], FieldType.MFString, AccessType.inputOutput, 'X3DLayerNode'),
        ('pickable', True, FieldType.SFBool, AccessType.inputOutput, 'X3DLayerNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DLayerNode'),
        ('viewport', None, FieldType.SFNode, AccessType.inputOutput, 'X3DLayerNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'Layer'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 objectType=["ALL"],
                 pickable=True,
                 visible=True,
                 viewport=None,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Layer __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.objectType = objectType
        self.pickable = pickable
        self.visible = visible
        self.viewport = viewport
        self.children = children
    @property # getter - - - - - - - - - -
    def objectType(self):
        return self.__objectType
    @objectType.setter
    def objectType(self, objectType=None):
        if  objectType is None:
            objectType = MFString.DEFAULT_VALUE
        assertValidMFString(objectType)
        self.__objectType = objectType
    @property # getter - - - - - - - - - -
    def pickable(self):
        return self.__pickable
    @pickable.setter
    def pickable(self, pickable=None):
        if  pickable is None:
            pickable = SFBool.DEFAULT_VALUE
        assertValidSFBool(pickable)
        self.__pickable = pickable
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def viewport(self):
        """[X3DViewportNode] The viewport field is a single Viewport node that constrains layer output to a sub-region of the render surface."""
        return self.__viewport
    @viewport.setter
    def viewport(self, viewport=None):
        if  viewport is None:
            viewport = SFNode.DEFAULT_VALUE
        assertValidSFNode(viewport)
        if not isinstance(viewport, object):
            # print(flush=True)
            raise X3DTypeError(str(viewport) + ' does not have a valid node type object')
        self.__viewport = viewport
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Nodes making up this layer."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata) or bool(self.viewport)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Layer.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Layer'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.objectType != ["ALL"]:
            result += " objectType='" + MFString(self.objectType).XML() + "'"
        if self.pickable != True:
            result += " pickable='" + SFBool(self.pickable).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.viewport: # output this SFNode
                result += self.viewport.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Layer>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class LayerSet(_X3DNode):
    """
    LayerSet defines a list of layers and a rendering order.
    """
    NAME = 'LayerSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#LayerSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('activeLayer', 0, FieldType.SFInt32, AccessType.inputOutput, 'LayerSet'),
        ('order', [0], FieldType.MFInt32, AccessType.initializeOnly, 'LayerSet'),
        ('layers', list(), FieldType.MFNode, AccessType.inputOutput, 'LayerSet'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 activeLayer=0,
                 order=[0],
                 layers=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode LayerSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.activeLayer = activeLayer
        self.order = order
        self.layers = layers
    @property # getter - - - - - - - - - -
    def activeLayer(self):
        """[0,+infinity) activeLayer field specifies the layer in which navigation takes place."""
        return self.__activeLayer
    @activeLayer.setter
    def activeLayer(self, activeLayer=None):
        if  activeLayer is None:
            activeLayer = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(activeLayer)
        assertNonNegative('activeLayer', activeLayer)
        self.__activeLayer = activeLayer
    @property # getter - - - - - - - - - -
    def order(self):
        """[0,+infinity) The order list defines the order in which layers are rendered."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(order)
        assertNonNegative('order', order)
        self.__order = order
    @property # getter - - - - - - - - - -
    def layers(self):
        """[X3DLayerNode] The layers list defines a list of Layer nodes that contain the constituent parts of the scene."""
        return self.__layers
    @layers.setter
    def layers(self, layers=None):
        if  layers is None:
            layers = MFNode.DEFAULT_VALUE
        assertValidMFNode(layers)
        self.__layers = layers
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.layers) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function LayerSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<LayerSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.activeLayer != 0:
            result += " activeLayer='" + SFInt32(self.activeLayer).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.order != [0]:
            result += " order='" + MFInt32(self.order).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.layers: # walk each child node, if any
                for each in self.layers:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</LayerSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Layout(_X3DLayoutNode): #  # TODO fix additional inheritance method resolution order (MRO)
    """
    Layout node is used as layout field of LayoutLayer and LayoutGroup nodes.
    """
    NAME = 'Layout'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Layout'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('align', ["CENTER", "CENTER"], FieldType.MFString, AccessType.inputOutput, 'Layout'),
        ('offset', [0, 0], FieldType.MFFloat, AccessType.inputOutput, 'Layout'),
        ('offsetUnits', ["WORLD", "WORLD"], FieldType.MFString, AccessType.inputOutput, 'Layout'),
        ('scaleMode', ["NONE", "NONE"], FieldType.MFString, AccessType.inputOutput, 'Layout'),
        ('size', [1, 1], FieldType.MFFloat, AccessType.initializeOnly, 'Layout'),
        ('sizeUnits', ["WORLD", "WORLD"], FieldType.MFString, AccessType.inputOutput, 'Layout'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 align=["CENTER", "CENTER"],
                 offset=[0, 0],
                 offsetUnits=["WORLD", "WORLD"],
                 scaleMode=["NONE", "NONE"],
                 size=[1, 1],
                 sizeUnits=["WORLD", "WORLD"],
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Layout __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.align = align
        self.offset = offset
        self.offsetUnits = offsetUnits
        self.scaleMode = scaleMode
        self.size = size
        self.sizeUnits = sizeUnits
    @property # getter - - - - - - - - - -
    def align(self):
        """The align field values align the sized rectangle to an edge or center of the parent rectangle."""
        return self.__align
    @align.setter
    def align(self, align=None):
        if  align is None:
            align = MFString.DEFAULT_VALUE
        assertValidMFString(align)
        self.__align = align
    @property # getter - - - - - - - - - -
    def offset(self):
        """(-infinity,+infinity) The values of the offset field are used to translate the location of this rectangle after the initial alignment."""
        return self.__offset
    @offset.setter
    def offset(self, offset=None):
        if  offset is None:
            offset = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(offset)
        self.__offset = offset
    @property # getter - - - - - - - - - -
    def offsetUnits(self):
        """The offsetUnits field values are used to interprete the offset values."""
        return self.__offsetUnits
    @offsetUnits.setter
    def offsetUnits(self, offsetUnits=None):
        if  offsetUnits is None:
            offsetUnits = MFString.DEFAULT_VALUE
        assertValidMFString(offsetUnits)
        self.__offsetUnits = offsetUnits
    @property # getter - - - - - - - - - -
    def scaleMode(self):
        """The scaleMode field specifies how the scale of the parent is modified."""
        return self.__scaleMode
    @scaleMode.setter
    def scaleMode(self, scaleMode=None):
        if  scaleMode is None:
            scaleMode = MFString.DEFAULT_VALUE
        assertValidMFString(scaleMode)
        self.__scaleMode = scaleMode
    @property # getter - - - - - - - - - -
    def size(self):
        """(0,+infinity) The two values in the size field define the width and height of the layout rectangle."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(size)
        self.__size = size
    @property # getter - - - - - - - - - -
    def sizeUnits(self):
        """The sizeUnits field values are used to interprete the offset values."""
        return self.__sizeUnits
    @sizeUnits.setter
    def sizeUnits(self, sizeUnits=None):
        if  sizeUnits is None:
            sizeUnits = MFString.DEFAULT_VALUE
        assertValidMFString(sizeUnits)
        self.__sizeUnits = sizeUnits
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Layout.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Layout'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.align != ["CENTER", "CENTER"]:
            result += " align='" + MFString(self.align).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.offset != [0, 0]:
            result += " offset='" + MFFloat(self.offset).XML() + "'"
        if self.offsetUnits != ["WORLD", "WORLD"]:
            result += " offsetUnits='" + MFString(self.offsetUnits).XML() + "'"
        if self.scaleMode != ["NONE", "NONE"]:
            result += " scaleMode='" + MFString(self.scaleMode).XML() + "'"
        if self.size != [1, 1]:
            result += " size='" + MFFloat(self.size).XML() + "'"
        if self.sizeUnits != ["WORLD", "WORLD"]:
            result += " sizeUnits='" + MFString(self.sizeUnits).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Layout>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class LayoutGroup(_X3DNode): # , _X3DGroupingNode # TODO fix additional inheritance method resolution order (MRO)
    """
    LayoutGroup is a Grouping node that can contain most nodes, whose children are related by a common layout within a parent layout.
    """
    NAME = 'LayoutGroup'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#LayoutGroup'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('layout', None, FieldType.SFNode, AccessType.inputOutput, 'LayoutGroup'),
        ('viewport', None, FieldType.SFNode, AccessType.inputOutput, 'LayoutGroup'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'LayoutGroup'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 visible=True,
                 layout=None,
                 viewport=None,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode LayoutGroup __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.visible = visible
        self.layout = layout
        self.viewport = viewport
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def layout(self):
        """[X3DLayoutNode] The layout field contains an X3DLayoutNode node that provides the information required to locate and size the layout region of the LayoutGroup node relative to its parent’s layout region, and also to scale the contents of the LayoutGroup."""
        return self.__layout
    @layout.setter
    def layout(self, layout=None):
        if  layout is None:
            layout = SFNode.DEFAULT_VALUE
        assertValidSFNode(layout)
        if not isinstance(layout, object):
            # print(flush=True)
            raise X3DTypeError(str(layout) + ' does not have a valid node type object')
        self.__layout = layout
    @property # getter - - - - - - - - - -
    def viewport(self):
        """[X3DViewportNode] The content of the LayoutGroup is clipped by the specified viewport."""
        return self.__viewport
    @viewport.setter
    def viewport(self, viewport=None):
        if  viewport is None:
            viewport = SFNode.DEFAULT_VALUE
        assertValidSFNode(viewport)
        if not isinstance(viewport, object):
            # print(flush=True)
            raise X3DTypeError(str(viewport) + ' does not have a valid node type object')
        self.__viewport = viewport
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.layout) or bool(self.metadata) or bool(self.viewport)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function LayoutGroup.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<LayoutGroup'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.layout: # output this SFNode
                result += self.layout.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.viewport: # output this SFNode
                result += self.viewport.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</LayoutGroup>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class LayoutLayer(_X3DLayerNode): #  # TODO fix additional inheritance method resolution order (MRO)
    """
    LayoutLayer is a Grouping node that can contain most nodes.
    """
    NAME = 'LayoutLayer'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#LayoutLayer'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('objectType', ["ALL"], FieldType.MFString, AccessType.inputOutput, 'X3DLayerNode'),
        ('pickable', True, FieldType.SFBool, AccessType.inputOutput, 'X3DLayerNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DLayerNode'),
        ('layout', None, FieldType.SFNode, AccessType.inputOutput, 'LayoutLayer'),
        ('viewport', None, FieldType.SFNode, AccessType.inputOutput, 'X3DLayerNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'LayoutLayer'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 objectType=["ALL"],
                 pickable=True,
                 visible=True,
                 layout=None,
                 viewport=None,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode LayoutLayer __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.objectType = objectType
        self.pickable = pickable
        self.visible = visible
        self.layout = layout
        self.viewport = viewport
        self.children = children
    @property # getter - - - - - - - - - -
    def objectType(self):
        return self.__objectType
    @objectType.setter
    def objectType(self, objectType=None):
        if  objectType is None:
            objectType = MFString.DEFAULT_VALUE
        assertValidMFString(objectType)
        self.__objectType = objectType
    @property # getter - - - - - - - - - -
    def pickable(self):
        return self.__pickable
    @pickable.setter
    def pickable(self, pickable=None):
        if  pickable is None:
            pickable = SFBool.DEFAULT_VALUE
        assertValidSFBool(pickable)
        self.__pickable = pickable
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def layout(self):
        """[X3DLayoutNode] The layout field contains an X3DLayoutNode node that provides the information required to locate and size the layout region of the LayoutGroup node relative to its parent’s layout region, and also to scale the contents of the LayoutGroup."""
        return self.__layout
    @layout.setter
    def layout(self, layout=None):
        if  layout is None:
            layout = SFNode.DEFAULT_VALUE
        assertValidSFNode(layout)
        if not isinstance(layout, object):
            # print(flush=True)
            raise X3DTypeError(str(layout) + ' does not have a valid node type object')
        self.__layout = layout
    @property # getter - - - - - - - - - -
    def viewport(self):
        """[X3DViewportNode] The content of the LayoutGroup is clipped by the specified viewport."""
        return self.__viewport
    @viewport.setter
    def viewport(self, viewport=None):
        if  viewport is None:
            viewport = SFNode.DEFAULT_VALUE
        assertValidSFNode(viewport)
        if not isinstance(viewport, object):
            # print(flush=True)
            raise X3DTypeError(str(viewport) + ' does not have a valid node type object')
        self.__viewport = viewport
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.layout) or bool(self.metadata) or bool(self.viewport)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function LayoutLayer.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<LayoutLayer'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.objectType != ["ALL"]:
            result += " objectType='" + MFString(self.objectType).XML() + "'"
        if self.pickable != True:
            result += " pickable='" + SFBool(self.pickable).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.layout: # output this SFNode
                result += self.layout.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.viewport: # output this SFNode
                result += self.viewport.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</LayoutLayer>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class LinePickSensor(_X3DPickSensorNode):
    """
    LinePickSensor uses one or more pickingGeometry line segments to compute intersections with pickTarget shapes.
    """
    NAME = 'LinePickSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#LinePickSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('intersectionType', 'BOUNDS', FieldType.SFString, AccessType.initializeOnly, 'X3DPickSensorNode'),
        ('matchCriterion', 'MATCH_ANY', FieldType.SFString, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('objectType', ["ALL"], FieldType.MFString, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('sortOrder', 'CLOSEST', FieldType.SFString, AccessType.initializeOnly, 'X3DPickSensorNode'),
        ('pickingGeometry', None, FieldType.SFNode, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('pickTarget', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 intersectionType='BOUNDS',
                 matchCriterion='MATCH_ANY',
                 objectType=["ALL"],
                 sortOrder='CLOSEST',
                 pickingGeometry=None,
                 pickTarget=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode LinePickSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.intersectionType = intersectionType
        self.matchCriterion = matchCriterion
        self.objectType = objectType
        self.sortOrder = sortOrder
        self.pickingGeometry = pickingGeometry
        self.pickTarget = pickTarget
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def intersectionType(self):
        """intersectionType specifies precision of the collision computation."""
        return self.__intersectionType
    @intersectionType.setter
    def intersectionType(self, intersectionType=None):
        if  intersectionType is None:
            intersectionType = SFString.DEFAULT_VALUE
        assertValidSFString(intersectionType)
        self.__intersectionType = intersectionType
    @property # getter - - - - - - - - - -
    def matchCriterion(self):
        """defines whether the intersection test (i."""
        return self.__matchCriterion
    @matchCriterion.setter
    def matchCriterion(self, matchCriterion=None):
        if  matchCriterion is None:
            matchCriterion = SFString.DEFAULT_VALUE
        assertValidSFString(matchCriterion)
        self.__matchCriterion = matchCriterion
    @property # getter - - - - - - - - - -
    def objectType(self):
        """The objectType field specifies a set of labels used in the picking process."""
        return self.__objectType
    @objectType.setter
    def objectType(self, objectType=None):
        if  objectType is None:
            objectType = MFString.DEFAULT_VALUE
        assertValidMFString(objectType)
        self.__objectType = objectType
    @property # getter - - - - - - - - - -
    def sortOrder(self):
        """The sortOrder field determines the order provided for picked output events."""
        return self.__sortOrder
    @sortOrder.setter
    def sortOrder(self, sortOrder=None):
        if  sortOrder is None:
            sortOrder = SFString.DEFAULT_VALUE
        assertValidSFString(sortOrder)
        self.__sortOrder = sortOrder
    @property # getter - - - - - - - - - -
    def pickingGeometry(self):
        """[IndexedLineSet|LineSet] pickingGeometry specifies the exact geometry coordinates that are used to perform the intersection testing of the picking operation."""
        return self.__pickingGeometry
    @pickingGeometry.setter
    def pickingGeometry(self, pickingGeometry=None):
        if  pickingGeometry is None:
            pickingGeometry = SFNode.DEFAULT_VALUE
        assertValidSFNode(pickingGeometry)
        if not isinstance(pickingGeometry, object):
            # print(flush=True)
            raise X3DTypeError(str(pickingGeometry) + ' does not have a valid node type object')
        self.__pickingGeometry = pickingGeometry
    @property # getter - - - - - - - - - -
    def pickTarget(self):
        """[X3DGroupingNode|X3DShapeNode|Inline] pickTarget specifies the list of nodes against which picking operations are performed."""
        return self.__pickTarget
    @pickTarget.setter
    def pickTarget(self, pickTarget=None):
        if  pickTarget is None:
            pickTarget = MFNode.DEFAULT_VALUE
        assertValidMFNode(pickTarget)
        self.__pickTarget = pickTarget
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.pickTarget) or bool(self.IS) or bool(self.metadata) or bool(self.pickingGeometry)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function LinePickSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<LinePickSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.intersectionType != 'BOUNDS':
            result += " intersectionType='" + self.intersectionType + "'"
        if self.matchCriterion != 'MATCH_ANY':
            result += " matchCriterion='" + self.matchCriterion + "'"
        if self.objectType != ["ALL"]:
            result += " objectType='" + MFString(self.objectType).XML() + "'"
        if self.sortOrder != 'CLOSEST':
            result += " sortOrder='" + self.sortOrder + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.pickingGeometry: # output this SFNode
                result += self.pickingGeometry.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.pickTarget: # walk each child node, if any
                for each in self.pickTarget:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</LinePickSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class LineProperties(_X3DAppearanceChildNode):
    """
    LineProperties allows precise fine-grained control over the rendering style of lines and edges for associated geometry nodes inside the same Shape.
    """
    NAME = 'LineProperties'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#LineProperties'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('applied', True, FieldType.SFBool, AccessType.inputOutput, 'LineProperties'),
        ('linetype', 1, FieldType.SFInt32, AccessType.inputOutput, 'LineProperties'),
        ('linewidthScaleFactor', 0, FieldType.SFFloat, AccessType.inputOutput, 'LineProperties'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 applied=True,
                 linetype=1,
                 linewidthScaleFactor=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode LineProperties __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.applied = applied
        self.linetype = linetype
        self.linewidthScaleFactor = linewidthScaleFactor
    @property # getter - - - - - - - - - -
    def applied(self):
        """Whether or not LineProperties are applied to associated geometry."""
        return self.__applied
    @applied.setter
    def applied(self, applied=None):
        if  applied is None:
            applied = SFBool.DEFAULT_VALUE
        assertValidSFBool(applied)
        self.__applied = applied
    @property # getter - - - - - - - - - -
    def linetype(self):
        """linetype selects a line pattern, with solid default if defined value isn't supported."""
        return self.__linetype
    @linetype.setter
    def linetype(self, linetype=None):
        if  linetype is None:
            linetype = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(linetype)
        assertGreaterThanEquals('linetype', linetype, 1)
        self.__linetype = linetype
    @property # getter - - - - - - - - - -
    def linewidthScaleFactor(self):
        """linewidthScaleFactor is a scale factor multiplied by browser-dependent nominal linewidth, mapped to nearest available line width."""
        return self.__linewidthScaleFactor
    @linewidthScaleFactor.setter
    def linewidthScaleFactor(self, linewidthScaleFactor=None):
        if  linewidthScaleFactor is None:
            linewidthScaleFactor = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(linewidthScaleFactor)
        self.__linewidthScaleFactor = linewidthScaleFactor
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function LineProperties.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<LineProperties'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.applied != True:
            result += " applied='" + SFBool(self.applied).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.linetype != 1:
            result += " linetype='" + SFInt32(self.linetype).XML() + "'"
        if self.linewidthScaleFactor != 0:
            result += " linewidthScaleFactor='" + SFFloat(self.linewidthScaleFactor).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</LineProperties>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class LineSet(_X3DGeometryNode):
    """
    LineSet is a geometry node that can contain a Coordinate|CoordinateDouble node and optionally a Color|ColorRGBA node.
    """
    NAME = 'LineSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#LineSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('vertexCount', list(), FieldType.MFInt32, AccessType.inputOutput, 'LineSet'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'LineSet'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'LineSet'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'LineSet'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'LineSet'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 vertexCount=list(),
                 color=None,
                 coord=None,
                 fogCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode LineSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.vertexCount = vertexCount
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def vertexCount(self):
        """[2,+infinity) vertexCount describes how many vertices are used in each individual polyline segment from the Coordinate point values."""
        return self.__vertexCount
    @vertexCount.setter
    def vertexCount(self, vertexCount=None):
        if  vertexCount is None:
            vertexCount = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(vertexCount)
        assertGreaterThanEquals('vertexCount', vertexCount, 2)
        self.__vertexCount = vertexCount
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function LineSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<LineSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.vertexCount != list():
            result += " vertexCount='" + MFInt32(self.vertexCount).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</LineSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class LoadSensor(_X3DNetworkSensorNode):
    """
    LoadSensor generates events as watchList child nodes are either loaded or fail to load.
    """
    NAME = 'LoadSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#LoadSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('timeOut', 0, FieldType.SFTime, AccessType.inputOutput, 'LoadSensor'),
        ('watchList', list(), FieldType.MFNode, AccessType.inputOutput, 'LoadSensor'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 timeOut=0,
                 watchList=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode LoadSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.timeOut = timeOut
        self.watchList = watchList
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def timeOut(self):
        """Time in seconds of maximum load duration prior to declaring failure."""
        return self.__timeOut
    @timeOut.setter
    def timeOut(self, timeOut=None):
        if  timeOut is None:
            timeOut = SFTime.DEFAULT_VALUE
        assertValidSFTime(timeOut)
        assertNonNegative('timeOut', timeOut)
        self.__timeOut = timeOut
    @property # getter - - - - - - - - - -
    def watchList(self):
        """[X3DUrlObject] The watchList field monitors one or more USE nodes that contain a valid url field."""
        return self.__watchList
    @watchList.setter
    def watchList(self, watchList=None):
        if  watchList is None:
            watchList = MFNode.DEFAULT_VALUE
        assertValidMFNode(watchList)
        self.__watchList = watchList
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.watchList) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function LoadSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<LoadSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.timeOut != 0:
            result += " timeOut='" + SFTime(self.timeOut).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.watchList: # walk each child node, if any
                for each in self.watchList:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</LoadSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class LocalFog(_X3DChildNode, _X3DFogObject):
    """
    LocalFog simulates atmospheric effects by blending distant objects with fog color.
    """
    NAME = 'LocalFog'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#LocalFog'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('color', (1, 1, 1), FieldType.SFColor, AccessType.inputOutput, 'X3DFogObject'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'LocalFog'),
        ('fogType', 'LINEAR', FieldType.SFString, AccessType.inputOutput, 'X3DFogObject'),
        ('visibilityRange', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DFogObject'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 color=(1, 1, 1),
                 enabled=True,
                 fogType='LINEAR',
                 visibilityRange=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode LocalFog __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.color = color
        self.enabled = enabled
        self.fogType = fogType
        self.visibilityRange = visibilityRange
    @property # getter - - - - - - - - - -
    def color(self):
        """[0,1] Fog color."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFColor.DEFAULT_VALUE
        assertValidSFColor(color)
        assertZeroToOne('color', color)
        self.__color = color
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def fogType(self):
        """Specifies algorithm for rate of increasing Fog, either LINEAR or EXPONENTIAL."""
        return self.__fogType
    @fogType.setter
    def fogType(self, fogType=None):
        if  fogType is None:
            fogType = SFString.DEFAULT_VALUE
        assertValidSFString(fogType)
        self.__fogType = fogType
    @property # getter - - - - - - - - - -
    def visibilityRange(self):
        """Distance in meters where objects are totally obscured by the fog, using local coordinate system."""
        return self.__visibilityRange
    @visibilityRange.setter
    def visibilityRange(self, visibilityRange=None):
        if  visibilityRange is None:
            visibilityRange = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(visibilityRange)
        assertNonNegative('visibilityRange', visibilityRange)
        self.__visibilityRange = visibilityRange
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function LocalFog.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<LocalFog'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.color != (1, 1, 1):
            result += " color='" + SFColor(self.color).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.fogType != 'LINEAR':
            result += " fogType='" + self.fogType + "'"
        if self.visibilityRange != 0:
            result += " visibilityRange='" + SFFloat(self.visibilityRange).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</LocalFog>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class LOD(_X3DGroupingNode):
    """
    LOD (Level Of Detail) uses camera-to-object distance to switch among contained child levels.
    """
    NAME = 'LOD'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#LOD'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'LOD'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('forceTransitions', False, FieldType.SFBool, AccessType.initializeOnly, 'LOD'),
        ('range', list(), FieldType.MFFloat, AccessType.initializeOnly, 'LOD'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 center=(0, 0, 0),
                 displayBBox=False,
                 forceTransitions=False,
                 range=list(),
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode LOD __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.center = center
        self.displayBBox = displayBBox
        self.forceTransitions = forceTransitions
        self.range = range
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def center(self):
        """Viewpoint distance-measurement offset from origin of local coordinate system, used for LOD node distance calculations."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def forceTransitions(self):
        """Whether to perform every range-based transition, regardless of browser optimizations that might otherwise occur."""
        return self.__forceTransitions
    @forceTransitions.setter
    def forceTransitions(self, forceTransitions=None):
        if  forceTransitions is None:
            forceTransitions = SFBool.DEFAULT_VALUE
        assertValidSFBool(forceTransitions)
        self.__forceTransitions = forceTransitions
    @property # getter - - - - - - - - - -
    def range(self):
        """(0,+infinity) Specifies ideal distances at which to switch between levels."""
        return self.__range
    @range.setter
    def range(self, range=None):
        if  range is None:
            range = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(range)
        self.__range = range
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function LOD.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<LOD'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.forceTransitions != False:
            result += " forceTransitions='" + SFBool(self.forceTransitions).XML() + "'"
        if self.range != list():
            result += " range='" + MFFloat(self.range).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</LOD>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Material(_X3DMaterialNode):
    """
    Material specifies surface rendering properties for associated geometry nodes.
    """
    NAME = 'Material'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Material'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ambientIntensity', 0.2, FieldType.SFFloat, AccessType.inputOutput, 'Material'),
        ('diffuseColor', (0.8, 0.8, 0.8), FieldType.SFColor, AccessType.inputOutput, 'Material'),
        ('emissiveColor', (0, 0, 0), FieldType.SFColor, AccessType.inputOutput, 'Material'),
        ('shininess', 0.2, FieldType.SFFloat, AccessType.inputOutput, 'Material'),
        ('specularColor', (0, 0, 0), FieldType.SFColor, AccessType.inputOutput, 'Material'),
        ('transparency', 0, FieldType.SFFloat, AccessType.inputOutput, 'Material'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ambientIntensity=0.2,
                 diffuseColor=(0.8, 0.8, 0.8),
                 emissiveColor=(0, 0, 0),
                 shininess=0.2,
                 specularColor=(0, 0, 0),
                 transparency=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Material __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ambientIntensity = ambientIntensity
        self.diffuseColor = diffuseColor
        self.emissiveColor = emissiveColor
        self.shininess = shininess
        self.specularColor = specularColor
        self.transparency = transparency
    @property # getter - - - - - - - - - -
    def ambientIntensity(self):
        """[0,1] how much ambient omnidirectional light is reflected from all light sources."""
        return self.__ambientIntensity
    @ambientIntensity.setter
    def ambientIntensity(self, ambientIntensity=None):
        if  ambientIntensity is None:
            ambientIntensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(ambientIntensity)
        assertZeroToOne('ambientIntensity', ambientIntensity)
        self.__ambientIntensity = ambientIntensity
    @property # getter - - - - - - - - - -
    def diffuseColor(self):
        """[0,1] how much direct, angle-dependent light is reflected from all light sources."""
        return self.__diffuseColor
    @diffuseColor.setter
    def diffuseColor(self, diffuseColor=None):
        if  diffuseColor is None:
            diffuseColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(diffuseColor)
        assertZeroToOne('diffuseColor', diffuseColor)
        self.__diffuseColor = diffuseColor
    @property # getter - - - - - - - - - -
    def emissiveColor(self):
        """[0,1] how much glowing light is emitted from this object."""
        return self.__emissiveColor
    @emissiveColor.setter
    def emissiveColor(self, emissiveColor=None):
        if  emissiveColor is None:
            emissiveColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(emissiveColor)
        assertZeroToOne('emissiveColor', emissiveColor)
        self.__emissiveColor = emissiveColor
    @property # getter - - - - - - - - - -
    def shininess(self):
        """[0,1] Lower shininess values provide soft specular glows, while higher values result in sharper, smaller highlights."""
        return self.__shininess
    @shininess.setter
    def shininess(self, shininess=None):
        if  shininess is None:
            shininess = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(shininess)
        assertZeroToOne('shininess', shininess)
        self.__shininess = shininess
    @property # getter - - - - - - - - - -
    def specularColor(self):
        """[0,1] specular highlights are brightness reflections (example: shiny spots on an apple)."""
        return self.__specularColor
    @specularColor.setter
    def specularColor(self, specularColor=None):
        if  specularColor is None:
            specularColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(specularColor)
        assertZeroToOne('specularColor', specularColor)
        self.__specularColor = specularColor
    @property # getter - - - - - - - - - -
    def transparency(self):
        """[0,1] how "clear" an object is: 1."""
        return self.__transparency
    @transparency.setter
    def transparency(self, transparency=None):
        if  transparency is None:
            transparency = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(transparency)
        assertZeroToOne('transparency', transparency)
        self.__transparency = transparency
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Material.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Material'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ambientIntensity != 0.2:
            result += " ambientIntensity='" + SFFloat(self.ambientIntensity).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.diffuseColor != (0.8, 0.8, 0.8):
            result += " diffuseColor='" + SFColor(self.diffuseColor).XML() + "'"
        if self.emissiveColor != (0, 0, 0):
            result += " emissiveColor='" + SFColor(self.emissiveColor).XML() + "'"
        if self.shininess != 0.2:
            result += " shininess='" + SFFloat(self.shininess).XML() + "'"
        if self.specularColor != (0, 0, 0):
            result += " specularColor='" + SFColor(self.specularColor).XML() + "'"
        if self.transparency != 0:
            result += " transparency='" + SFFloat(self.transparency).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Material>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Matrix3VertexAttribute(_X3DVertexAttributeNode):
    """
    Matrix3VertexAttribute defines a set of per-vertex 3x3 matrix attributes.
    """
    NAME = 'Matrix3VertexAttribute'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Matrix3VertexAttribute'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DVertexAttributeNode'),
        ('value', list(), FieldType.MFMatrix3f, AccessType.inputOutput, 'Matrix3VertexAttribute'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 name='',
                 value=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Matrix3VertexAttribute __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.value = value
    @property # getter - - - - - - - - - -
    def name(self):
        """Required name for this particular VertexAttribute instance."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def value(self):
        """value specifies an arbitrary collection of matrix values that will be passed to the shader as per-vertex information."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = MFMatrix3f.DEFAULT_VALUE
        assertValidMFMatrix3f(value)
        self.__value = value
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Matrix3VertexAttribute.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Matrix3VertexAttribute'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.value != list():
            result += " value='" + MFMatrix3f(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Matrix3VertexAttribute>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Matrix4VertexAttribute(_X3DVertexAttributeNode):
    """
    Matrix4VertexAttribute defines a set of per-vertex 4x4 matrix attributes.
    """
    NAME = 'Matrix4VertexAttribute'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Matrix4VertexAttribute'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DVertexAttributeNode'),
        ('value', list(), FieldType.MFMatrix4f, AccessType.inputOutput, 'Matrix4VertexAttribute'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 name='',
                 value=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Matrix4VertexAttribute __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.value = value
    @property # getter - - - - - - - - - -
    def name(self):
        """Required name for this particular VertexAttribute instance."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def value(self):
        """value specifies an arbitrary collection of matrix values that will be passed to the shader as per-vertex information."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = MFMatrix4f.DEFAULT_VALUE
        assertValidMFMatrix4f(value)
        self.__value = value
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Matrix4VertexAttribute.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Matrix4VertexAttribute'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.value != list():
            result += " value='" + MFMatrix4f(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Matrix4VertexAttribute>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MetadataBoolean(_X3DNode): # , _X3DMetadataObject # TODO fix additional inheritance method resolution order (MRO)
    """
    The metadata provided by this node is contained in the Boolean values of the value field.
    """
    NAME = 'MetadataBoolean'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataBoolean'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('reference', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('value', list(), FieldType.MFBool, AccessType.inputOutput, 'MetadataBoolean'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 name='',
                 reference='',
                 value=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MetadataBoolean __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.reference = reference
        self.value = value
    @property # getter - - - - - - - - - -
    def name(self):
        """Depending on the metadata vocabulary, the attribute name is usually required for metadata nodes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def reference(self):
        """Reference to the metadata standard or definition defining this particular metadata value."""
        return self.__reference
    @reference.setter
    def reference(self, reference=None):
        if  reference is None:
            reference = SFString.DEFAULT_VALUE
        assertValidSFString(reference)
        self.__reference = reference
    @property # getter - - - - - - - - - -
    def value(self):
        """The value attribute is a strictly typed data array providing relevant metadata information."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = MFBool.DEFAULT_VALUE
        assertValidMFBool(value)
        self.__value = value
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MetadataBoolean.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MetadataBoolean'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.reference:
            result += " reference='" + self.reference + "'"
        if self.value != list():
            result += " value='" + MFBool(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</MetadataBoolean>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MetadataDouble(_X3DNode): # , _X3DMetadataObject # TODO fix additional inheritance method resolution order (MRO)
    """
    The metadata provided by this node is contained in the double-precision floating point numbers of the value field.
    """
    NAME = 'MetadataDouble'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataDouble'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('reference', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('value', list(), FieldType.MFDouble, AccessType.inputOutput, 'MetadataDouble'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 name='',
                 reference='',
                 value=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MetadataDouble __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.reference = reference
        self.value = value
    @property # getter - - - - - - - - - -
    def name(self):
        """Depending on the metadata vocabulary, the attribute name is usually required for metadata nodes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def reference(self):
        """Reference to the metadata standard or definition defining this particular metadata value."""
        return self.__reference
    @reference.setter
    def reference(self, reference=None):
        if  reference is None:
            reference = SFString.DEFAULT_VALUE
        assertValidSFString(reference)
        self.__reference = reference
    @property # getter - - - - - - - - - -
    def value(self):
        """The value attribute is a strictly typed data array providing relevant metadata information."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(value)
        self.__value = value
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MetadataDouble.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MetadataDouble'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.reference:
            result += " reference='" + self.reference + "'"
        if self.value != list():
            result += " value='" + MFDouble(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</MetadataDouble>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MetadataFloat(_X3DNode): # , _X3DMetadataObject # TODO fix additional inheritance method resolution order (MRO)
    """
    The metadata provided by this node is contained in the single-precision floating point numbers of the value field.
    """
    NAME = 'MetadataFloat'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataFloat'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('reference', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('value', list(), FieldType.MFFloat, AccessType.inputOutput, 'MetadataFloat'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 name='',
                 reference='',
                 value=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MetadataFloat __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.reference = reference
        self.value = value
    @property # getter - - - - - - - - - -
    def name(self):
        """Depending on the metadata vocabulary, the attribute name is usually required for metadata nodes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def reference(self):
        """Reference to the metadata standard or definition defining this particular metadata value."""
        return self.__reference
    @reference.setter
    def reference(self, reference=None):
        if  reference is None:
            reference = SFString.DEFAULT_VALUE
        assertValidSFString(reference)
        self.__reference = reference
    @property # getter - - - - - - - - - -
    def value(self):
        """The value attribute is a strictly typed data array providing relevant metadata information."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(value)
        self.__value = value
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MetadataFloat.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MetadataFloat'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.reference:
            result += " reference='" + self.reference + "'"
        if self.value != list():
            result += " value='" + MFFloat(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</MetadataFloat>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MetadataInteger(_X3DNode): # , _X3DMetadataObject # TODO fix additional inheritance method resolution order (MRO)
    """
    The metadata provided by this node is contained in the integer numbers of the value field.
    """
    NAME = 'MetadataInteger'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataInteger'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('reference', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('value', list(), FieldType.MFInt32, AccessType.inputOutput, 'MetadataInteger'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 name='',
                 reference='',
                 value=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MetadataInteger __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.reference = reference
        self.value = value
    @property # getter - - - - - - - - - -
    def name(self):
        """Depending on the metadata vocabulary, the attribute name is usually required for metadata nodes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def reference(self):
        """Reference to the metadata standard or definition defining this particular metadata value."""
        return self.__reference
    @reference.setter
    def reference(self, reference=None):
        if  reference is None:
            reference = SFString.DEFAULT_VALUE
        assertValidSFString(reference)
        self.__reference = reference
    @property # getter - - - - - - - - - -
    def value(self):
        """The value attribute is a strictly typed data array providing relevant metadata information."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(value)
        self.__value = value
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MetadataInteger.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MetadataInteger'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.reference:
            result += " reference='" + self.reference + "'"
        if self.value != list():
            result += " value='" + MFInt32(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</MetadataInteger>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MetadataSet(_X3DNode): # , _X3DMetadataObject # TODO fix additional inheritance method resolution order (MRO)
    """
    The metadata provided by this node is contained in the metadata nodes of the value field.
    """
    NAME = 'MetadataSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('reference', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('value', list(), FieldType.MFNode, AccessType.inputOutput, 'MetadataSet'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'MetadataSet'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'MetadataSet')]
    def __init__(self,
                 name='',
                 reference='',
                 value=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MetadataSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.reference = reference
        self.value = value
    @property # getter - - - - - - - - - -
    def name(self):
        """Depending on the metadata vocabulary, the attribute name is usually required for metadata nodes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def reference(self):
        """Reference to the metadata standard or definition defining this particular metadata value."""
        return self.__reference
    @reference.setter
    def reference(self, reference=None):
        if  reference is None:
            reference = SFString.DEFAULT_VALUE
        assertValidSFString(reference)
        self.__reference = reference
    @property # getter - - - - - - - - - -
    def value(self):
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = MFNode.DEFAULT_VALUE
        assertValidMFNode(value)
        self.__value = value
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.value) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MetadataSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MetadataSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.reference:
            result += " reference='" + self.reference + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.value: # walk each child node, if any
                for each in self.value:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</MetadataSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MetadataString(_X3DNode): # , _X3DMetadataObject # TODO fix additional inheritance method resolution order (MRO)
    """
    The metadata provided by this node is contained in the strings of the value field.
    """
    NAME = 'MetadataString'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MetadataString'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('reference', '', FieldType.SFString, AccessType.inputOutput, 'X3DMetadataObject'),
        ('value', list(), FieldType.MFString, AccessType.inputOutput, 'MetadataString'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 name='',
                 reference='',
                 value=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MetadataString __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.reference = reference
        self.value = value
    @property # getter - - - - - - - - - -
    def name(self):
        """Depending on the metadata vocabulary, the attribute name is usually required for metadata nodes."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def reference(self):
        """Reference to the metadata standard or definition defining this particular metadata value."""
        return self.__reference
    @reference.setter
    def reference(self, reference=None):
        if  reference is None:
            reference = SFString.DEFAULT_VALUE
        assertValidSFString(reference)
        self.__reference = reference
    @property # getter - - - - - - - - - -
    def value(self):
        """The value attribute is a strictly typed data array providing relevant metadata information."""
        return self.__value
    @value.setter
    def value(self, value=None):
        if  value is None:
            value = MFString.DEFAULT_VALUE
        assertValidMFString(value)
        self.__value = value
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MetadataString.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MetadataString'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if self.reference:
            result += " reference='" + self.reference + "'"
        if self.value != list():
            result += " value='" + MFString(self.value).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</MetadataString>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MotorJoint(_X3DRigidJointNode):
    """
    MotorJoint drives relative angular velocities between body1 and body2 within a common reference frame.
    """
    NAME = 'MotorJoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MotorJoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('autoCalc', False, FieldType.SFBool, AccessType.initializeOnly, 'MotorJoint'),
        ('axis1Angle', 0, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('axis1Torque', 0, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('axis2Angle', 0, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('axis2Torque', 0, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('axis3Angle', 0, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('axis3Torque', 0, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('enabledAxes', 1, FieldType.SFInt32, AccessType.inputOutput, 'MotorJoint'),
        ('forceOutput', ["NONE"], FieldType.MFString, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('motor1Axis', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'MotorJoint'),
        ('motor2Axis', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'MotorJoint'),
        ('motor3Axis', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'MotorJoint'),
        ('stop1Bounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('stop1ErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('stop2Bounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('stop2ErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('stop3Bounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('stop3ErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'MotorJoint'),
        ('body1', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('body2', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 autoCalc=False,
                 axis1Angle=0,
                 axis1Torque=0,
                 axis2Angle=0,
                 axis2Torque=0,
                 axis3Angle=0,
                 axis3Torque=0,
                 enabledAxes=1,
                 forceOutput=["NONE"],
                 motor1Axis=(0, 0, 0),
                 motor2Axis=(0, 0, 0),
                 motor3Axis=(0, 0, 0),
                 stop1Bounce=0,
                 stop1ErrorCorrection=0.8,
                 stop2Bounce=0,
                 stop2ErrorCorrection=0.8,
                 stop3Bounce=0,
                 stop3ErrorCorrection=0.8,
                 body1=None,
                 body2=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MotorJoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.autoCalc = autoCalc
        self.axis1Angle = axis1Angle
        self.axis1Torque = axis1Torque
        self.axis2Angle = axis2Angle
        self.axis2Torque = axis2Torque
        self.axis3Angle = axis3Angle
        self.axis3Torque = axis3Torque
        self.enabledAxes = enabledAxes
        self.forceOutput = forceOutput
        self.motor1Axis = motor1Axis
        self.motor2Axis = motor2Axis
        self.motor3Axis = motor3Axis
        self.stop1Bounce = stop1Bounce
        self.stop1ErrorCorrection = stop1ErrorCorrection
        self.stop2Bounce = stop2Bounce
        self.stop2ErrorCorrection = stop2ErrorCorrection
        self.stop3Bounce = stop3Bounce
        self.stop3ErrorCorrection = stop3ErrorCorrection
        self.body1 = body1
        self.body2 = body2
    @property # getter - - - - - - - - - -
    def autoCalc(self):
        """autoCalc controls whether user manually provides individual angle rotations each frame (false) or if angle values are automatically calculated by motor implementations (true)."""
        return self.__autoCalc
    @autoCalc.setter
    def autoCalc(self, autoCalc=None):
        if  autoCalc is None:
            autoCalc = SFBool.DEFAULT_VALUE
        assertValidSFBool(autoCalc)
        self.__autoCalc = autoCalc
    @property # getter - - - - - - - - - -
    def axis1Angle(self):
        """axis1Angle (radians) is rotation angle for corresponding motor axis when in user-calculated mode."""
        return self.__axis1Angle
    @axis1Angle.setter
    def axis1Angle(self, axis1Angle=None):
        if  axis1Angle is None:
            axis1Angle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(axis1Angle)
        self.__axis1Angle = axis1Angle
    @property # getter - - - - - - - - - -
    def axis1Torque(self):
        """axis1Torque is rotational torque applied by corresponding motor axis when in user-calculated mode."""
        return self.__axis1Torque
    @axis1Torque.setter
    def axis1Torque(self, axis1Torque=None):
        if  axis1Torque is None:
            axis1Torque = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(axis1Torque)
        self.__axis1Torque = axis1Torque
    @property # getter - - - - - - - - - -
    def axis2Angle(self):
        """axis2Angle (radians) is rotation angle for corresponding motor axis when in user-calculated mode."""
        return self.__axis2Angle
    @axis2Angle.setter
    def axis2Angle(self, axis2Angle=None):
        if  axis2Angle is None:
            axis2Angle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(axis2Angle)
        self.__axis2Angle = axis2Angle
    @property # getter - - - - - - - - - -
    def axis2Torque(self):
        """axis2Torque is rotational torque applied by corresponding motor axis when in user-calculated mode."""
        return self.__axis2Torque
    @axis2Torque.setter
    def axis2Torque(self, axis2Torque=None):
        if  axis2Torque is None:
            axis2Torque = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(axis2Torque)
        self.__axis2Torque = axis2Torque
    @property # getter - - - - - - - - - -
    def axis3Angle(self):
        """axis3Angle (radians) is rotation angle for corresponding motor axis when in user-calculated mode."""
        return self.__axis3Angle
    @axis3Angle.setter
    def axis3Angle(self, axis3Angle=None):
        if  axis3Angle is None:
            axis3Angle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(axis3Angle)
        self.__axis3Angle = axis3Angle
    @property # getter - - - - - - - - - -
    def axis3Torque(self):
        """axis3Torque is rotational torque applied by corresponding motor axis when in user-calculated mode."""
        return self.__axis3Torque
    @axis3Torque.setter
    def axis3Torque(self, axis3Torque=None):
        if  axis3Torque is None:
            axis3Torque = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(axis3Torque)
        self.__axis3Torque = axis3Torque
    @property # getter - - - - - - - - - -
    def enabledAxes(self):
        """[0,3] enabledAxes indicates which motor axes are active."""
        return self.__enabledAxes
    @enabledAxes.setter
    def enabledAxes(self, enabledAxes=None):
        if  enabledAxes is None:
            enabledAxes = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(enabledAxes)
        assertGreaterThanEquals('enabledAxes', enabledAxes, 0)
        assertLessThanEquals('enabledAxes', enabledAxes, 3)
        self.__enabledAxes = enabledAxes
    @property # getter - - - - - - - - - -
    def forceOutput(self):
        """forceOutput controls which output fields are generated for the next frame."""
        return self.__forceOutput
    @forceOutput.setter
    def forceOutput(self, forceOutput=None):
        if  forceOutput is None:
            forceOutput = MFString.DEFAULT_VALUE
        assertValidMFString(forceOutput)
        self.__forceOutput = forceOutput
    @property # getter - - - - - - - - - -
    def motor1Axis(self):
        """motor1Axis defines axis vector of corresponding motor axis."""
        return self.__motor1Axis
    @motor1Axis.setter
    def motor1Axis(self, motor1Axis=None):
        if  motor1Axis is None:
            motor1Axis = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(motor1Axis)
        self.__motor1Axis = motor1Axis
    @property # getter - - - - - - - - - -
    def motor2Axis(self):
        """motor2Axis defines axis vector of corresponding motor axis."""
        return self.__motor2Axis
    @motor2Axis.setter
    def motor2Axis(self, motor2Axis=None):
        if  motor2Axis is None:
            motor2Axis = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(motor2Axis)
        self.__motor2Axis = motor2Axis
    @property # getter - - - - - - - - - -
    def motor3Axis(self):
        """motor3Axis defines axis vector of corresponding motor axis."""
        return self.__motor3Axis
    @motor3Axis.setter
    def motor3Axis(self, motor3Axis=None):
        if  motor3Axis is None:
            motor3Axis = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(motor3Axis)
        self.__motor3Axis = motor3Axis
    @property # getter - - - - - - - - - -
    def stop1Bounce(self):
        """[0,1] stop1Bounce is velocity factor for bounce back once stop point is reached."""
        return self.__stop1Bounce
    @stop1Bounce.setter
    def stop1Bounce(self, stop1Bounce=None):
        if  stop1Bounce is None:
            stop1Bounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop1Bounce)
        self.__stop1Bounce = stop1Bounce
    @property # getter - - - - - - - - - -
    def stop1ErrorCorrection(self):
        """[0,1] stop1ErrorCorrection is fraction of error correction performed during time step once stop point is reached."""
        return self.__stop1ErrorCorrection
    @stop1ErrorCorrection.setter
    def stop1ErrorCorrection(self, stop1ErrorCorrection=None):
        if  stop1ErrorCorrection is None:
            stop1ErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop1ErrorCorrection)
        self.__stop1ErrorCorrection = stop1ErrorCorrection
    @property # getter - - - - - - - - - -
    def stop2Bounce(self):
        """[0,1] stop2Bounce is velocity factor for bounce back once stop point is reached."""
        return self.__stop2Bounce
    @stop2Bounce.setter
    def stop2Bounce(self, stop2Bounce=None):
        if  stop2Bounce is None:
            stop2Bounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop2Bounce)
        self.__stop2Bounce = stop2Bounce
    @property # getter - - - - - - - - - -
    def stop2ErrorCorrection(self):
        """[0,1] stop2ErrorCorrection is fraction of error correction performed during time step once stop point is reached."""
        return self.__stop2ErrorCorrection
    @stop2ErrorCorrection.setter
    def stop2ErrorCorrection(self, stop2ErrorCorrection=None):
        if  stop2ErrorCorrection is None:
            stop2ErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop2ErrorCorrection)
        self.__stop2ErrorCorrection = stop2ErrorCorrection
    @property # getter - - - - - - - - - -
    def stop3Bounce(self):
        """[0,1] stop3Bounce is velocity factor for bounce back once stop point is reached."""
        return self.__stop3Bounce
    @stop3Bounce.setter
    def stop3Bounce(self, stop3Bounce=None):
        if  stop3Bounce is None:
            stop3Bounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop3Bounce)
        self.__stop3Bounce = stop3Bounce
    @property # getter - - - - - - - - - -
    def stop3ErrorCorrection(self):
        """[0,1] stop3ErrorCorrection is fraction of error correction performed during time step once stop point is reached."""
        return self.__stop3ErrorCorrection
    @stop3ErrorCorrection.setter
    def stop3ErrorCorrection(self, stop3ErrorCorrection=None):
        if  stop3ErrorCorrection is None:
            stop3ErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop3ErrorCorrection)
        self.__stop3ErrorCorrection = stop3ErrorCorrection
    @property # getter - - - - - - - - - -
    def body1(self):
        return self.__body1
    @body1.setter
    def body1(self, body1=None):
        if  body1 is None:
            body1 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body1)
        if not isinstance(body1, object):
            # print(flush=True)
            raise X3DTypeError(str(body1) + ' does not have a valid node type object')
        self.__body1 = body1
    @property # getter - - - - - - - - - -
    def body2(self):
        return self.__body2
    @body2.setter
    def body2(self, body2=None):
        if  body2 is None:
            body2 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body2)
        if not isinstance(body2, object):
            # print(flush=True)
            raise X3DTypeError(str(body2) + ' does not have a valid node type object')
        self.__body2 = body2
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.body1) or bool(self.body2) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MotorJoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MotorJoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.autoCalc != False:
            result += " autoCalc='" + SFBool(self.autoCalc).XML() + "'"
        if self.axis1Angle != 0:
            result += " axis1Angle='" + SFFloat(self.axis1Angle).XML() + "'"
        if self.axis1Torque != 0:
            result += " axis1Torque='" + SFFloat(self.axis1Torque).XML() + "'"
        if self.axis2Angle != 0:
            result += " axis2Angle='" + SFFloat(self.axis2Angle).XML() + "'"
        if self.axis2Torque != 0:
            result += " axis2Torque='" + SFFloat(self.axis2Torque).XML() + "'"
        if self.axis3Angle != 0:
            result += " axis3Angle='" + SFFloat(self.axis3Angle).XML() + "'"
        if self.axis3Torque != 0:
            result += " axis3Torque='" + SFFloat(self.axis3Torque).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabledAxes != 1:
            result += " enabledAxes='" + SFInt32(self.enabledAxes).XML() + "'"
        if self.forceOutput != ["NONE"]:
            result += " forceOutput='" + MFString(self.forceOutput).XML() + "'"
        if self.motor1Axis != (0, 0, 0):
            result += " motor1Axis='" + SFVec3f(self.motor1Axis).XML() + "'"
        if self.motor2Axis != (0, 0, 0):
            result += " motor2Axis='" + SFVec3f(self.motor2Axis).XML() + "'"
        if self.motor3Axis != (0, 0, 0):
            result += " motor3Axis='" + SFVec3f(self.motor3Axis).XML() + "'"
        if self.stop1Bounce != 0:
            result += " stop1Bounce='" + SFFloat(self.stop1Bounce).XML() + "'"
        if self.stop1ErrorCorrection != 0.8:
            result += " stop1ErrorCorrection='" + SFFloat(self.stop1ErrorCorrection).XML() + "'"
        if self.stop2Bounce != 0:
            result += " stop2Bounce='" + SFFloat(self.stop2Bounce).XML() + "'"
        if self.stop2ErrorCorrection != 0.8:
            result += " stop2ErrorCorrection='" + SFFloat(self.stop2ErrorCorrection).XML() + "'"
        if self.stop3Bounce != 0:
            result += " stop3Bounce='" + SFFloat(self.stop3Bounce).XML() + "'"
        if self.stop3ErrorCorrection != 0.8:
            result += " stop3ErrorCorrection='" + SFFloat(self.stop3ErrorCorrection).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.body1: # output this SFNode
                result += self.body1.XML(indentLevel=indentLevel+1)
            if self.body2: # output this SFNode
                result += self.body2.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</MotorJoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MovieTexture(_X3DSoundSourceNode, _X3DTexture2DNode, _X3DUrlObject):
    """
    MovieTexture applies a 2D movie image to surface geometry, or provides audio for a Sound node.
    """
    NAME = 'MovieTexture'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MovieTexture'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DSoundSourceNode'),
        ('loop', False, FieldType.SFBool, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('pauseTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('pitch', 1.0, FieldType.SFFloat, AccessType.inputOutput, 'X3DSoundSourceNode'),
        ('repeatS', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture2DNode'),
        ('repeatT', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture2DNode'),
        ('resumeTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('speed', 1.0, FieldType.SFFloat, AccessType.inputOutput, 'MovieTexture'),
        ('startTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('stopTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('textureProperties', None, FieldType.SFNode, AccessType.initializeOnly, 'MovieTexture'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 description='',
                 loop=False,
                 pauseTime=0,
                 pitch=1.0,
                 repeatS=True,
                 repeatT=True,
                 resumeTime=0,
                 speed=1.0,
                 startTime=0,
                 stopTime=0,
                 url=list(),
                 textureProperties=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MovieTexture __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.description = description
        self.loop = loop
        self.pauseTime = pauseTime
        self.pitch = pitch
        self.repeatS = repeatS
        self.repeatT = repeatT
        self.resumeTime = resumeTime
        self.speed = speed
        self.startTime = startTime
        self.stopTime = stopTime
        self.url = url
        self.textureProperties = textureProperties
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def loop(self):
        """Repeat indefinitely when loop=true, repeat only once when loop=false."""
        return self.__loop
    @loop.setter
    def loop(self, loop=None):
        if  loop is None:
            loop = SFBool.DEFAULT_VALUE
        assertValidSFBool(loop)
        self.__loop = loop
    @property # getter - - - - - - - - - -
    def pauseTime(self):
        """When time now >= pauseTime, isPaused becomes true and MovieTexture becomes paused."""
        return self.__pauseTime
    @pauseTime.setter
    def pauseTime(self, pauseTime=None):
        if  pauseTime is None:
            pauseTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(pauseTime)
        self.__pauseTime = pauseTime
    @property # getter - - - - - - - - - -
    def pitch(self):
        return self.__pitch
    @pitch.setter
    def pitch(self, pitch=None):
        if  pitch is None:
            pitch = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(pitch)
        assertPositive('pitch', pitch)
        self.__pitch = pitch
    @property # getter - - - - - - - - - -
    def repeatS(self):
        """Whether to horizontally repeat texture along S axis."""
        return self.__repeatS
    @repeatS.setter
    def repeatS(self, repeatS=None):
        if  repeatS is None:
            repeatS = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatS)
        self.__repeatS = repeatS
    @property # getter - - - - - - - - - -
    def repeatT(self):
        """Whether to vertically repeat texture along T axis."""
        return self.__repeatT
    @repeatT.setter
    def repeatT(self, repeatT=None):
        if  repeatT is None:
            repeatT = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatT)
        self.__repeatT = repeatT
    @property # getter - - - - - - - - - -
    def resumeTime(self):
        """When resumeTime becomes <= time now, isPaused becomes false and MovieTexture becomes active."""
        return self.__resumeTime
    @resumeTime.setter
    def resumeTime(self, resumeTime=None):
        if  resumeTime is None:
            resumeTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(resumeTime)
        self.__resumeTime = resumeTime
    @property # getter - - - - - - - - - -
    def speed(self):
        """Factor for how fast the movie (or soundtrack) is played."""
        return self.__speed
    @speed.setter
    def speed(self, speed=None):
        if  speed is None:
            speed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speed)
        self.__speed = speed
    @property # getter - - - - - - - - - -
    def startTime(self):
        """Absolute time: number of seconds since January 1, 1970, 00:00:00 GMT."""
        return self.__startTime
    @startTime.setter
    def startTime(self, startTime=None):
        if  startTime is None:
            startTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(startTime)
        self.__startTime = startTime
    @property # getter - - - - - - - - - -
    def stopTime(self):
        """Absolute time: number of seconds since January 1, 1970, 00:00:00 GMT."""
        return self.__stopTime
    @stopTime.setter
    def stopTime(self, stopTime=None):
        if  stopTime is None:
            stopTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(stopTime)
        self.__stopTime = stopTime
    @property # getter - - - - - - - - - -
    def url(self):
        """Location and filename of movie file or stream."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def textureProperties(self):
        return self.__textureProperties
    @textureProperties.setter
    def textureProperties(self, textureProperties=None):
        if  textureProperties is None:
            textureProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(textureProperties)
        if not isinstance(textureProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(textureProperties) + ' does not have a valid node type object')
        self.__textureProperties = textureProperties
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.textureProperties)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MovieTexture.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MovieTexture'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.loop != False:
            result += " loop='" + SFBool(self.loop).XML() + "'"
        if self.pauseTime != 0:
            result += " pauseTime='" + SFTime(self.pauseTime).XML() + "'"
        if self.pitch != 1.0:
            result += " pitch='" + SFFloat(self.pitch).XML() + "'"
        if self.repeatS != True:
            result += " repeatS='" + SFBool(self.repeatS).XML() + "'"
        if self.repeatT != True:
            result += " repeatT='" + SFBool(self.repeatT).XML() + "'"
        if self.resumeTime != 0:
            result += " resumeTime='" + SFTime(self.resumeTime).XML() + "'"
        if self.speed != 1.0:
            result += " speed='" + SFFloat(self.speed).XML() + "'"
        if self.startTime != 0:
            result += " startTime='" + SFTime(self.startTime).XML() + "'"
        if self.stopTime != 0:
            result += " stopTime='" + SFTime(self.stopTime).XML() + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.textureProperties: # output this SFNode
                result += self.textureProperties.XML(indentLevel=indentLevel+1)
            result += indent + '</MovieTexture>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MultiTexture(_X3DTextureNode):
    """
    MultiTexture applies several individual textures to a single geometry node, enabling a variety of visual effects that include light mapping and environment mapping.
    """
    NAME = 'MultiTexture'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MultiTexture'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('alpha', 1, FieldType.SFFloat, AccessType.inputOutput, 'MultiTexture'),
        ('color', (1, 1, 1), FieldType.SFColor, AccessType.inputOutput, 'MultiTexture'),
        ('function', list(), FieldType.MFString, AccessType.inputOutput, 'MultiTexture'),
        ('mode', list(), FieldType.MFString, AccessType.inputOutput, 'MultiTexture'),
        ('source', list(), FieldType.MFString, AccessType.inputOutput, 'MultiTexture'),
        ('texture', list(), FieldType.MFNode, AccessType.inputOutput, 'MultiTexture'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 alpha=1,
                 color=(1, 1, 1),
                 function=list(),
                 mode=list(),
                 source=list(),
                 texture=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MultiTexture __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.alpha = alpha
        self.color = color
        self.function = function
        self.mode = mode
        self.source = source
        self.texture = texture
    @property # getter - - - - - - - - - -
    def alpha(self):
        """[0,1] The alpha field defines the alpha (1-transparency) base value for mode operations."""
        return self.__alpha
    @alpha.setter
    def alpha(self, alpha=None):
        if  alpha is None:
            alpha = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(alpha)
        assertZeroToOne('alpha', alpha)
        self.__alpha = alpha
    @property # getter - - - - - - - - - -
    def color(self):
        """[0,1] The color field defines the RGB base values for mode operations."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFColor.DEFAULT_VALUE
        assertValidSFColor(color)
        assertZeroToOne('color', color)
        self.__color = color
    @property # getter - - - - - - - - - -
    def function(self):
        """function operators COMPLEMENT or ALPHAREPLICATE can be applied after the mode blending operation."""
        return self.__function
    @function.setter
    def function(self, function=None):
        if  function is None:
            function = MFString.DEFAULT_VALUE
        assertValidMFString(function)
        self.__function = function
    @property # getter - - - - - - - - - -
    def mode(self):
        """mode field indicates the type of blending operation, both for color and for alpha channel."""
        return self.__mode
    @mode.setter
    def mode(self, mode=None):
        if  mode is None:
            mode = MFString.DEFAULT_VALUE
        assertValidMFString(mode)
        self.__mode = mode
    @property # getter - - - - - - - - - -
    def source(self):
        """source field determines whether each image source is treated as DIFFUSE, SPECULAR or a multiplicative FACTOR."""
        return self.__source
    @source.setter
    def source(self, source=None):
        if  source is None:
            source = MFString.DEFAULT_VALUE
        assertValidMFString(source)
        self.__source = source
    @property # getter - - - - - - - - - -
    def texture(self):
        """[X3DTextureNode] Contained texture nodes (ImageTexture, MovieTexture, PixelTexture) that map image(s) to surface geometry, defining each of the different texture channels."""
        return self.__texture
    @texture.setter
    def texture(self, texture=None):
        if  texture is None:
            texture = MFNode.DEFAULT_VALUE
        assertValidMFNode(texture)
        self.__texture = texture
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.texture) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MultiTexture.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MultiTexture'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.alpha != 1:
            result += " alpha='" + SFFloat(self.alpha).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.color != (1, 1, 1):
            result += " color='" + SFColor(self.color).XML() + "'"
        if self.function != list():
            result += " function='" + MFString(self.function).XML() + "'"
        if self.mode != list():
            result += " mode='" + MFString(self.mode).XML() + "'"
        if self.source != list():
            result += " source='" + MFString(self.source).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.texture: # walk each child node, if any
                for each in self.texture:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</MultiTexture>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MultiTextureCoordinate(_X3DTextureCoordinateNode):
    """
    MultiTextureCoordinate contains multiple TextureCoordinate or TextureCoordinateGenerator nodes, for use by a parent polygonal geometry node such as IndexedFaceSet or a Triangle* node.
    """
    NAME = 'MultiTextureCoordinate'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MultiTextureCoordinate'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('texCoord', list(), FieldType.MFNode, AccessType.inputOutput, 'MultiTextureCoordinate'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 texCoord=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MultiTextureCoordinate __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.texCoord = texCoord
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Zero or more contained TextureCoordinate or TextureCoordinateGenerator nodes that specify texture coordinates for the different texture channels, used for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = MFNode.DEFAULT_VALUE
        assertValidMFNode(texCoord)
        self.__texCoord = texCoord
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.texCoord) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MultiTextureCoordinate.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MultiTextureCoordinate'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.texCoord: # walk each child node, if any
                for each in self.texCoord:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</MultiTextureCoordinate>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class MultiTextureTransform(_X3DTextureTransformNode):
    """
    MultiTextureTransform contains multiple TextureTransform nodes, each provided for use by corresponding ImageTexture MovieTexture or PixelTexture nodes within a sibling MultiTexture node.
    """
    NAME = 'MultiTextureTransform'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#MultiTextureTransform'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('textureTransform', list(), FieldType.MFNode, AccessType.inputOutput, 'MultiTextureTransform'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 textureTransform=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode MultiTextureTransform __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.textureTransform = textureTransform
    @property # getter - - - - - - - - - -
    def textureTransform(self):
        """[X3DTextureTransformNode] Zero or more contained TextureTransform nodes, for each of the different texture channels, that define 2D transformation applied to texture coordinates."""
        return self.__textureTransform
    @textureTransform.setter
    def textureTransform(self, textureTransform=None):
        if  textureTransform is None:
            textureTransform = MFNode.DEFAULT_VALUE
        assertValidMFNode(textureTransform)
        self.__textureTransform = textureTransform
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.textureTransform) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function MultiTextureTransform.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<MultiTextureTransform'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.textureTransform: # walk each child node, if any
                for each in self.textureTransform:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</MultiTextureTransform>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NavigationInfo(_X3DBindableNode):
    """
    NavigationInfo describes the user's viewing model, user navigation-interaction modalities, and also dimensional characteristics of the user's (typically invisible) avatar.
    """
    NAME = 'NavigationInfo'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NavigationInfo'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('avatarSize', [0.25, 1.6, 0.75], FieldType.MFFloat, AccessType.inputOutput, 'NavigationInfo'),
        ('headlight', True, FieldType.SFBool, AccessType.inputOutput, 'NavigationInfo'),
        ('speed', 1, FieldType.SFFloat, AccessType.inputOutput, 'NavigationInfo'),
        ('transitionTime', 1.0, FieldType.SFTime, AccessType.inputOutput, 'NavigationInfo'),
        ('transitionType', ["LINEAR"], FieldType.MFString, AccessType.inputOutput, 'NavigationInfo'),
        ('type', ["EXAMINE", "ANY"], FieldType.MFString, AccessType.inputOutput, 'NavigationInfo'),
        ('visibilityLimit', 0, FieldType.SFFloat, AccessType.inputOutput, 'NavigationInfo'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 avatarSize=[0.25, 1.6, 0.75],
                 headlight=True,
                 speed=1,
                 transitionTime=1.0,
                 transitionType=["LINEAR"],
                 type=["EXAMINE", "ANY"],
                 visibilityLimit=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NavigationInfo __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.avatarSize = avatarSize
        self.headlight = headlight
        self.speed = speed
        self.transitionTime = transitionTime
        self.transitionType = transitionType
        self.type = type
        self.visibilityLimit = visibilityLimit
    @property # getter - - - - - - - - - -
    def avatarSize(self):
        """avatarSize triplet values define three separate parameters: (a) collisionDistance between user and geometry, i."""
        return self.__avatarSize
    @avatarSize.setter
    def avatarSize(self, avatarSize=None):
        if  avatarSize is None:
            avatarSize = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(avatarSize)
        assertNonNegative('avatarSize', avatarSize)
        self.__avatarSize = avatarSize
    @property # getter - - - - - - - - - -
    def headlight(self):
        """Enable/disable directional light that always points in the direction the user is looking."""
        return self.__headlight
    @headlight.setter
    def headlight(self, headlight=None):
        if  headlight is None:
            headlight = SFBool.DEFAULT_VALUE
        assertValidSFBool(headlight)
        self.__headlight = headlight
    @property # getter - - - - - - - - - -
    def speed(self):
        """[0,+infinity) Default rate at which viewer travels through scene, meters/second."""
        return self.__speed
    @speed.setter
    def speed(self, speed=None):
        if  speed is None:
            speed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speed)
        assertNonNegative('speed', speed)
        self.__speed = speed
    @property # getter - - - - - - - - - -
    def transitionTime(self):
        """transitionTime defines the expected duration of viewpoint transition in seconds."""
        return self.__transitionTime
    @transitionTime.setter
    def transitionTime(self, transitionTime=None):
        if  transitionTime is None:
            transitionTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(transitionTime)
        assertNonNegative('transitionTime', transitionTime)
        self.__transitionTime = transitionTime
    @property # getter - - - - - - - - - -
    def transitionType(self):
        """Camera transition between viewpoints."""
        return self.__transitionType
    @transitionType.setter
    def transitionType(self, transitionType=None):
        if  transitionType is None:
            transitionType = MFString.DEFAULT_VALUE
        assertValidMFString(transitionType)
        self.__transitionType = transitionType
    @property # getter - - - - - - - - - -
    def type(self):
        """Enter one or more quoted SFString values: "EXAMINE" "WALK" "FLY" "LOOKAT" "EXPLORE" "ANY" "NONE"."""
        return self.__type
    @type.setter
    def type(self, type=None):
        if  type is None:
            type = MFString.DEFAULT_VALUE
        assertValidMFString(type)
        self.__type = type
    @property # getter - - - - - - - - - -
    def visibilityLimit(self):
        """Geometry beyond the visibilityLimit may not be rendered (far clipping plane of the view frustrum)."""
        return self.__visibilityLimit
    @visibilityLimit.setter
    def visibilityLimit(self, visibilityLimit=None):
        if  visibilityLimit is None:
            visibilityLimit = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(visibilityLimit)
        assertNonNegative('visibilityLimit', visibilityLimit)
        self.__visibilityLimit = visibilityLimit
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NavigationInfo.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NavigationInfo'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.avatarSize != [0.25, 1.6, 0.75]:
            result += " avatarSize='" + MFFloat(self.avatarSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.headlight != True:
            result += " headlight='" + SFBool(self.headlight).XML() + "'"
        if self.speed != 1:
            result += " speed='" + SFFloat(self.speed).XML() + "'"
        if self.transitionTime != 1.0:
            result += " transitionTime='" + SFTime(self.transitionTime).XML() + "'"
        if self.transitionType != ["LINEAR"]:
            result += " transitionType='" + MFString(self.transitionType).XML() + "'"
        if self.type != ["EXAMINE", "ANY"]:
            result += " type='" + MFString(self.type).XML() + "'"
        if self.visibilityLimit != 0:
            result += " visibilityLimit='" + SFFloat(self.visibilityLimit).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</NavigationInfo>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Normal(_X3DNormalNode):
    """
    Normal defines a set of 3D surface-normal vectors that apply either to a sibling Coordinate|CoordinateDouble node, or else to a parent ElevationGrid node.
    """
    NAME = 'Normal'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Normal'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('vector', list(), FieldType.MFVec3f, AccessType.inputOutput, 'Normal'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 vector=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Normal __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.vector = vector
    @property # getter - - - - - - - - - -
    def vector(self):
        """set of unit-length normal vectors, corresponding to indexed polygons or vertices."""
        return self.__vector
    @vector.setter
    def vector(self, vector=None):
        if  vector is None:
            vector = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(vector)
        assertGreaterThanEquals('vector', vector, -1)
        assertLessThanEquals('vector', vector, 1)
        self.__vector = vector
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Normal.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Normal'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.vector != list():
            result += " vector='" + MFVec3f(self.vector).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Normal>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NormalInterpolator(_X3DInterpolatorNode):
    """
    NormalInterpolator generates a series of normal (perpendicular) 3-tuple SFVec3f values.
    """
    NAME = 'NormalInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NormalInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFVec3f, AccessType.inputOutput, 'NormalInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NormalInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NormalInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NormalInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFVec3f(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</NormalInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsCurve(_X3DParametricGeometryNode):
    """
    NurbsCurve is a 3D curve analogous to NurbsPatchSurface.
    """
    NAME = 'NurbsCurve'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsCurve'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('closed', False, FieldType.SFBool, AccessType.initializeOnly, 'NurbsCurve'),
        ('knot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'NurbsCurve'),
        ('order', 3, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsCurve'),
        ('tessellation', 0, FieldType.SFInt32, AccessType.inputOutput, 'NurbsCurve'),
        ('weight', list(), FieldType.MFDouble, AccessType.inputOutput, 'NurbsCurve'),
        ('controlPoint', None, FieldType.SFNode, AccessType.inputOutput, 'NurbsCurve'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 closed=False,
                 knot=list(),
                 order=3,
                 tessellation=0,
                 weight=list(),
                 controlPoint=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsCurve __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.closed = closed
        self.knot = knot
        self.order = order
        self.tessellation = tessellation
        self.weight = weight
        self.controlPoint = controlPoint
    @property # getter - - - - - - - - - -
    def closed(self):
        """Whether or not the curve is closed (i."""
        return self.__closed
    @closed.setter
    def closed(self, closed=None):
        if  closed is None:
            closed = SFBool.DEFAULT_VALUE
        assertValidSFBool(closed)
        self.__closed = closed
    @property # getter - - - - - - - - - -
    def knot(self):
        """knot vector, where size = number of control points + order of curve."""
        return self.__knot
    @knot.setter
    def knot(self, knot=None):
        if  knot is None:
            knot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(knot)
        self.__knot = knot
    @property # getter - - - - - - - - - -
    def order(self):
        """define order of surface by polynomials of degree = order-1."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 2)
        self.__order = order
    @property # getter - - - - - - - - - -
    def tessellation(self):
        """hint for surface tesselation."""
        return self.__tessellation
    @tessellation.setter
    def tessellation(self, tessellation=None):
        if  tessellation is None:
            tessellation = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(tessellation)
        self.__tessellation = tessellation
    @property # getter - - - - - - - - - -
    def weight(self):
        """Vector assigning relative weight value to each control point."""
        return self.__weight
    @weight.setter
    def weight(self, weight=None):
        if  weight is None:
            weight = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(weight)
        assertPositive('weight', weight)
        self.__weight = weight
    @property # getter - - - - - - - - - -
    def controlPoint(self):
        return self.__controlPoint
    @controlPoint.setter
    def controlPoint(self, controlPoint=None):
        if  controlPoint is None:
            controlPoint = SFNode.DEFAULT_VALUE
        assertValidSFNode(controlPoint)
        if not isinstance(controlPoint, object):
            # print(flush=True)
            raise X3DTypeError(str(controlPoint) + ' does not have a valid node type object')
        self.__controlPoint = controlPoint
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.controlPoint) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsCurve.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsCurve'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.closed != False:
            result += " closed='" + SFBool(self.closed).XML() + "'"
        if self.knot != list():
            result += " knot='" + MFDouble(self.knot).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.tessellation != 0:
            result += " tessellation='" + SFInt32(self.tessellation).XML() + "'"
        if self.weight != list():
            result += " weight='" + MFDouble(self.weight).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.controlPoint: # output this SFNode
                result += self.controlPoint.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsCurve>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsCurve2D(_X3DNurbsControlCurveNode):
    """
    NurbsCurve2D defines a trimming segment that is part of a trimming contour in the u-v domain of a surface.
    """
    NAME = 'NurbsCurve2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsCurve2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('closed', False, FieldType.SFBool, AccessType.initializeOnly, 'NurbsCurve2D'),
        ('controlPoint', list(), FieldType.MFVec2d, AccessType.inputOutput, 'X3DNurbsControlCurveNode'),
        ('knot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'NurbsCurve2D'),
        ('order', 3, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsCurve2D'),
        ('tessellation', 0, FieldType.SFInt32, AccessType.inputOutput, 'NurbsCurve2D'),
        ('weight', list(), FieldType.MFDouble, AccessType.inputOutput, 'NurbsCurve2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 closed=False,
                 controlPoint=list(),
                 knot=list(),
                 order=3,
                 tessellation=0,
                 weight=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsCurve2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.closed = closed
        self.controlPoint = controlPoint
        self.knot = knot
        self.order = order
        self.tessellation = tessellation
        self.weight = weight
    @property # getter - - - - - - - - - -
    def closed(self):
        """Whether or not the curve is closed (i."""
        return self.__closed
    @closed.setter
    def closed(self, closed=None):
        if  closed is None:
            closed = SFBool.DEFAULT_VALUE
        assertValidSFBool(closed)
        self.__closed = closed
    @property # getter - - - - - - - - - -
    def controlPoint(self):
        """controlPoint defines a set of control points of dimension uDimension by vDimension, and defines a mesh where the points do not have uniform spacing."""
        return self.__controlPoint
    @controlPoint.setter
    def controlPoint(self, controlPoint=None):
        if  controlPoint is None:
            controlPoint = MFVec2d.DEFAULT_VALUE
        assertValidMFVec2d(controlPoint)
        self.__controlPoint = controlPoint
    @property # getter - - - - - - - - - -
    def knot(self):
        """knot vector, where size = number of control points + order of curve."""
        return self.__knot
    @knot.setter
    def knot(self, knot=None):
        if  knot is None:
            knot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(knot)
        self.__knot = knot
    @property # getter - - - - - - - - - -
    def order(self):
        """define order of surface by polynomials of degree = order-1."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 2)
        self.__order = order
    @property # getter - - - - - - - - - -
    def tessellation(self):
        """hint for surface tesselation."""
        return self.__tessellation
    @tessellation.setter
    def tessellation(self, tessellation=None):
        if  tessellation is None:
            tessellation = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(tessellation)
        self.__tessellation = tessellation
    @property # getter - - - - - - - - - -
    def weight(self):
        """Vector assigning relative weight value to each control point."""
        return self.__weight
    @weight.setter
    def weight(self, weight=None):
        if  weight is None:
            weight = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(weight)
        assertPositive('weight', weight)
        self.__weight = weight
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsCurve2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsCurve2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.closed != False:
            result += " closed='" + SFBool(self.closed).XML() + "'"
        if self.controlPoint != list():
            result += " controlPoint='" + MFVec2d(self.controlPoint).XML() + "'"
        if self.knot != list():
            result += " knot='" + MFDouble(self.knot).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.tessellation != 0:
            result += " tessellation='" + SFInt32(self.tessellation).XML() + "'"
        if self.weight != list():
            result += " weight='" + MFDouble(self.weight).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsCurve2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsOrientationInterpolator(_X3DChildNode):
    """
    NurbsOrientationInterpolator describes a 3D NURBS curve and outputs interpolated orientation values.
    """
    NAME = 'NurbsOrientationInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsOrientationInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('knot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'NurbsOrientationInterpolator'),
        ('order', 3, FieldType.SFInt32, AccessType.inputOutput, 'NurbsOrientationInterpolator'),
        ('weight', list(), FieldType.MFDouble, AccessType.inputOutput, 'NurbsOrientationInterpolator'),
        ('controlPoint', None, FieldType.SFNode, AccessType.inputOutput, 'NurbsOrientationInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 knot=list(),
                 order=3,
                 weight=list(),
                 controlPoint=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsOrientationInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.knot = knot
        self.order = order
        self.weight = weight
        self.controlPoint = controlPoint
    @property # getter - - - - - - - - - -
    def knot(self):
        """knot vector, where size = number of control points + order of curve."""
        return self.__knot
    @knot.setter
    def knot(self, knot=None):
        if  knot is None:
            knot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(knot)
        self.__knot = knot
    @property # getter - - - - - - - - - -
    def order(self):
        """define order of surface by polynomials of degree = order-1."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 2)
        self.__order = order
    @property # getter - - - - - - - - - -
    def weight(self):
        """Output values for computational interpolation, each corresponding to knots."""
        return self.__weight
    @weight.setter
    def weight(self, weight=None):
        if  weight is None:
            weight = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(weight)
        self.__weight = weight
    @property # getter - - - - - - - - - -
    def controlPoint(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies control points for NURBS geometry definitions."""
        return self.__controlPoint
    @controlPoint.setter
    def controlPoint(self, controlPoint=None):
        if  controlPoint is None:
            controlPoint = SFNode.DEFAULT_VALUE
        assertValidSFNode(controlPoint)
        if not isinstance(controlPoint, object):
            # print(flush=True)
            raise X3DTypeError(str(controlPoint) + ' does not have a valid node type object')
        self.__controlPoint = controlPoint
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.controlPoint) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsOrientationInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsOrientationInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.knot != list():
            result += " knot='" + MFDouble(self.knot).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.weight != list():
            result += " weight='" + MFDouble(self.weight).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.controlPoint: # output this SFNode
                result += self.controlPoint.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsOrientationInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsPatchSurface(_X3DNurbsSurfaceGeometryNode):
    """
    NurbsPatchSurface defines a contiguous 3D Non-Uniform Rational B-Spline (NURBS) surface.
    """
    NAME = 'NurbsPatchSurface'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsPatchSurface'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uClosed', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uDimension', 0, FieldType.SFInt32, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uKnot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uOrder', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uTessellation', 0, FieldType.SFInt32, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('vClosed', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('vDimension', 0, FieldType.SFInt32, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('vKnot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('vOrder', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('vTessellation', 0, FieldType.SFInt32, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('weight', list(), FieldType.MFDouble, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('controlPoint', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 solid=True,
                 uClosed=False,
                 uDimension=0,
                 uKnot=list(),
                 uOrder=3,
                 uTessellation=0,
                 vClosed=False,
                 vDimension=0,
                 vKnot=list(),
                 vOrder=3,
                 vTessellation=0,
                 weight=list(),
                 controlPoint=None,
                 texCoord=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsPatchSurface __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.solid = solid
        self.uClosed = uClosed
        self.uDimension = uDimension
        self.uKnot = uKnot
        self.uOrder = uOrder
        self.uTessellation = uTessellation
        self.vClosed = vClosed
        self.vDimension = vDimension
        self.vKnot = vKnot
        self.vOrder = vOrder
        self.vTessellation = vTessellation
        self.weight = weight
        self.controlPoint = controlPoint
        self.texCoord = texCoord
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def uClosed(self):
        """Whether opposite surface sides are closed (seamless) across u dimension."""
        return self.__uClosed
    @uClosed.setter
    def uClosed(self, uClosed=None):
        if  uClosed is None:
            uClosed = SFBool.DEFAULT_VALUE
        assertValidSFBool(uClosed)
        self.__uClosed = uClosed
    @property # getter - - - - - - - - - -
    def uDimension(self):
        """Number of control points in u dimension."""
        return self.__uDimension
    @uDimension.setter
    def uDimension(self, uDimension=None):
        if  uDimension is None:
            uDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uDimension)
        assertNonNegative('uDimension', uDimension)
        self.__uDimension = uDimension
    @property # getter - - - - - - - - - -
    def uKnot(self):
        """knot vector, where size = number of control points + order of curve."""
        return self.__uKnot
    @uKnot.setter
    def uKnot(self, uKnot=None):
        if  uKnot is None:
            uKnot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(uKnot)
        self.__uKnot = uKnot
    @property # getter - - - - - - - - - -
    def uOrder(self):
        """define order of surface by polynomials of degree = order-1."""
        return self.__uOrder
    @uOrder.setter
    def uOrder(self, uOrder=None):
        if  uOrder is None:
            uOrder = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uOrder)
        assertGreaterThanEquals('uOrder', uOrder, 2)
        self.__uOrder = uOrder
    @property # getter - - - - - - - - - -
    def uTessellation(self):
        """hint for surface tesselation."""
        return self.__uTessellation
    @uTessellation.setter
    def uTessellation(self, uTessellation=None):
        if  uTessellation is None:
            uTessellation = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uTessellation)
        self.__uTessellation = uTessellation
    @property # getter - - - - - - - - - -
    def vClosed(self):
        """Whether opposite surface sides are closed (seamless) across u dimension."""
        return self.__vClosed
    @vClosed.setter
    def vClosed(self, vClosed=None):
        if  vClosed is None:
            vClosed = SFBool.DEFAULT_VALUE
        assertValidSFBool(vClosed)
        self.__vClosed = vClosed
    @property # getter - - - - - - - - - -
    def vDimension(self):
        """Number of control points in v dimension."""
        return self.__vDimension
    @vDimension.setter
    def vDimension(self, vDimension=None):
        if  vDimension is None:
            vDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vDimension)
        assertNonNegative('vDimension', vDimension)
        self.__vDimension = vDimension
    @property # getter - - - - - - - - - -
    def vKnot(self):
        """knot vector, where size = number of control points + order of curve."""
        return self.__vKnot
    @vKnot.setter
    def vKnot(self, vKnot=None):
        if  vKnot is None:
            vKnot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(vKnot)
        self.__vKnot = vKnot
    @property # getter - - - - - - - - - -
    def vOrder(self):
        """define order of surface by polynomials of degree = order-1."""
        return self.__vOrder
    @vOrder.setter
    def vOrder(self, vOrder=None):
        if  vOrder is None:
            vOrder = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vOrder)
        assertGreaterThanEquals('vOrder', vOrder, 2)
        self.__vOrder = vOrder
    @property # getter - - - - - - - - - -
    def vTessellation(self):
        """hint for surface tesselation."""
        return self.__vTessellation
    @vTessellation.setter
    def vTessellation(self, vTessellation=None):
        if  vTessellation is None:
            vTessellation = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vTessellation)
        self.__vTessellation = vTessellation
    @property # getter - - - - - - - - - -
    def weight(self):
        """Vector assigning relative weight value to each control point."""
        return self.__weight
    @weight.setter
    def weight(self, weight=None):
        if  weight is None:
            weight = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(weight)
        assertPositive('weight', weight)
        self.__weight = weight
    @property # getter - - - - - - - - - -
    def controlPoint(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies control points for NURBS geometry definitions."""
        return self.__controlPoint
    @controlPoint.setter
    def controlPoint(self, controlPoint=None):
        if  controlPoint is None:
            controlPoint = SFNode.DEFAULT_VALUE
        assertValidSFNode(controlPoint)
        if not isinstance(controlPoint, object):
            # print(flush=True)
            raise X3DTypeError(str(controlPoint) + ' does not have a valid node type object')
        self.__controlPoint = controlPoint
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode|NurbsTextureCoordinate] Single contained NurbsTextureCoordinate, TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.controlPoint) or bool(self.IS) or bool(self.metadata) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsPatchSurface.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsPatchSurface'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.uClosed != False:
            result += " uClosed='" + SFBool(self.uClosed).XML() + "'"
        if self.uDimension != 0:
            result += " uDimension='" + SFInt32(self.uDimension).XML() + "'"
        if self.uKnot != list():
            result += " uKnot='" + MFDouble(self.uKnot).XML() + "'"
        if self.uOrder != 3:
            result += " uOrder='" + SFInt32(self.uOrder).XML() + "'"
        if self.uTessellation != 0:
            result += " uTessellation='" + SFInt32(self.uTessellation).XML() + "'"
        if self.vClosed != False:
            result += " vClosed='" + SFBool(self.vClosed).XML() + "'"
        if self.vDimension != 0:
            result += " vDimension='" + SFInt32(self.vDimension).XML() + "'"
        if self.vKnot != list():
            result += " vKnot='" + MFDouble(self.vKnot).XML() + "'"
        if self.vOrder != 3:
            result += " vOrder='" + SFInt32(self.vOrder).XML() + "'"
        if self.vTessellation != 0:
            result += " vTessellation='" + SFInt32(self.vTessellation).XML() + "'"
        if self.weight != list():
            result += " weight='" + MFDouble(self.weight).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.controlPoint: # output this SFNode
                result += self.controlPoint.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsPatchSurface>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsPositionInterpolator(_X3DChildNode):
    """
    NurbsPositionInterpolator describes a 3D NURBS curve and outputs interpolated position values.
    """
    NAME = 'NurbsPositionInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsPositionInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('knot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'NurbsPositionInterpolator'),
        ('order', 3, FieldType.SFInt32, AccessType.inputOutput, 'NurbsPositionInterpolator'),
        ('weight', list(), FieldType.MFDouble, AccessType.inputOutput, 'NurbsPositionInterpolator'),
        ('controlPoint', None, FieldType.SFNode, AccessType.inputOutput, 'NurbsPositionInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 knot=list(),
                 order=3,
                 weight=list(),
                 controlPoint=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsPositionInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.knot = knot
        self.order = order
        self.weight = weight
        self.controlPoint = controlPoint
    @property # getter - - - - - - - - - -
    def knot(self):
        """knot vector, where size = number of control points + order of curve."""
        return self.__knot
    @knot.setter
    def knot(self, knot=None):
        if  knot is None:
            knot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(knot)
        self.__knot = knot
    @property # getter - - - - - - - - - -
    def order(self):
        """define order of surface by polynomials of degree = order-1."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 2)
        self.__order = order
    @property # getter - - - - - - - - - -
    def weight(self):
        """Output values for linear interpolation, each corresponding to knots."""
        return self.__weight
    @weight.setter
    def weight(self, weight=None):
        if  weight is None:
            weight = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(weight)
        self.__weight = weight
    @property # getter - - - - - - - - - -
    def controlPoint(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies control points for NURBS geometry definitions."""
        return self.__controlPoint
    @controlPoint.setter
    def controlPoint(self, controlPoint=None):
        if  controlPoint is None:
            controlPoint = SFNode.DEFAULT_VALUE
        assertValidSFNode(controlPoint)
        if not isinstance(controlPoint, object):
            # print(flush=True)
            raise X3DTypeError(str(controlPoint) + ' does not have a valid node type object')
        self.__controlPoint = controlPoint
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.controlPoint) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsPositionInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsPositionInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.knot != list():
            result += " knot='" + MFDouble(self.knot).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.weight != list():
            result += " weight='" + MFDouble(self.weight).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.controlPoint: # output this SFNode
                result += self.controlPoint.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsPositionInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsSet(_X3DChildNode, _X3DBoundedObject):
    """
    NurbsSet collects a set of NurbsSurface nodes into a common group and treats NurbsSurface set as a unit during tessellation, thereby enforcing tessellation continuity along borders.
    """
    NAME = 'NurbsSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('tessellationScale', 1.0, FieldType.SFFloat, AccessType.inputOutput, 'NurbsSet'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('geometry', list(), FieldType.MFNode, AccessType.inputOutput, 'NurbsSet'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 tessellationScale=1.0,
                 visible=True,
                 geometry=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.tessellationScale = tessellationScale
        self.visible = visible
        self.geometry = geometry
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def tessellationScale(self):
        """scale for surface tesselation in children NurbsSurface nodes."""
        return self.__tessellationScale
    @tessellationScale.setter
    def tessellationScale(self, tessellationScale=None):
        if  tessellationScale is None:
            tessellationScale = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(tessellationScale)
        assertPositive('tessellationScale', tessellationScale)
        self.__tessellationScale = tessellationScale
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def geometry(self):
        """[NurbsPatchSurface|NurbsTrimmedSurface] The children form a closed loop with first point of first child repeated as last point of last child, and the last point of a segment repeated as first point of the consecutive one."""
        return self.__geometry
    @geometry.setter
    def geometry(self, geometry=None):
        if  geometry is None:
            geometry = MFNode.DEFAULT_VALUE
        assertValidMFNode(geometry)
        self.__geometry = geometry
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.geometry) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.tessellationScale != 1.0:
            result += " tessellationScale='" + SFFloat(self.tessellationScale).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.geometry: # walk each child node, if any
                for each in self.geometry:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsSurfaceInterpolator(_X3DChildNode):
    """
    NurbsSurfaceInterpolator describes a 3D NURBS curve and outputs interpolated position and normal values.
    """
    NAME = 'NurbsSurfaceInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsSurfaceInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('uDimension', 0, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsSurfaceInterpolator'),
        ('uKnot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'NurbsSurfaceInterpolator'),
        ('uOrder', 3, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsSurfaceInterpolator'),
        ('vDimension', 0, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsSurfaceInterpolator'),
        ('vKnot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'NurbsSurfaceInterpolator'),
        ('vOrder', 3, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsSurfaceInterpolator'),
        ('weight', list(), FieldType.MFDouble, AccessType.inputOutput, 'NurbsSurfaceInterpolator'),
        ('controlPoint', None, FieldType.SFNode, AccessType.inputOutput, 'NurbsSurfaceInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 uDimension=0,
                 uKnot=list(),
                 uOrder=3,
                 vDimension=0,
                 vKnot=list(),
                 vOrder=3,
                 weight=list(),
                 controlPoint=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsSurfaceInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.uDimension = uDimension
        self.uKnot = uKnot
        self.uOrder = uOrder
        self.vDimension = vDimension
        self.vKnot = vKnot
        self.vOrder = vOrder
        self.weight = weight
        self.controlPoint = controlPoint
    @property # getter - - - - - - - - - -
    def uDimension(self):
        """Number of control points in u dimension."""
        return self.__uDimension
    @uDimension.setter
    def uDimension(self, uDimension=None):
        if  uDimension is None:
            uDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uDimension)
        assertNonNegative('uDimension', uDimension)
        self.__uDimension = uDimension
    @property # getter - - - - - - - - - -
    def uKnot(self):
        """Knot vector, where size = number of control points + order of curve."""
        return self.__uKnot
    @uKnot.setter
    def uKnot(self, uKnot=None):
        if  uKnot is None:
            uKnot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(uKnot)
        self.__uKnot = uKnot
    @property # getter - - - - - - - - - -
    def uOrder(self):
        """Define order of surface by polynomials of degree = order-1."""
        return self.__uOrder
    @uOrder.setter
    def uOrder(self, uOrder=None):
        if  uOrder is None:
            uOrder = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uOrder)
        assertGreaterThanEquals('uOrder', uOrder, 2)
        self.__uOrder = uOrder
    @property # getter - - - - - - - - - -
    def vDimension(self):
        """Number of control points in v dimension."""
        return self.__vDimension
    @vDimension.setter
    def vDimension(self, vDimension=None):
        if  vDimension is None:
            vDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vDimension)
        assertNonNegative('vDimension', vDimension)
        self.__vDimension = vDimension
    @property # getter - - - - - - - - - -
    def vKnot(self):
        """Knot vector, where size = number of control points + order of curve."""
        return self.__vKnot
    @vKnot.setter
    def vKnot(self, vKnot=None):
        if  vKnot is None:
            vKnot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(vKnot)
        self.__vKnot = vKnot
    @property # getter - - - - - - - - - -
    def vOrder(self):
        """Define order of surface by polynomials of degree = order-1."""
        return self.__vOrder
    @vOrder.setter
    def vOrder(self, vOrder=None):
        if  vOrder is None:
            vOrder = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vOrder)
        assertGreaterThanEquals('vOrder', vOrder, 2)
        self.__vOrder = vOrder
    @property # getter - - - - - - - - - -
    def weight(self):
        """Output values for linear interpolation, each corresponding to knots."""
        return self.__weight
    @weight.setter
    def weight(self, weight=None):
        if  weight is None:
            weight = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(weight)
        self.__weight = weight
    @property # getter - - - - - - - - - -
    def controlPoint(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies control points for NURBS geometry definitions."""
        return self.__controlPoint
    @controlPoint.setter
    def controlPoint(self, controlPoint=None):
        if  controlPoint is None:
            controlPoint = SFNode.DEFAULT_VALUE
        assertValidSFNode(controlPoint)
        if not isinstance(controlPoint, object):
            # print(flush=True)
            raise X3DTypeError(str(controlPoint) + ' does not have a valid node type object')
        self.__controlPoint = controlPoint
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.controlPoint) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsSurfaceInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsSurfaceInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.uDimension != 0:
            result += " uDimension='" + SFInt32(self.uDimension).XML() + "'"
        if self.uKnot != list():
            result += " uKnot='" + MFDouble(self.uKnot).XML() + "'"
        if self.uOrder != 3:
            result += " uOrder='" + SFInt32(self.uOrder).XML() + "'"
        if self.vDimension != 0:
            result += " vDimension='" + SFInt32(self.vDimension).XML() + "'"
        if self.vKnot != list():
            result += " vKnot='" + MFDouble(self.vKnot).XML() + "'"
        if self.vOrder != 3:
            result += " vOrder='" + SFInt32(self.vOrder).XML() + "'"
        if self.weight != list():
            result += " weight='" + MFDouble(self.weight).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.controlPoint: # output this SFNode
                result += self.controlPoint.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsSurfaceInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsSweptSurface(_X3DParametricGeometryNode):
    """
    NurbsSweptSurface contains a crossSectionCurve and a trajectoryCurve [NurbsCurve].
    """
    NAME = 'NurbsSweptSurface'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsSweptSurface'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'NurbsSweptSurface'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'NurbsSweptSurface'),
        ('crossSectionCurve', None, FieldType.SFNode, AccessType.inputOutput, 'NurbsSweptSurface'),
        ('trajectoryCurve', None, FieldType.SFNode, AccessType.inputOutput, 'NurbsSweptSurface'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 solid=True,
                 crossSectionCurve=None,
                 trajectoryCurve=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsSweptSurface __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.solid = solid
        self.crossSectionCurve = crossSectionCurve
        self.trajectoryCurve = trajectoryCurve
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def crossSectionCurve(self):
        return self.__crossSectionCurve
    @crossSectionCurve.setter
    def crossSectionCurve(self, crossSectionCurve=None):
        if  crossSectionCurve is None:
            crossSectionCurve = SFNode.DEFAULT_VALUE
        assertValidSFNode(crossSectionCurve)
        if not isinstance(crossSectionCurve, object):
            # print(flush=True)
            raise X3DTypeError(str(crossSectionCurve) + ' does not have a valid node type object')
        self.__crossSectionCurve = crossSectionCurve
    @property # getter - - - - - - - - - -
    def trajectoryCurve(self):
        return self.__trajectoryCurve
    @trajectoryCurve.setter
    def trajectoryCurve(self, trajectoryCurve=None):
        if  trajectoryCurve is None:
            trajectoryCurve = SFNode.DEFAULT_VALUE
        assertValidSFNode(trajectoryCurve)
        if not isinstance(trajectoryCurve, object):
            # print(flush=True)
            raise X3DTypeError(str(trajectoryCurve) + ' does not have a valid node type object')
        self.__trajectoryCurve = trajectoryCurve
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.crossSectionCurve) or bool(self.IS) or bool(self.metadata) or bool(self.trajectoryCurve)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsSweptSurface.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsSweptSurface'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.crossSectionCurve: # output this SFNode
                result += self.crossSectionCurve.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.trajectoryCurve: # output this SFNode
                result += self.trajectoryCurve.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsSweptSurface>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsSwungSurface(_X3DParametricGeometryNode):
    """
    NurbsSwungSurface contains a profileCurve and a trajectoryCurve [X3DNurbsControlCurveNode].
    """
    NAME = 'NurbsSwungSurface'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsSwungSurface'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'NurbsSwungSurface'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'NurbsSwungSurface'),
        ('profileCurve', None, FieldType.SFNode, AccessType.inputOutput, 'NurbsSwungSurface'),
        ('trajectoryCurve', None, FieldType.SFNode, AccessType.inputOutput, 'NurbsSwungSurface'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 solid=True,
                 profileCurve=None,
                 trajectoryCurve=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsSwungSurface __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.solid = solid
        self.profileCurve = profileCurve
        self.trajectoryCurve = trajectoryCurve
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def profileCurve(self):
        return self.__profileCurve
    @profileCurve.setter
    def profileCurve(self, profileCurve=None):
        if  profileCurve is None:
            profileCurve = SFNode.DEFAULT_VALUE
        assertValidSFNode(profileCurve)
        if not isinstance(profileCurve, object):
            # print(flush=True)
            raise X3DTypeError(str(profileCurve) + ' does not have a valid node type object')
        self.__profileCurve = profileCurve
    @property # getter - - - - - - - - - -
    def trajectoryCurve(self):
        return self.__trajectoryCurve
    @trajectoryCurve.setter
    def trajectoryCurve(self, trajectoryCurve=None):
        if  trajectoryCurve is None:
            trajectoryCurve = SFNode.DEFAULT_VALUE
        assertValidSFNode(trajectoryCurve)
        if not isinstance(trajectoryCurve, object):
            # print(flush=True)
            raise X3DTypeError(str(trajectoryCurve) + ' does not have a valid node type object')
        self.__trajectoryCurve = trajectoryCurve
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.profileCurve) or bool(self.trajectoryCurve)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsSwungSurface.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsSwungSurface'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.profileCurve: # output this SFNode
                result += self.profileCurve.XML(indentLevel=indentLevel+1)
            if self.trajectoryCurve: # output this SFNode
                result += self.trajectoryCurve.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsSwungSurface>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsTextureCoordinate(_X3DNode):
    """
    NurbsTextureCoordinate describes a 3D NURBS surface in the parametric domain of its surface host, specifying mapping of texture onto the surface.
    """
    NAME = 'NurbsTextureCoordinate'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsTextureCoordinate'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('controlPoint', list(), FieldType.MFVec2f, AccessType.inputOutput, 'NurbsTextureCoordinate'),
        ('uDimension', 0, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsTextureCoordinate'),
        ('uKnot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'NurbsTextureCoordinate'),
        ('uOrder', 3, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsTextureCoordinate'),
        ('vDimension', 0, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsTextureCoordinate'),
        ('vKnot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'NurbsTextureCoordinate'),
        ('vOrder', 3, FieldType.SFInt32, AccessType.initializeOnly, 'NurbsTextureCoordinate'),
        ('weight', list(), FieldType.MFFloat, AccessType.inputOutput, 'NurbsTextureCoordinate'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 controlPoint=list(),
                 uDimension=0,
                 uKnot=list(),
                 uOrder=3,
                 vDimension=0,
                 vKnot=list(),
                 vOrder=3,
                 weight=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsTextureCoordinate __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.controlPoint = controlPoint
        self.uDimension = uDimension
        self.uKnot = uKnot
        self.uOrder = uOrder
        self.vDimension = vDimension
        self.vKnot = vKnot
        self.vOrder = vOrder
        self.weight = weight
    @property # getter - - - - - - - - - -
    def controlPoint(self):
        """controlPoint defines a set of control points of dimension uDimension by vDimension, and defines a mesh where the points do not have uniform spacing."""
        return self.__controlPoint
    @controlPoint.setter
    def controlPoint(self, controlPoint=None):
        if  controlPoint is None:
            controlPoint = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(controlPoint)
        self.__controlPoint = controlPoint
    @property # getter - - - - - - - - - -
    def uDimension(self):
        """Number of control points in u dimension."""
        return self.__uDimension
    @uDimension.setter
    def uDimension(self, uDimension=None):
        if  uDimension is None:
            uDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uDimension)
        assertNonNegative('uDimension', uDimension)
        self.__uDimension = uDimension
    @property # getter - - - - - - - - - -
    def uKnot(self):
        """Knot vector, where size = number of control points + order of curve."""
        return self.__uKnot
    @uKnot.setter
    def uKnot(self, uKnot=None):
        if  uKnot is None:
            uKnot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(uKnot)
        self.__uKnot = uKnot
    @property # getter - - - - - - - - - -
    def uOrder(self):
        """Define order of surface by polynomials of degree = order-1."""
        return self.__uOrder
    @uOrder.setter
    def uOrder(self, uOrder=None):
        if  uOrder is None:
            uOrder = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uOrder)
        assertGreaterThanEquals('uOrder', uOrder, 2)
        self.__uOrder = uOrder
    @property # getter - - - - - - - - - -
    def vDimension(self):
        """Number of control points in v dimension."""
        return self.__vDimension
    @vDimension.setter
    def vDimension(self, vDimension=None):
        if  vDimension is None:
            vDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vDimension)
        assertNonNegative('vDimension', vDimension)
        self.__vDimension = vDimension
    @property # getter - - - - - - - - - -
    def vKnot(self):
        """Knot vector, where size = number of control points + order of curve."""
        return self.__vKnot
    @vKnot.setter
    def vKnot(self, vKnot=None):
        if  vKnot is None:
            vKnot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(vKnot)
        self.__vKnot = vKnot
    @property # getter - - - - - - - - - -
    def vOrder(self):
        """Define order of surface by polynomials of degree = order-1."""
        return self.__vOrder
    @vOrder.setter
    def vOrder(self, vOrder=None):
        if  vOrder is None:
            vOrder = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vOrder)
        assertGreaterThanEquals('vOrder', vOrder, 2)
        self.__vOrder = vOrder
    @property # getter - - - - - - - - - -
    def weight(self):
        """Output values for linear interpolation, each corresponding to knots."""
        return self.__weight
    @weight.setter
    def weight(self, weight=None):
        if  weight is None:
            weight = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(weight)
        assertPositive('weight', weight)
        self.__weight = weight
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsTextureCoordinate.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsTextureCoordinate'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.controlPoint != list():
            result += " controlPoint='" + MFVec2f(self.controlPoint).XML() + "'"
        if self.uDimension != 0:
            result += " uDimension='" + SFInt32(self.uDimension).XML() + "'"
        if self.uKnot != list():
            result += " uKnot='" + MFDouble(self.uKnot).XML() + "'"
        if self.uOrder != 3:
            result += " uOrder='" + SFInt32(self.uOrder).XML() + "'"
        if self.vDimension != 0:
            result += " vDimension='" + SFInt32(self.vDimension).XML() + "'"
        if self.vKnot != list():
            result += " vKnot='" + MFDouble(self.vKnot).XML() + "'"
        if self.vOrder != 3:
            result += " vOrder='" + SFInt32(self.vOrder).XML() + "'"
        if self.weight != list():
            result += " weight='" + MFFloat(self.weight).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsTextureCoordinate>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class NurbsTrimmedSurface(_X3DNurbsSurfaceGeometryNode):
    """
    NurbsTrimmedSurface generates texture coordinates from a Non-Uniform Rational B-Spline (NURBS) surface.
    """
    NAME = 'NurbsTrimmedSurface'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#NurbsTrimmedSurface'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uClosed', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uDimension', 0, FieldType.SFInt32, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uKnot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uOrder', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('uTessellation', 0, FieldType.SFInt32, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('vClosed', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('vDimension', 0, FieldType.SFInt32, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('vKnot', list(), FieldType.MFDouble, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('vOrder', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DNurbsSurfaceGeometryNode'),
        ('vTessellation', 0, FieldType.SFInt32, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('weight', list(), FieldType.MFDouble, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('controlPoint', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNurbsSurfaceGeometryNode'),
        ('trimmingContour', list(), FieldType.MFNode, AccessType.inputOutput, 'NurbsTrimmedSurface'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 solid=True,
                 uClosed=False,
                 uDimension=0,
                 uKnot=list(),
                 uOrder=3,
                 uTessellation=0,
                 vClosed=False,
                 vDimension=0,
                 vKnot=list(),
                 vOrder=3,
                 vTessellation=0,
                 weight=list(),
                 controlPoint=None,
                 texCoord=None,
                 trimmingContour=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode NurbsTrimmedSurface __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.solid = solid
        self.uClosed = uClosed
        self.uDimension = uDimension
        self.uKnot = uKnot
        self.uOrder = uOrder
        self.uTessellation = uTessellation
        self.vClosed = vClosed
        self.vDimension = vDimension
        self.vKnot = vKnot
        self.vOrder = vOrder
        self.vTessellation = vTessellation
        self.weight = weight
        self.controlPoint = controlPoint
        self.texCoord = texCoord
        self.trimmingContour = trimmingContour
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def uClosed(self):
        """Whether opposite surface sides are closed (seamless) across u dimension."""
        return self.__uClosed
    @uClosed.setter
    def uClosed(self, uClosed=None):
        if  uClosed is None:
            uClosed = SFBool.DEFAULT_VALUE
        assertValidSFBool(uClosed)
        self.__uClosed = uClosed
    @property # getter - - - - - - - - - -
    def uDimension(self):
        """Number of control points in u dimension."""
        return self.__uDimension
    @uDimension.setter
    def uDimension(self, uDimension=None):
        if  uDimension is None:
            uDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uDimension)
        assertNonNegative('uDimension', uDimension)
        self.__uDimension = uDimension
    @property # getter - - - - - - - - - -
    def uKnot(self):
        """Knot vector, where size = number of control points + order of curve."""
        return self.__uKnot
    @uKnot.setter
    def uKnot(self, uKnot=None):
        if  uKnot is None:
            uKnot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(uKnot)
        self.__uKnot = uKnot
    @property # getter - - - - - - - - - -
    def uOrder(self):
        """Define order of surface by polynomials of degree = order-1."""
        return self.__uOrder
    @uOrder.setter
    def uOrder(self, uOrder=None):
        if  uOrder is None:
            uOrder = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uOrder)
        assertGreaterThanEquals('uOrder', uOrder, 2)
        self.__uOrder = uOrder
    @property # getter - - - - - - - - - -
    def uTessellation(self):
        """hint for surface tesselation."""
        return self.__uTessellation
    @uTessellation.setter
    def uTessellation(self, uTessellation=None):
        if  uTessellation is None:
            uTessellation = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(uTessellation)
        self.__uTessellation = uTessellation
    @property # getter - - - - - - - - - -
    def vClosed(self):
        """Whether opposite surface sides are closed (seamless) across u dimension."""
        return self.__vClosed
    @vClosed.setter
    def vClosed(self, vClosed=None):
        if  vClosed is None:
            vClosed = SFBool.DEFAULT_VALUE
        assertValidSFBool(vClosed)
        self.__vClosed = vClosed
    @property # getter - - - - - - - - - -
    def vDimension(self):
        """Number of control points in v dimension."""
        return self.__vDimension
    @vDimension.setter
    def vDimension(self, vDimension=None):
        if  vDimension is None:
            vDimension = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vDimension)
        assertNonNegative('vDimension', vDimension)
        self.__vDimension = vDimension
    @property # getter - - - - - - - - - -
    def vKnot(self):
        """Knot vector, where size = number of control points + order of curve."""
        return self.__vKnot
    @vKnot.setter
    def vKnot(self, vKnot=None):
        if  vKnot is None:
            vKnot = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(vKnot)
        self.__vKnot = vKnot
    @property # getter - - - - - - - - - -
    def vOrder(self):
        """Define order of surface by polynomials of degree = order-1."""
        return self.__vOrder
    @vOrder.setter
    def vOrder(self, vOrder=None):
        if  vOrder is None:
            vOrder = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vOrder)
        assertGreaterThanEquals('vOrder', vOrder, 2)
        self.__vOrder = vOrder
    @property # getter - - - - - - - - - -
    def vTessellation(self):
        """hint for surface tesselation."""
        return self.__vTessellation
    @vTessellation.setter
    def vTessellation(self, vTessellation=None):
        if  vTessellation is None:
            vTessellation = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(vTessellation)
        self.__vTessellation = vTessellation
    @property # getter - - - - - - - - - -
    def weight(self):
        """Vector assigning relative weight value to each control point."""
        return self.__weight
    @weight.setter
    def weight(self, weight=None):
        if  weight is None:
            weight = MFDouble.DEFAULT_VALUE
        assertValidMFDouble(weight)
        assertPositive('weight', weight)
        self.__weight = weight
    @property # getter - - - - - - - - - -
    def controlPoint(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies control points for NURBS geometry definitions."""
        return self.__controlPoint
    @controlPoint.setter
    def controlPoint(self, controlPoint=None):
        if  controlPoint is None:
            controlPoint = SFNode.DEFAULT_VALUE
        assertValidSFNode(controlPoint)
        if not isinstance(controlPoint, object):
            # print(flush=True)
            raise X3DTypeError(str(controlPoint) + ' does not have a valid node type object')
        self.__controlPoint = controlPoint
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode|NurbsTextureCoordinate] Single contained NurbsTextureCoordinate, TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def trimmingContour(self):
        """[Contour2D] A set of Contour2D nodes are used as trimming loops."""
        return self.__trimmingContour
    @trimmingContour.setter
    def trimmingContour(self, trimmingContour=None):
        if  trimmingContour is None:
            trimmingContour = MFNode.DEFAULT_VALUE
        assertValidMFNode(trimmingContour)
        self.__trimmingContour = trimmingContour
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.trimmingContour) or bool(self.controlPoint) or bool(self.IS) or bool(self.metadata) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function NurbsTrimmedSurface.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<NurbsTrimmedSurface'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.uClosed != False:
            result += " uClosed='" + SFBool(self.uClosed).XML() + "'"
        if self.uDimension != 0:
            result += " uDimension='" + SFInt32(self.uDimension).XML() + "'"
        if self.uKnot != list():
            result += " uKnot='" + MFDouble(self.uKnot).XML() + "'"
        if self.uOrder != 3:
            result += " uOrder='" + SFInt32(self.uOrder).XML() + "'"
        if self.uTessellation != 0:
            result += " uTessellation='" + SFInt32(self.uTessellation).XML() + "'"
        if self.vClosed != False:
            result += " vClosed='" + SFBool(self.vClosed).XML() + "'"
        if self.vDimension != 0:
            result += " vDimension='" + SFInt32(self.vDimension).XML() + "'"
        if self.vKnot != list():
            result += " vKnot='" + MFDouble(self.vKnot).XML() + "'"
        if self.vOrder != 3:
            result += " vOrder='" + SFInt32(self.vOrder).XML() + "'"
        if self.vTessellation != 0:
            result += " vTessellation='" + SFInt32(self.vTessellation).XML() + "'"
        if self.weight != list():
            result += " weight='" + MFDouble(self.weight).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.controlPoint: # output this SFNode
                result += self.controlPoint.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.trimmingContour: # walk each child node, if any
                for each in self.trimmingContour:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</NurbsTrimmedSurface>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class OpacityMapVolumeStyle(_X3DComposableVolumeRenderStyleNode):
    """
    OpacityMapVolumeStyle specifies that volumetric data is rendered using opacity mapped to a transfer function texture.
    """
    NAME = 'OpacityMapVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#OpacityMapVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('transferFunction', None, FieldType.SFNode, AccessType.inputOutput, 'OpacityMapVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 transferFunction=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode OpacityMapVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.transferFunction = transferFunction
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def transferFunction(self):
        return self.__transferFunction
    @transferFunction.setter
    def transferFunction(self, transferFunction=None):
        if  transferFunction is None:
            transferFunction = SFNode.DEFAULT_VALUE
        assertValidSFNode(transferFunction)
        if not isinstance(transferFunction, object):
            # print(flush=True)
            raise X3DTypeError(str(transferFunction) + ' does not have a valid node type object')
        self.__transferFunction = transferFunction
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.transferFunction)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function OpacityMapVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<OpacityMapVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.transferFunction: # output this SFNode
                result += self.transferFunction.XML(indentLevel=indentLevel+1)
            result += indent + '</OpacityMapVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class OrientationChaser(_X3DChaserNode):
    """
    OrientationChaser generates a series of 4-tuple axis-angle SFRotation values that progressively change from initial value to destination value.
    """
    NAME = 'OrientationChaser'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#OrientationChaser'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('duration', 1, FieldType.SFTime, AccessType.initializeOnly, 'X3DChaserNode'),
        ('initialDestination', (0, 1, 0, 0), FieldType.SFRotation, AccessType.initializeOnly, 'OrientationChaser'),
        ('initialValue', (0, 1, 0, 0), FieldType.SFRotation, AccessType.initializeOnly, 'OrientationChaser'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 duration=1,
                 initialDestination=(0, 1, 0, 0),
                 initialValue=(0, 1, 0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode OrientationChaser __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.duration = duration
        self.initialDestination = initialDestination
        self.initialValue = initialValue
    @property # getter - - - - - - - - - -
    def duration(self):
        """[0,+infinity) duration is the time interval for filter response in seconds."""
        return self.__duration
    @duration.setter
    def duration(self, duration=None):
        if  duration is None:
            duration = SFTime.DEFAULT_VALUE
        assertValidSFTime(duration)
        assertNonNegative('duration', duration)
        self.__duration = duration
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(initialValue)
        self.__initialValue = initialValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function OrientationChaser.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<OrientationChaser'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.duration != 1:
            result += " duration='" + SFTime(self.duration).XML() + "'"
        if self.initialDestination != (0, 1, 0, 0):
            result += " initialDestination='" + SFRotation(self.initialDestination).XML() + "'"
        if self.initialValue != (0, 1, 0, 0):
            result += " initialValue='" + SFRotation(self.initialValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</OrientationChaser>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class OrientationDamper(_X3DDamperNode):
    """
    OrientationDamper generates a series of 4-tuple axis-angle SFRotation values that progressively change from initial value to destination value.
    """
    NAME = 'OrientationDamper'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#OrientationDamper'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('initialDestination', (0, 1, 0, 0), FieldType.SFRotation, AccessType.initializeOnly, 'OrientationDamper'),
        ('initialValue', (0, 1, 0, 0), FieldType.SFRotation, AccessType.initializeOnly, 'OrientationDamper'),
        ('order', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DDamperNode'),
        ('tau', 0.3, FieldType.SFTime, AccessType.inputOutput, 'X3DDamperNode'),
        ('tolerance', -1, FieldType.SFFloat, AccessType.inputOutput, 'X3DDamperNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 initialDestination=(0, 1, 0, 0),
                 initialValue=(0, 1, 0, 0),
                 order=3,
                 tau=0.3,
                 tolerance=-1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode OrientationDamper __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.initialDestination = initialDestination
        self.initialValue = initialValue
        self.order = order
        self.tau = tau
        self.tolerance = tolerance
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(initialValue)
        self.__initialValue = initialValue
    @property # getter - - - - - - - - - -
    def order(self):
        """[0,5] order defines the number of internal filters (larger means smoother response, longer delay)."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 0)
        assertLessThanEquals('order', order, 5)
        self.__order = order
    @property # getter - - - - - - - - - -
    def tau(self):
        """[0,+infinity) tau is the exponential-decay time constant for filter response in seconds."""
        return self.__tau
    @tau.setter
    def tau(self, tau=None):
        if  tau is None:
            tau = SFTime.DEFAULT_VALUE
        assertValidSFTime(tau)
        assertNonNegative('tau', tau)
        self.__tau = tau
    @property # getter - - - - - - - - - -
    def tolerance(self):
        """[0,+infinity) or -1."""
        return self.__tolerance
    @tolerance.setter
    def tolerance(self, tolerance=None):
        if  tolerance is None:
            tolerance = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(tolerance)
        self.__tolerance = tolerance
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function OrientationDamper.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<OrientationDamper'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.initialDestination != (0, 1, 0, 0):
            result += " initialDestination='" + SFRotation(self.initialDestination).XML() + "'"
        if self.initialValue != (0, 1, 0, 0):
            result += " initialValue='" + SFRotation(self.initialValue).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.tau != 0.3:
            result += " tau='" + SFTime(self.tau).XML() + "'"
        if self.tolerance != -1:
            result += " tolerance='" + SFFloat(self.tolerance).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</OrientationDamper>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class OrientationInterpolator(_X3DInterpolatorNode):
    """
    OrientationInterpolator generates a series of 4-tuple axis-angle SFRotation values.
    """
    NAME = 'OrientationInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#OrientationInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFRotation, AccessType.inputOutput, 'OrientationInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode OrientationInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFRotation.DEFAULT_VALUE
        assertValidMFRotation(keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function OrientationInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<OrientationInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFRotation(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</OrientationInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class OrthoViewpoint(_X3DViewpointNode):
    """
    OrthoViewpoint provides an orthographic perspective-free view of a scene from a specific location and direction.
    """
    NAME = 'OrthoViewpoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#OrthoViewpoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('centerOfRotation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'OrthoViewpoint'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DViewpointNode'),
        ('fieldOfView', [-1, -1, 1, 1], FieldType.MFFloat, AccessType.inputOutput, 'OrthoViewpoint'),
        ('jump', True, FieldType.SFBool, AccessType.inputOutput, 'X3DViewpointNode'),
        ('orientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'X3DViewpointNode'),
        ('position', (0, 0, 10), FieldType.SFVec3f, AccessType.inputOutput, 'OrthoViewpoint'),
        ('retainUserOffsets', False, FieldType.SFBool, AccessType.inputOutput, 'X3DViewpointNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 centerOfRotation=(0, 0, 0),
                 description='',
                 fieldOfView=[-1, -1, 1, 1],
                 jump=True,
                 orientation=(0, 0, 1, 0),
                 position=(0, 0, 10),
                 retainUserOffsets=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode OrthoViewpoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.centerOfRotation = centerOfRotation
        self.description = description
        self.fieldOfView = fieldOfView
        self.jump = jump
        self.orientation = orientation
        self.position = position
        self.retainUserOffsets = retainUserOffsets
    @property # getter - - - - - - - - - -
    def centerOfRotation(self):
        """centerOfRotation specifies center point about which to rotate user's eyepoint when in EXAMINE or LOOKAT mode."""
        return self.__centerOfRotation
    @centerOfRotation.setter
    def centerOfRotation(self, centerOfRotation=None):
        if  centerOfRotation is None:
            centerOfRotation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(centerOfRotation)
        self.__centerOfRotation = centerOfRotation
    @property # getter - - - - - - - - - -
    def description(self):
        """Text description or navigation hint to describe the significance of this model Viewpoint."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def fieldOfView(self):
        """Minimum and maximum extents of view in units of local coordinate system."""
        return self.__fieldOfView
    @fieldOfView.setter
    def fieldOfView(self, fieldOfView=None):
        if  fieldOfView is None:
            fieldOfView = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(fieldOfView)
        self.__fieldOfView = fieldOfView
    @property # getter - - - - - - - - - -
    def jump(self):
        """Transition instantly by jumping, otherwise smoothly adjust offsets in place when changing to this Viewpoint."""
        return self.__jump
    @jump.setter
    def jump(self, jump=None):
        if  jump is None:
            jump = SFBool.DEFAULT_VALUE
        assertValidSFBool(jump)
        self.__jump = jump
    @property # getter - - - - - - - - - -
    def orientation(self):
        """Rotation (axis, angle in radians) of Viewpoint, relative to default -Z axis direction in local coordinate system."""
        return self.__orientation
    @orientation.setter
    def orientation(self, orientation=None):
        if  orientation is None:
            orientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(orientation)
        self.__orientation = orientation
    @property # getter - - - - - - - - - -
    def position(self):
        """position (x, y, z in meters) relative to local coordinate system."""
        return self.__position
    @position.setter
    def position(self, position=None):
        if  position is None:
            position = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(position)
        self.__position = position
    @property # getter - - - - - - - - - -
    def retainUserOffsets(self):
        """Retain (true) or reset to zero (false) any prior user navigation offsets from defined viewpoint position, orientation."""
        return self.__retainUserOffsets
    @retainUserOffsets.setter
    def retainUserOffsets(self, retainUserOffsets=None):
        if  retainUserOffsets is None:
            retainUserOffsets = SFBool.DEFAULT_VALUE
        assertValidSFBool(retainUserOffsets)
        self.__retainUserOffsets = retainUserOffsets
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function OrthoViewpoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<OrthoViewpoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.centerOfRotation != (0, 0, 0):
            result += " centerOfRotation='" + SFVec3f(self.centerOfRotation).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.fieldOfView != [-1, -1, 1, 1]:
            result += " fieldOfView='" + MFFloat(self.fieldOfView).XML() + "'"
        if self.jump != True:
            result += " jump='" + SFBool(self.jump).XML() + "'"
        if self.orientation != (0, 0, 1, 0):
            result += " orientation='" + SFRotation(self.orientation).XML() + "'"
        if self.position != (0, 0, 10):
            result += " position='" + SFVec3f(self.position).XML() + "'"
        if self.retainUserOffsets != False:
            result += " retainUserOffsets='" + SFBool(self.retainUserOffsets).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</OrthoViewpoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PackagedShader(_X3DShaderNode): # , _X3DUrlObject, _X3DProgrammableShaderObject # TODO fix additional inheritance method resolution order (MRO)
    """
    PackagedShader can contain field declarations, but no CDATA section of plain-text source code.
    """
    NAME = 'PackagedShader'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PackagedShader'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('language', '', FieldType.SFString, AccessType.initializeOnly, 'X3DShaderNode'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('field', list(), FieldType.MFNode, AccessType.inputOutput, 'PackagedShader'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'PackagedShader'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'PackagedShader')]
    def __init__(self,
                 language='',
                 url=list(),
                 field=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PackagedShader __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.language = language
        self.url = url
        self.field = field
    @property # getter - - - - - - - - - -
    def language(self):
        """The language field indicates to the X3D player which shading language is used."""
        return self.__language
    @language.setter
    def language(self, language=None):
        if  language is None:
            language = SFString.DEFAULT_VALUE
        assertValidSFString(language)
        self.__language = language
    @property # getter - - - - - - - - - -
    def url(self):
        """url points to a shader source-code file that may contain a number of shaders and combined effects."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def field(self):
        """Include a field statement for each field declaration in the PackagedShader node."""
        return self.__field
    @field.setter
    def field(self, field=None):
        if  field is None:
            field = MFNode.DEFAULT_VALUE
        # TODO type-aware checks for field
        if field: # walk each child node, if any
            for each in field:
                assertValidFieldInitializationValue(each.name, each.type, each.value, parent='PackagedShader')
        self.__field = field
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.field) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PackagedShader.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PackagedShader'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.language:
            result += " language='" + self.language + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.field: # walk each child node, if any
                for each in self.field:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</PackagedShader>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ParticleSystem(_X3DShapeNode):
    """
    ParticleSystem specifies a complete particle system.
    """
    NAME = 'ParticleSystem'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ParticleSystem'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DShapeNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DShapeNode'),
        ('colorKey', list(), FieldType.MFFloat, AccessType.initializeOnly, 'ParticleSystem'),
        ('createParticles', True, FieldType.SFBool, AccessType.inputOutput, 'ParticleSystem'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DShapeNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'ParticleSystem'),
        ('geometryType', 'QUAD', FieldType.SFString, AccessType.initializeOnly, 'ParticleSystem'),
        ('lifetimeVariation', 0.25, FieldType.SFFloat, AccessType.inputOutput, 'ParticleSystem'),
        ('maxParticles', 200, FieldType.SFInt32, AccessType.inputOutput, 'ParticleSystem'),
        ('particleLifetime', 5, FieldType.SFFloat, AccessType.inputOutput, 'ParticleSystem'),
        ('particleSize', (0.02, 0.02), FieldType.SFVec2f, AccessType.inputOutput, 'ParticleSystem'),
        ('texCoordKey', list(), FieldType.MFFloat, AccessType.initializeOnly, 'ParticleSystem'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DShapeNode'),
        ('appearance', None, FieldType.SFNode, AccessType.inputOutput, 'X3DShapeNode'),
        ('colorRamp', None, FieldType.SFNode, AccessType.initializeOnly, 'ParticleSystem'),
        ('emitter', None, FieldType.SFNode, AccessType.initializeOnly, 'ParticleSystem'),
        ('geometry', None, FieldType.SFNode, AccessType.inputOutput, 'X3DShapeNode'),
        ('texCoordRamp', None, FieldType.SFNode, AccessType.initializeOnly, 'ParticleSystem'),
        ('physics', list(), FieldType.MFNode, AccessType.initializeOnly, 'ParticleSystem'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 colorKey=list(),
                 createParticles=True,
                 displayBBox=False,
                 enabled=True,
                 geometryType='QUAD',
                 lifetimeVariation=0.25,
                 maxParticles=200,
                 particleLifetime=5,
                 particleSize=(0.02, 0.02),
                 texCoordKey=list(),
                 visible=True,
                 appearance=None,
                 colorRamp=None,
                 emitter=None,
                 geometry=None,
                 texCoordRamp=None,
                 physics=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ParticleSystem __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.colorKey = colorKey
        self.createParticles = createParticles
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.geometryType = geometryType
        self.lifetimeVariation = lifetimeVariation
        self.maxParticles = maxParticles
        self.particleLifetime = particleLifetime
        self.particleSize = particleSize
        self.texCoordKey = texCoordKey
        self.visible = visible
        self.appearance = appearance
        self.colorRamp = colorRamp
        self.emitter = emitter
        self.geometry = geometry
        self.geometry = geometry
        self.texCoordRamp = texCoordRamp
        self.physics = physics
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def colorKey(self):
        """[0,+infinity) Array of time intervals in seconds, corresponding to particle lifetime, that are used to interpolate colorRamp array values."""
        return self.__colorKey
    @colorKey.setter
    def colorKey(self, colorKey=None):
        if  colorKey is None:
            colorKey = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(colorKey)
        assertNonNegative('colorKey', colorKey)
        self.__colorKey = colorKey
    @property # getter - - - - - - - - - -
    def createParticles(self):
        """Enables/disables creation of new particles, while any existing particles remain in existence and continue to animate until the end of their lifetimes."""
        return self.__createParticles
    @createParticles.setter
    def createParticles(self, createParticles=None):
        if  createParticles is None:
            createParticles = SFBool.DEFAULT_VALUE
        assertValidSFBool(createParticles)
        self.__createParticles = createParticles
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def geometryType(self):
        """specifies type of geometry used to represent individual particles."""
        return self.__geometryType
    @geometryType.setter
    def geometryType(self, geometryType=None):
        if  geometryType is None:
            geometryType = SFString.DEFAULT_VALUE
        assertValidSFString(geometryType)
        self.__geometryType = geometryType
    @property # getter - - - - - - - - - -
    def lifetimeVariation(self):
        """[0,1) TODO not properly defined in X3D spedification."""
        return self.__lifetimeVariation
    @lifetimeVariation.setter
    def lifetimeVariation(self, lifetimeVariation=None):
        if  lifetimeVariation is None:
            lifetimeVariation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(lifetimeVariation)
        assertZeroToOne('lifetimeVariation', lifetimeVariation)
        self.__lifetimeVariation = lifetimeVariation
    @property # getter - - - - - - - - - -
    def maxParticles(self):
        """[0,+infinity) Maximum number of particles to be generated at one time (subject to player limitations)."""
        return self.__maxParticles
    @maxParticles.setter
    def maxParticles(self, maxParticles=None):
        if  maxParticles is None:
            maxParticles = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(maxParticles)
        assertNonNegative('maxParticles', maxParticles)
        self.__maxParticles = maxParticles
    @property # getter - - - - - - - - - -
    def particleLifetime(self):
        """[0,+infinity) TODO not properly defined in X3D spedification."""
        return self.__particleLifetime
    @particleLifetime.setter
    def particleLifetime(self, particleLifetime=None):
        if  particleLifetime is None:
            particleLifetime = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(particleLifetime)
        assertNonNegative('particleLifetime', particleLifetime)
        self.__particleLifetime = particleLifetime
    @property # getter - - - - - - - - - -
    def particleSize(self):
        """[0,+infinity) particleSize describes width and height dimensions for each particle in length base units (default is meters)."""
        return self.__particleSize
    @particleSize.setter
    def particleSize(self, particleSize=None):
        if  particleSize is None:
            particleSize = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(particleSize)
        assertNonNegative('particleSize', particleSize)
        self.__particleSize = particleSize
    @property # getter - - - - - - - - - -
    def texCoordKey(self):
        """[0,+infinity) Array of time intervals in seconds, corresponding to particle lifetime, that are used to sequence texCoordRamp array values."""
        return self.__texCoordKey
    @texCoordKey.setter
    def texCoordKey(self, texCoordKey=None):
        if  texCoordKey is None:
            texCoordKey = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(texCoordKey)
        assertNonNegative('texCoordKey', texCoordKey)
        self.__texCoordKey = texCoordKey
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def appearance(self):
        """[X3DAppearanceNode] The appearance field holds an Appearance node that is used for the geometry."""
        return self.__appearance
    @appearance.setter
    def appearance(self, appearance=None):
        if  appearance is None:
            appearance = SFNode.DEFAULT_VALUE
        assertValidSFNode(appearance)
        if not isinstance(appearance, object):
            # print(flush=True)
            raise X3DTypeError(str(appearance) + ' does not have a valid node type object')
        self.__appearance = appearance
    @property # getter - - - - - - - - - -
    def colorRamp(self):
        """[X3DColorNode] The colorRamp Color|ColorRGBA node holds a series of color values to be used at the given colorKey points in time."""
        return self.__colorRamp
    @colorRamp.setter
    def colorRamp(self, colorRamp=None):
        if  colorRamp is None:
            colorRamp = SFNode.DEFAULT_VALUE
        assertValidSFNode(colorRamp)
        if not isinstance(colorRamp, object):
            # print(flush=True)
            raise X3DTypeError(str(colorRamp) + ' does not have a valid node type object')
        self.__colorRamp = colorRamp
    @property # getter - - - - - - - - - -
    def emitter(self):
        """[X3DParticleEmitterNode] The emitter field specifies the type of emitter geometry and properties that the particles are given for their initial positions."""
        return self.__emitter
    @emitter.setter
    def emitter(self, emitter=None):
        if  emitter is None:
            emitter = SFNode.DEFAULT_VALUE
        assertValidSFNode(emitter)
        if not isinstance(emitter, object):
            # print(flush=True)
            raise X3DTypeError(str(emitter) + ' does not have a valid node type object')
        self.__emitter = emitter
    @property # getter - - - - - - - - - -
    def geometry(self):
        """[X3DGeometryNode] Single contained geometry node provides geometry used for each particle when geometryType=GEOMETRY."""
        return self.__geometry
    @geometry.setter
    def geometry(self, geometry=None):
        if  geometry is None:
            geometry = SFNode.DEFAULT_VALUE
        assertValidSFNode(geometry)
        if not isinstance(geometry, object):
            # print(flush=True)
            raise X3DTypeError(str(geometry) + ' does not have a valid node type object')
        self.__geometry = geometry
    @property # getter - - - - - - - - - -
    def geometry(self):
        """[X3DGeometryNode] Single contained geometry node provides geometry used for each particle when geometryType=GEOMETRY."""
        return self.__geometry
    @geometry.setter
    def geometry(self, geometry=None):
        if  geometry is None:
            geometry = SFNode.DEFAULT_VALUE
        assertValidSFNode(geometry)
        if not isinstance(geometry, object):
            # print(flush=True)
            raise X3DTypeError(str(geometry) + ' does not have a valid node type object')
        self.__geometry = geometry
    @property # getter - - - - - - - - - -
    def texCoordRamp(self):
        """[TextureCoordinate] texture coordinates of the provided texture(s) in the Appearance node, over time."""
        return self.__texCoordRamp
    @texCoordRamp.setter
    def texCoordRamp(self, texCoordRamp=None):
        if  texCoordRamp is None:
            texCoordRamp = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoordRamp)
        if not isinstance(texCoordRamp, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoordRamp) + ' does not have a valid node type object')
        self.__texCoordRamp = texCoordRamp
    @property # getter - - - - - - - - - -
    def physics(self):
        """[X3DParticlePhysicsModelNode] After being created, the individual particles are then manipulated according to the physics model(s) specified in the physics field."""
        return self.__physics
    @physics.setter
    def physics(self, physics=None):
        if  physics is None:
            physics = MFNode.DEFAULT_VALUE
        assertValidMFNode(physics)
        self.__physics = physics
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.physics) or bool(self.appearance) or bool(self.colorRamp) or bool(self.emitter) or bool(self.geometry) or bool(self.IS) or bool(self.metadata) or bool(self.texCoordRamp)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ParticleSystem.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ParticleSystem'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorKey != list():
            result += " colorKey='" + MFFloat(self.colorKey).XML() + "'"
        if self.createParticles != True:
            result += " createParticles='" + SFBool(self.createParticles).XML() + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.geometryType != 'QUAD':
            result += " geometryType='" + self.geometryType + "'"
        if self.lifetimeVariation != 0.25:
            result += " lifetimeVariation='" + SFFloat(self.lifetimeVariation).XML() + "'"
        if self.maxParticles != 200:
            result += " maxParticles='" + SFInt32(self.maxParticles).XML() + "'"
        if self.particleLifetime != 5:
            result += " particleLifetime='" + SFFloat(self.particleLifetime).XML() + "'"
        if self.particleSize != (0.02, 0.02):
            result += " particleSize='" + SFVec2f(self.particleSize).XML() + "'"
        if self.texCoordKey != list():
            result += " texCoordKey='" + MFFloat(self.texCoordKey).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.appearance: # output this SFNode
                result += self.appearance.XML(indentLevel=indentLevel+1)
            if self.colorRamp: # output this SFNode
                result += self.colorRamp.XML(indentLevel=indentLevel+1)
            if self.emitter: # output this SFNode
                result += self.emitter.XML(indentLevel=indentLevel+1)
            if self.geometry: # output this SFNode
                result += self.geometry.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.texCoordRamp: # output this SFNode
                result += self.texCoordRamp.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.physics: # walk each child node, if any
                for each in self.physics:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ParticleSystem>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PickableGroup(_X3DGroupingNode, _X3DPickableObject):
    """
    PickableGroup is a Grouping node that can contain most nodes.
    """
    NAME = 'PickableGroup'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PickableGroup'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('objectType', ["ALL"], FieldType.MFString, AccessType.inputOutput, 'X3DPickableObject'),
        ('pickable', True, FieldType.SFBool, AccessType.inputOutput, 'X3DPickableObject'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 objectType=["ALL"],
                 pickable=True,
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PickableGroup __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.objectType = objectType
        self.pickable = pickable
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def objectType(self):
        """The objectType field specifies a set of labels used in the picking process."""
        return self.__objectType
    @objectType.setter
    def objectType(self, objectType=None):
        if  objectType is None:
            objectType = MFString.DEFAULT_VALUE
        assertValidMFString(objectType)
        self.__objectType = objectType
    @property # getter - - - - - - - - - -
    def pickable(self):
        """The pickable field determines whether pick traversal is performed on this node or its children."""
        return self.__pickable
    @pickable.setter
    def pickable(self, pickable=None):
        if  pickable is None:
            pickable = SFBool.DEFAULT_VALUE
        assertValidSFBool(pickable)
        self.__pickable = pickable
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PickableGroup.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PickableGroup'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.objectType != ["ALL"]:
            result += " objectType='" + MFString(self.objectType).XML() + "'"
        if self.pickable != True:
            result += " pickable='" + SFBool(self.pickable).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</PickableGroup>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PixelTexture(_X3DTexture2DNode):
    """
    PixelTexture creates a 2D-image texture map using a numeric array of pixel values.
    """
    NAME = 'PixelTexture'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PixelTexture'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('image', [0, 0, 0], FieldType.SFImage, AccessType.inputOutput, 'PixelTexture'),
        ('repeatS', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture2DNode'),
        ('repeatT', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture2DNode'),
        ('textureProperties', None, FieldType.SFNode, AccessType.initializeOnly, 'X3DTexture2DNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 image=[0, 0, 0],
                 repeatS=True,
                 repeatT=True,
                 textureProperties=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PixelTexture __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.image = image
        self.repeatS = repeatS
        self.repeatT = repeatT
        self.textureProperties = textureProperties
    @property # getter - - - - - - - - - -
    def image(self):
        """Defines image: width, height, number_of_components per each pixel value, and list of pixel_values."""
        return self.__image
    @image.setter
    def image(self, image=None):
        if  image is None:
            image = SFImage.DEFAULT_VALUE
        assertValidSFImage(image)
        self.__image = image
    @property # getter - - - - - - - - - -
    def repeatS(self):
        """Whether to horizontally repeat texture along S axis."""
        return self.__repeatS
    @repeatS.setter
    def repeatS(self, repeatS=None):
        if  repeatS is None:
            repeatS = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatS)
        self.__repeatS = repeatS
    @property # getter - - - - - - - - - -
    def repeatT(self):
        """Whether to vertically repeat texture along T axis."""
        return self.__repeatT
    @repeatT.setter
    def repeatT(self, repeatT=None):
        if  repeatT is None:
            repeatT = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatT)
        self.__repeatT = repeatT
    @property # getter - - - - - - - - - -
    def textureProperties(self):
        return self.__textureProperties
    @textureProperties.setter
    def textureProperties(self, textureProperties=None):
        if  textureProperties is None:
            textureProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(textureProperties)
        if not isinstance(textureProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(textureProperties) + ' does not have a valid node type object')
        self.__textureProperties = textureProperties
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.textureProperties)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PixelTexture.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PixelTexture'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.image != [0, 0, 0]:
            result += " image='" + SFImage(self.image).XML() + "'"
        if self.repeatS != True:
            result += " repeatS='" + SFBool(self.repeatS).XML() + "'"
        if self.repeatT != True:
            result += " repeatT='" + SFBool(self.repeatT).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.textureProperties: # output this SFNode
                result += self.textureProperties.XML(indentLevel=indentLevel+1)
            result += indent + '</PixelTexture>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PixelTexture3D(_X3DTexture3DNode):
    """
    PixelTexture3D defines a 3D image-based texture map as an explicit array of pixel values (image field).
    """
    NAME = 'PixelTexture3D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PixelTexture3D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('image', [0, 0, 0, 0], FieldType.MFInt32, AccessType.inputOutput, 'PixelTexture3D'),
        ('repeatR', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('repeatS', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('repeatT', False, FieldType.SFBool, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('textureProperties', None, FieldType.SFNode, AccessType.initializeOnly, 'X3DTexture3DNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 image=[0, 0, 0, 0],
                 repeatR=False,
                 repeatS=False,
                 repeatT=False,
                 textureProperties=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PixelTexture3D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.image = image
        self.repeatR = repeatR
        self.repeatS = repeatS
        self.repeatT = repeatT
        self.textureProperties = textureProperties
    @property # getter - - - - - - - - - -
    def image(self):
        """image describes raw data for this 3D texture: number of components to the image [0,4], width, height and depth of the texture, followed by (width x height x depth) pixel values."""
        return self.__image
    @image.setter
    def image(self, image=None):
        if  image is None:
            image = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(image)
        self.__image = image
    @property # getter - - - - - - - - - -
    def repeatR(self):
        """Whether to vertically repeat texture along R axis."""
        return self.__repeatR
    @repeatR.setter
    def repeatR(self, repeatR=None):
        if  repeatR is None:
            repeatR = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatR)
        self.__repeatR = repeatR
    @property # getter - - - - - - - - - -
    def repeatS(self):
        """Whether to horizontally repeat texture along S axis."""
        return self.__repeatS
    @repeatS.setter
    def repeatS(self, repeatS=None):
        if  repeatS is None:
            repeatS = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatS)
        self.__repeatS = repeatS
    @property # getter - - - - - - - - - -
    def repeatT(self):
        """Whether to vertically repeat texture along T axis."""
        return self.__repeatT
    @repeatT.setter
    def repeatT(self, repeatT=None):
        if  repeatT is None:
            repeatT = SFBool.DEFAULT_VALUE
        assertValidSFBool(repeatT)
        self.__repeatT = repeatT
    @property # getter - - - - - - - - - -
    def textureProperties(self):
        return self.__textureProperties
    @textureProperties.setter
    def textureProperties(self, textureProperties=None):
        if  textureProperties is None:
            textureProperties = SFNode.DEFAULT_VALUE
        assertValidSFNode(textureProperties)
        if not isinstance(textureProperties, object):
            # print(flush=True)
            raise X3DTypeError(str(textureProperties) + ' does not have a valid node type object')
        self.__textureProperties = textureProperties
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.textureProperties)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PixelTexture3D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PixelTexture3D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.image != [0, 0, 0, 0]:
            result += " image='" + MFInt32(self.image).XML() + "'"
        if self.repeatR != False:
            result += " repeatR='" + SFBool(self.repeatR).XML() + "'"
        if self.repeatS != False:
            result += " repeatS='" + SFBool(self.repeatS).XML() + "'"
        if self.repeatT != False:
            result += " repeatT='" + SFBool(self.repeatT).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.textureProperties: # output this SFNode
                result += self.textureProperties.XML(indentLevel=indentLevel+1)
            result += indent + '</PixelTexture3D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PlaneSensor(_X3DDragSensorNode):
    """
    PlaneSensor converts pointing device motion into 2D translation parallel to the local Z=0 plane.
    """
    NAME = 'PlaneSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PlaneSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('autoOffset', True, FieldType.SFBool, AccessType.inputOutput, 'X3DDragSensorNode'),
        ('axisRotation', (0, 1, 0, 0), FieldType.SFRotation, AccessType.inputOutput, 'PlaneSensor'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DPointingDeviceSensorNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('maxPosition', (-1, -1), FieldType.SFVec2f, AccessType.inputOutput, 'PlaneSensor'),
        ('minPosition', (0, 0), FieldType.SFVec2f, AccessType.inputOutput, 'PlaneSensor'),
        ('offset', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'PlaneSensor'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 autoOffset=True,
                 axisRotation=(0, 1, 0, 0),
                 description='',
                 enabled=True,
                 maxPosition=(-1, -1),
                 minPosition=(0, 0),
                 offset=(0, 0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PlaneSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.autoOffset = autoOffset
        self.axisRotation = axisRotation
        self.description = description
        self.enabled = enabled
        self.maxPosition = maxPosition
        self.minPosition = minPosition
        self.offset = offset
    @property # getter - - - - - - - - - -
    def autoOffset(self):
        """Determines whether previous offset values are remembered/accumulated."""
        return self.__autoOffset
    @autoOffset.setter
    def autoOffset(self, autoOffset=None):
        if  autoOffset is None:
            autoOffset = SFBool.DEFAULT_VALUE
        assertValidSFBool(autoOffset)
        self.__autoOffset = autoOffset
    @property # getter - - - - - - - - - -
    def axisRotation(self):
        """axisRotation determines local sensor coordinate system by rotating the local coordinate system."""
        return self.__axisRotation
    @axisRotation.setter
    def axisRotation(self, axisRotation=None):
        if  axisRotation is None:
            axisRotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(axisRotation)
        self.__axisRotation = axisRotation
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def maxPosition(self):
        """minPosition and maxPosition clamp translations to a range of values measured from origin of Z=0 plane default maxPosition < minPosition means no clamping."""
        return self.__maxPosition
    @maxPosition.setter
    def maxPosition(self, maxPosition=None):
        if  maxPosition is None:
            maxPosition = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(maxPosition)
        self.__maxPosition = maxPosition
    @property # getter - - - - - - - - - -
    def minPosition(self):
        """minPosition and maxPosition clamp translations to a range of values measured from origin of Z=0 plane default maxPosition < minPosition means no clamping."""
        return self.__minPosition
    @minPosition.setter
    def minPosition(self, minPosition=None):
        if  minPosition is None:
            minPosition = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(minPosition)
        self.__minPosition = minPosition
    @property # getter - - - - - - - - - -
    def offset(self):
        """Sends event and remembers last value sensed."""
        return self.__offset
    @offset.setter
    def offset(self, offset=None):
        if  offset is None:
            offset = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(offset)
        self.__offset = offset
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PlaneSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PlaneSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.autoOffset != True:
            result += " autoOffset='" + SFBool(self.autoOffset).XML() + "'"
        if self.axisRotation != (0, 1, 0, 0):
            result += " axisRotation='" + SFRotation(self.axisRotation).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.maxPosition != (-1, -1):
            result += " maxPosition='" + SFVec2f(self.maxPosition).XML() + "'"
        if self.minPosition != (0, 0):
            result += " minPosition='" + SFVec2f(self.minPosition).XML() + "'"
        if self.offset != (0, 0, 0):
            result += " offset='" + SFVec3f(self.offset).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PlaneSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PointEmitter(_X3DParticleEmitterNode):
    """
    PointEmitter generates particles from a specific point in space using the specified direction and speed.
    """
    NAME = 'PointEmitter'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PointEmitter'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('direction', (0, 1, 0), FieldType.SFVec3f, AccessType.inputOutput, 'PointEmitter'),
        ('mass', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('position', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'PointEmitter'),
        ('speed', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('surfaceArea', 0, FieldType.SFFloat, AccessType.initializeOnly, 'X3DParticleEmitterNode'),
        ('variation', 0.25, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 direction=(0, 1, 0),
                 mass=0,
                 position=(0, 0, 0),
                 speed=0,
                 surfaceArea=0,
                 variation=0.25,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PointEmitter __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.direction = direction
        self.mass = mass
        self.position = position
        self.speed = speed
        self.surfaceArea = surfaceArea
        self.variation = variation
    @property # getter - - - - - - - - - -
    def direction(self):
        """Initial direction from which particles emanate."""
        return self.__direction
    @direction.setter
    def direction(self, direction=None):
        if  direction is None:
            direction = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(direction)
        self.__direction = direction
    @property # getter - - - - - - - - - -
    def mass(self):
        """[0,+infinity) Basic mass of each particle, defined in mass base units (default is kilograms)."""
        return self.__mass
    @mass.setter
    def mass(self, mass=None):
        if  mass is None:
            mass = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(mass)
        assertNonNegative('mass', mass)
        self.__mass = mass
    @property # getter - - - - - - - - - -
    def position(self):
        """Point from which particles emanate."""
        return self.__position
    @position.setter
    def position(self, position=None):
        if  position is None:
            position = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(position)
        self.__position = position
    @property # getter - - - - - - - - - -
    def speed(self):
        """[0,+infinity) Initial linear speed (default is m/s) imparted to all particles along their direction of movement."""
        return self.__speed
    @speed.setter
    def speed(self, speed=None):
        if  speed is None:
            speed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speed)
        assertNonNegative('speed', speed)
        self.__speed = speed
    @property # getter - - - - - - - - - -
    def surfaceArea(self):
        """[0,+infinity) Particle surface area in area base units (default is meters squared)."""
        return self.__surfaceArea
    @surfaceArea.setter
    def surfaceArea(self, surfaceArea=None):
        if  surfaceArea is None:
            surfaceArea = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(surfaceArea)
        assertNonNegative('surfaceArea', surfaceArea)
        self.__surfaceArea = surfaceArea
    @property # getter - - - - - - - - - -
    def variation(self):
        """[0,+infinity) Multiplier for the randomness used to control the range of possible output values."""
        return self.__variation
    @variation.setter
    def variation(self, variation=None):
        if  variation is None:
            variation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(variation)
        assertNonNegative('variation', variation)
        self.__variation = variation
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PointEmitter.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PointEmitter'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.direction != (0, 1, 0):
            result += " direction='" + SFVec3f(self.direction).XML() + "'"
        if self.mass != 0:
            result += " mass='" + SFFloat(self.mass).XML() + "'"
        if self.position != (0, 0, 0):
            result += " position='" + SFVec3f(self.position).XML() + "'"
        if self.speed != 0:
            result += " speed='" + SFFloat(self.speed).XML() + "'"
        if self.surfaceArea != 0:
            result += " surfaceArea='" + SFFloat(self.surfaceArea).XML() + "'"
        if self.variation != 0.25:
            result += " variation='" + SFFloat(self.variation).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PointEmitter>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PointLight(_X3DLightNode):
    """
    Linear attenuation may occur at level 2, full support at level 3.
    """
    NAME = 'PointLight'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PointLight'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ambientIntensity', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DLightNode'),
        ('attenuation', (1, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'PointLight'),
        ('color', (1, 1, 1), FieldType.SFColor, AccessType.inputOutput, 'X3DLightNode'),
        ('global_', True, FieldType.SFBool, AccessType.inputOutput, 'PointLight'),
        ('intensity', 1, FieldType.SFFloat, AccessType.inputOutput, 'X3DLightNode'),
        ('location', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'PointLight'),
        ('on', True, FieldType.SFBool, AccessType.inputOutput, 'X3DLightNode'),
        ('radius', 100, FieldType.SFFloat, AccessType.initializeOnly, 'PointLight'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ambientIntensity=0,
                 attenuation=(1, 0, 0),
                 color=(1, 1, 1),
                 global_=True,
                 intensity=1,
                 location=(0, 0, 0),
                 on=True,
                 radius=100,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PointLight __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ambientIntensity = ambientIntensity
        self.attenuation = attenuation
        self.color = color
        self.global_ = global_
        self.intensity = intensity
        self.location = location
        self.on = on
        self.radius = radius
    @property # getter - - - - - - - - - -
    def ambientIntensity(self):
        """[0,1] Brightness of ambient (nondirectional background) emission from the light."""
        return self.__ambientIntensity
    @ambientIntensity.setter
    def ambientIntensity(self, ambientIntensity=None):
        if  ambientIntensity is None:
            ambientIntensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(ambientIntensity)
        assertZeroToOne('ambientIntensity', ambientIntensity)
        self.__ambientIntensity = ambientIntensity
    @property # getter - - - - - - - - - -
    def attenuation(self):
        """Constant, linear-distance and squared-distance dropoff factors as radial distance increases from the source."""
        return self.__attenuation
    @attenuation.setter
    def attenuation(self, attenuation=None):
        if  attenuation is None:
            attenuation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(attenuation)
        assertNonNegative('attenuation', attenuation)
        self.__attenuation = attenuation
    @property # getter - - - - - - - - - -
    def color(self):
        """[0,1] color of light, applied to colors of objects."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFColor.DEFAULT_VALUE
        assertValidSFColor(color)
        assertZeroToOne('color', color)
        self.__color = color
    @property # getter - - - - - - - - - -
    def global_(self):
        return self.__global_
    @global_.setter
    def global_(self, global_=None):
        if  global_ is None:
            global_ = SFBool.DEFAULT_VALUE
        assertValidSFBool(global_)
        self.__global_ = global_
    @property # getter - - - - - - - - - -
    def intensity(self):
        """[0,1] Brightness of direct emission from the light."""
        return self.__intensity
    @intensity.setter
    def intensity(self, intensity=None):
        if  intensity is None:
            intensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(intensity)
        assertZeroToOne('intensity', intensity)
        self.__intensity = intensity
    @property # getter - - - - - - - - - -
    def location(self):
        """Position of light relative to local coordinate system."""
        return self.__location
    @location.setter
    def location(self, location=None):
        if  location is None:
            location = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(location)
        self.__location = location
    @property # getter - - - - - - - - - -
    def on(self):
        """Enables/disables this light source."""
        return self.__on
    @on.setter
    def on(self, on=None):
        if  on is None:
            on = SFBool.DEFAULT_VALUE
        assertValidSFBool(on)
        self.__on = on
    @property # getter - - - - - - - - - -
    def radius(self):
        """Maximum effective distance of light relative to local light position, affected by ancestor scaling."""
        return self.__radius
    @radius.setter
    def radius(self, radius=None):
        if  radius is None:
            radius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(radius)
        assertNonNegative('radius', radius)
        self.__radius = radius
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PointLight.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PointLight'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ambientIntensity != 0:
            result += " ambientIntensity='" + SFFloat(self.ambientIntensity).XML() + "'"
        if self.attenuation != (1, 0, 0):
            result += " attenuation='" + SFVec3f(self.attenuation).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.color != (1, 1, 1):
            result += " color='" + SFColor(self.color).XML() + "'"
        if self.global_ != True:
            result += " global_='" + SFBool(self.global_).XML() + "'"
        if self.intensity != 1:
            result += " intensity='" + SFFloat(self.intensity).XML() + "'"
        if self.location != (0, 0, 0):
            result += " location='" + SFVec3f(self.location).XML() + "'"
        if self.on != True:
            result += " on='" + SFBool(self.on).XML() + "'"
        if self.radius != 100:
            result += " radius='" + SFFloat(self.radius).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PointLight>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PointPickSensor(_X3DPickSensorNode):
    """
    PointPickSensor tests one or more pickingGeometry points in space as lying inside the provided pickTarget geometry.
    """
    NAME = 'PointPickSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PointPickSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('intersectionType', 'BOUNDS', FieldType.SFString, AccessType.initializeOnly, 'X3DPickSensorNode'),
        ('matchCriterion', 'MATCH_ANY', FieldType.SFString, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('objectType', ["ALL"], FieldType.MFString, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('sortOrder', 'CLOSEST', FieldType.SFString, AccessType.initializeOnly, 'X3DPickSensorNode'),
        ('pickingGeometry', None, FieldType.SFNode, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('pickTarget', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 intersectionType='BOUNDS',
                 matchCriterion='MATCH_ANY',
                 objectType=["ALL"],
                 sortOrder='CLOSEST',
                 pickingGeometry=None,
                 pickTarget=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PointPickSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.intersectionType = intersectionType
        self.matchCriterion = matchCriterion
        self.objectType = objectType
        self.sortOrder = sortOrder
        self.pickingGeometry = pickingGeometry
        self.pickTarget = pickTarget
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def intersectionType(self):
        """intersectionType specifies precision of the collision computation."""
        return self.__intersectionType
    @intersectionType.setter
    def intersectionType(self, intersectionType=None):
        if  intersectionType is None:
            intersectionType = SFString.DEFAULT_VALUE
        assertValidSFString(intersectionType)
        self.__intersectionType = intersectionType
    @property # getter - - - - - - - - - -
    def matchCriterion(self):
        """defines whether the intersection test (i."""
        return self.__matchCriterion
    @matchCriterion.setter
    def matchCriterion(self, matchCriterion=None):
        if  matchCriterion is None:
            matchCriterion = SFString.DEFAULT_VALUE
        assertValidSFString(matchCriterion)
        self.__matchCriterion = matchCriterion
    @property # getter - - - - - - - - - -
    def objectType(self):
        """The objectType field specifies a set of labels used in the picking process."""
        return self.__objectType
    @objectType.setter
    def objectType(self, objectType=None):
        if  objectType is None:
            objectType = MFString.DEFAULT_VALUE
        assertValidMFString(objectType)
        self.__objectType = objectType
    @property # getter - - - - - - - - - -
    def sortOrder(self):
        """The sortOrder field determines the order provided for picked output events."""
        return self.__sortOrder
    @sortOrder.setter
    def sortOrder(self, sortOrder=None):
        if  sortOrder is None:
            sortOrder = SFString.DEFAULT_VALUE
        assertValidSFString(sortOrder)
        self.__sortOrder = sortOrder
    @property # getter - - - - - - - - - -
    def pickingGeometry(self):
        """[PointSet] pickingGeometry specifies the exact geometry coordinates that are used to perform the intersection testing of the picking operation."""
        return self.__pickingGeometry
    @pickingGeometry.setter
    def pickingGeometry(self, pickingGeometry=None):
        if  pickingGeometry is None:
            pickingGeometry = SFNode.DEFAULT_VALUE
        assertValidSFNode(pickingGeometry)
        if not isinstance(pickingGeometry, object):
            # print(flush=True)
            raise X3DTypeError(str(pickingGeometry) + ' does not have a valid node type object')
        self.__pickingGeometry = pickingGeometry
    @property # getter - - - - - - - - - -
    def pickTarget(self):
        """[X3DGroupingNode|X3DShapeNode|Inline] pickTarget specifies the list of nodes against which picking operations are performed."""
        return self.__pickTarget
    @pickTarget.setter
    def pickTarget(self, pickTarget=None):
        if  pickTarget is None:
            pickTarget = MFNode.DEFAULT_VALUE
        assertValidMFNode(pickTarget)
        self.__pickTarget = pickTarget
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.pickTarget) or bool(self.IS) or bool(self.metadata) or bool(self.pickingGeometry)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PointPickSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PointPickSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.intersectionType != 'BOUNDS':
            result += " intersectionType='" + self.intersectionType + "'"
        if self.matchCriterion != 'MATCH_ANY':
            result += " matchCriterion='" + self.matchCriterion + "'"
        if self.objectType != ["ALL"]:
            result += " objectType='" + MFString(self.objectType).XML() + "'"
        if self.sortOrder != 'CLOSEST':
            result += " sortOrder='" + self.sortOrder + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.pickingGeometry: # output this SFNode
                result += self.pickingGeometry.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.pickTarget: # walk each child node, if any
                for each in self.pickTarget:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</PointPickSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PointProperties(_X3DAppearanceChildNode):
    """
    PointProperties allows precise fine-grained control over the rendering style of PointSet node points inside the same Shape.
    """
    NAME = 'PointProperties'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PointProperties'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('colorMode', 'TEXTURE_AND_POINT_COLOR', FieldType.SFString, AccessType.inputOutput, 'PointProperties'),
        ('pointSizeAttenuation', [1, 0, 0], FieldType.MFFloat, AccessType.inputOutput, 'PointProperties'),
        ('pointSizeMaxValue', 1, FieldType.SFFloat, AccessType.inputOutput, 'PointProperties'),
        ('pointSizeMinValue', 1, FieldType.SFFloat, AccessType.inputOutput, 'PointProperties'),
        ('pointSizeScaleFactor', 1, FieldType.SFFloat, AccessType.inputOutput, 'PointProperties'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 colorMode='TEXTURE_AND_POINT_COLOR',
                 pointSizeAttenuation=[1, 0, 0],
                 pointSizeMaxValue=1,
                 pointSizeMinValue=1,
                 pointSizeScaleFactor=1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PointProperties __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.colorMode = colorMode
        self.pointSizeAttenuation = pointSizeAttenuation
        self.pointSizeMaxValue = pointSizeMaxValue
        self.pointSizeMinValue = pointSizeMinValue
        self.pointSizeScaleFactor = pointSizeScaleFactor
    @property # getter - - - - - - - - - -
    def colorMode(self):
        """colorMode has blending effect on the rendering of point sprites, applying supplied color (Color node or Material emissiveColor) and texture color."""
        return self.__colorMode
    @colorMode.setter
    def colorMode(self, colorMode=None):
        if  colorMode is None:
            colorMode = SFString.DEFAULT_VALUE
        assertValidSFString(colorMode)
        self.__colorMode = colorMode
    @property # getter - - - - - - - - - -
    def pointSizeAttenuation(self):
        """[0,+infinity) pointSizeAttenuation array values [a, b, c] are set to default values if undefined."""
        return self.__pointSizeAttenuation
    @pointSizeAttenuation.setter
    def pointSizeAttenuation(self, pointSizeAttenuation=None):
        if  pointSizeAttenuation is None:
            pointSizeAttenuation = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(pointSizeAttenuation)
        self.__pointSizeAttenuation = pointSizeAttenuation
    @property # getter - - - - - - - - - -
    def pointSizeMaxValue(self):
        """[0,+infinity) pointSizeMaxValue is maximum allowed scaling factor on nominal browser point scaling."""
        return self.__pointSizeMaxValue
    @pointSizeMaxValue.setter
    def pointSizeMaxValue(self, pointSizeMaxValue=None):
        if  pointSizeMaxValue is None:
            pointSizeMaxValue = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(pointSizeMaxValue)
        assertNonNegative('pointSizeMaxValue', pointSizeMaxValue)
        self.__pointSizeMaxValue = pointSizeMaxValue
    @property # getter - - - - - - - - - -
    def pointSizeMinValue(self):
        """[0,+infinity) pointSizeMinValue is minimum allowed scaling factor on nominal browser point scaling."""
        return self.__pointSizeMinValue
    @pointSizeMinValue.setter
    def pointSizeMinValue(self, pointSizeMinValue=None):
        if  pointSizeMinValue is None:
            pointSizeMinValue = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(pointSizeMinValue)
        assertNonNegative('pointSizeMinValue', pointSizeMinValue)
        self.__pointSizeMinValue = pointSizeMinValue
    @property # getter - - - - - - - - - -
    def pointSizeScaleFactor(self):
        """[1,+infinity) Nominal rendered point size is a browser-dependent minimum renderable point size, which is then multiplied by an additional pointSizeScaleFactor (which is greater than or equal to 1)."""
        return self.__pointSizeScaleFactor
    @pointSizeScaleFactor.setter
    def pointSizeScaleFactor(self, pointSizeScaleFactor=None):
        if  pointSizeScaleFactor is None:
            pointSizeScaleFactor = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(pointSizeScaleFactor)
        assertGreaterThanEquals('pointSizeScaleFactor', pointSizeScaleFactor, 1)
        self.__pointSizeScaleFactor = pointSizeScaleFactor
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PointProperties.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PointProperties'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorMode != 'TEXTURE_AND_POINT_COLOR':
            result += " colorMode='" + self.colorMode + "'"
        if self.pointSizeAttenuation != [1, 0, 0]:
            result += " pointSizeAttenuation='" + MFFloat(self.pointSizeAttenuation).XML() + "'"
        if self.pointSizeMaxValue != 1:
            result += " pointSizeMaxValue='" + SFFloat(self.pointSizeMaxValue).XML() + "'"
        if self.pointSizeMinValue != 1:
            result += " pointSizeMinValue='" + SFFloat(self.pointSizeMinValue).XML() + "'"
        if self.pointSizeScaleFactor != 1:
            result += " pointSizeScaleFactor='" + SFFloat(self.pointSizeScaleFactor).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PointProperties>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PointSet(_X3DGeometryNode):
    """
    PointSet is a node that contains a set of colored 3D points, represented by contained Color|ColorRGBA and Coordinate|CoordinateDouble nodes.
    """
    NAME = 'PointSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PointSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'PointSet'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'PointSet'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'PointSet'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'PointSet'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 color=None,
                 coord=None,
                 fogCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PointSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PointSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PointSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</PointSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Polyline2D(_X3DGeometryNode):
    """
    Polyline2D is a geometry node that defines a connected set of vertices in a contiguous set of line segments in X-Y plane.
    """
    NAME = 'Polyline2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Polyline2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('lineSegments', list(), FieldType.MFVec2f, AccessType.initializeOnly, 'Polyline2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 lineSegments=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Polyline2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.lineSegments = lineSegments
    @property # getter - - - - - - - - - -
    def lineSegments(self):
        """Coordinates of vertices connected into contiguous Polyline2D."""
        return self.__lineSegments
    @lineSegments.setter
    def lineSegments(self, lineSegments=None):
        if  lineSegments is None:
            lineSegments = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(lineSegments)
        self.__lineSegments = lineSegments
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Polyline2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Polyline2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.lineSegments != list():
            result += " lineSegments='" + MFVec2f(self.lineSegments).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Polyline2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PolylineEmitter(_X3DParticleEmitterNode):
    """
    PolylineEmitter emits particles along a single polyline.
    """
    NAME = 'PolylineEmitter'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PolylineEmitter'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('coordIndex', [-1], FieldType.MFInt32, AccessType.initializeOnly, 'PolylineEmitter'),
        ('direction', (0, 1, 0), FieldType.SFVec3f, AccessType.inputOutput, 'PolylineEmitter'),
        ('mass', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('speed', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('surfaceArea', 0, FieldType.SFFloat, AccessType.initializeOnly, 'X3DParticleEmitterNode'),
        ('variation', 0.25, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'PolylineEmitter'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 coordIndex=[-1],
                 direction=(0, 1, 0),
                 mass=0,
                 speed=0,
                 surfaceArea=0,
                 variation=0.25,
                 coord=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PolylineEmitter __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.coordIndex = coordIndex
        self.direction = direction
        self.mass = mass
        self.speed = speed
        self.surfaceArea = surfaceArea
        self.variation = variation
        self.coord = coord
    @property # getter - - - - - - - - - -
    def coordIndex(self):
        """[-1,+infinity) coordIndex indices are applied to contained Coordinate values in order to define randomly generated initial geometry of the particles."""
        return self.__coordIndex
    @coordIndex.setter
    def coordIndex(self, coordIndex=None):
        if  coordIndex is None:
            coordIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(coordIndex)
        assertGreaterThanEquals('coordIndex', coordIndex, -1)
        self.__coordIndex = coordIndex
    @property # getter - - - - - - - - - -
    def direction(self):
        """Initial direction from which particles emanate."""
        return self.__direction
    @direction.setter
    def direction(self, direction=None):
        if  direction is None:
            direction = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(direction)
        assertGreaterThanEquals('direction', direction, -1)
        assertLessThanEquals('direction', direction, 1)
        self.__direction = direction
    @property # getter - - - - - - - - - -
    def mass(self):
        """[0,+infinity) Basic mass of each particle, defined in mass base units (default is kilograms)."""
        return self.__mass
    @mass.setter
    def mass(self, mass=None):
        if  mass is None:
            mass = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(mass)
        assertNonNegative('mass', mass)
        self.__mass = mass
    @property # getter - - - - - - - - - -
    def speed(self):
        """[0,+infinity) Initial linear speed (default is m/s) imparted to all particles along their direction of movement."""
        return self.__speed
    @speed.setter
    def speed(self, speed=None):
        if  speed is None:
            speed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speed)
        assertNonNegative('speed', speed)
        self.__speed = speed
    @property # getter - - - - - - - - - -
    def surfaceArea(self):
        """[0,+infinity) Particle surface area in area base units (default is meters squared)."""
        return self.__surfaceArea
    @surfaceArea.setter
    def surfaceArea(self, surfaceArea=None):
        if  surfaceArea is None:
            surfaceArea = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(surfaceArea)
        assertNonNegative('surfaceArea', surfaceArea)
        self.__surfaceArea = surfaceArea
    @property # getter - - - - - - - - - -
    def variation(self):
        """[0,+infinity) Multiplier for the randomness used to control the range of possible output values."""
        return self.__variation
    @variation.setter
    def variation(self, variation=None):
        if  variation is None:
            variation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(variation)
        assertNonNegative('variation', variation)
        self.__variation = variation
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Coordinates for the line along which particles are randomly generated."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.coord) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PolylineEmitter.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PolylineEmitter'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.coordIndex != [-1]:
            result += " coordIndex='" + MFInt32(self.coordIndex).XML() + "'"
        if self.direction != (0, 1, 0):
            result += " direction='" + SFVec3f(self.direction).XML() + "'"
        if self.mass != 0:
            result += " mass='" + SFFloat(self.mass).XML() + "'"
        if self.speed != 0:
            result += " speed='" + SFFloat(self.speed).XML() + "'"
        if self.surfaceArea != 0:
            result += " surfaceArea='" + SFFloat(self.surfaceArea).XML() + "'"
        if self.variation != 0.25:
            result += " variation='" + SFFloat(self.variation).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PolylineEmitter>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Polypoint2D(_X3DGeometryNode):
    """
    Polypoint2D is a geometry node that defines a set of 2D points in X-Y plane.
    """
    NAME = 'Polypoint2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Polypoint2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('point', list(), FieldType.MFVec2f, AccessType.inputOutput, 'Polypoint2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 point=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Polypoint2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.point = point
    @property # getter - - - - - - - - - -
    def point(self):
        """2D coordinates of vertices."""
        return self.__point
    @point.setter
    def point(self, point=None):
        if  point is None:
            point = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(point)
        self.__point = point
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Polypoint2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Polypoint2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.point != list():
            result += " point='" + MFVec2f(self.point).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Polypoint2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PositionChaser(_X3DChaserNode):
    """
    PositionChaser generates a series of position values that progressively change from initial value to destination value.
    """
    NAME = 'PositionChaser'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PositionChaser'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('duration', 1, FieldType.SFTime, AccessType.initializeOnly, 'X3DChaserNode'),
        ('initialDestination', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'PositionChaser'),
        ('initialValue', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'PositionChaser'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 duration=1,
                 initialDestination=(0, 0, 0),
                 initialValue=(0, 0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PositionChaser __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.duration = duration
        self.initialDestination = initialDestination
        self.initialValue = initialValue
    @property # getter - - - - - - - - - -
    def duration(self):
        """[0,+infinity) duration is the time interval for filter response in seconds."""
        return self.__duration
    @duration.setter
    def duration(self, duration=None):
        if  duration is None:
            duration = SFTime.DEFAULT_VALUE
        assertValidSFTime(duration)
        assertNonNegative('duration', duration)
        self.__duration = duration
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(initialValue)
        self.__initialValue = initialValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PositionChaser.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PositionChaser'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.duration != 1:
            result += " duration='" + SFTime(self.duration).XML() + "'"
        if self.initialDestination != (0, 0, 0):
            result += " initialDestination='" + SFVec3f(self.initialDestination).XML() + "'"
        if self.initialValue != (0, 0, 0):
            result += " initialValue='" + SFVec3f(self.initialValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PositionChaser>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PositionChaser2D(_X3DChaserNode):
    """
    PositionChaser2D generates a series of 2D position values that progressively change from initial value to destination value.
    """
    NAME = 'PositionChaser2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PositionChaser2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('duration', 1, FieldType.SFTime, AccessType.initializeOnly, 'X3DChaserNode'),
        ('initialDestination', (0, 0), FieldType.SFVec2f, AccessType.initializeOnly, 'PositionChaser2D'),
        ('initialValue', (0, 0), FieldType.SFVec2f, AccessType.initializeOnly, 'PositionChaser2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 duration=1,
                 initialDestination=(0, 0),
                 initialValue=(0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PositionChaser2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.duration = duration
        self.initialDestination = initialDestination
        self.initialValue = initialValue
    @property # getter - - - - - - - - - -
    def duration(self):
        """[0,+infinity) duration is the time interval for filter response in seconds."""
        return self.__duration
    @duration.setter
    def duration(self, duration=None):
        if  duration is None:
            duration = SFTime.DEFAULT_VALUE
        assertValidSFTime(duration)
        assertNonNegative('duration', duration)
        self.__duration = duration
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(initialValue)
        self.__initialValue = initialValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PositionChaser2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PositionChaser2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.duration != 1:
            result += " duration='" + SFTime(self.duration).XML() + "'"
        if self.initialDestination != (0, 0):
            result += " initialDestination='" + SFVec2f(self.initialDestination).XML() + "'"
        if self.initialValue != (0, 0):
            result += " initialValue='" + SFVec2f(self.initialValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PositionChaser2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PositionDamper(_X3DDamperNode):
    """
    PositionDamper generates a series of position values that progressively change from initial value to destination value.
    """
    NAME = 'PositionDamper'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PositionDamper'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('initialDestination', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'PositionDamper'),
        ('initialValue', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'PositionDamper'),
        ('order', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DDamperNode'),
        ('tau', 0.3, FieldType.SFTime, AccessType.inputOutput, 'X3DDamperNode'),
        ('tolerance', -1, FieldType.SFFloat, AccessType.inputOutput, 'X3DDamperNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 initialDestination=(0, 0, 0),
                 initialValue=(0, 0, 0),
                 order=3,
                 tau=0.3,
                 tolerance=-1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PositionDamper __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.initialDestination = initialDestination
        self.initialValue = initialValue
        self.order = order
        self.tau = tau
        self.tolerance = tolerance
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(initialValue)
        self.__initialValue = initialValue
    @property # getter - - - - - - - - - -
    def order(self):
        """[0,5] order defines the number of internal filters (larger means smoother response, longer delay)."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 0)
        assertLessThanEquals('order', order, 5)
        self.__order = order
    @property # getter - - - - - - - - - -
    def tau(self):
        """[0,+infinity) tau is the exponential-decay time constant for filter response in seconds."""
        return self.__tau
    @tau.setter
    def tau(self, tau=None):
        if  tau is None:
            tau = SFTime.DEFAULT_VALUE
        assertValidSFTime(tau)
        assertNonNegative('tau', tau)
        self.__tau = tau
    @property # getter - - - - - - - - - -
    def tolerance(self):
        """[0,+infinity) or -1."""
        return self.__tolerance
    @tolerance.setter
    def tolerance(self, tolerance=None):
        if  tolerance is None:
            tolerance = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(tolerance)
        self.__tolerance = tolerance
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PositionDamper.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PositionDamper'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.initialDestination != (0, 0, 0):
            result += " initialDestination='" + SFVec3f(self.initialDestination).XML() + "'"
        if self.initialValue != (0, 0, 0):
            result += " initialValue='" + SFVec3f(self.initialValue).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.tau != 0.3:
            result += " tau='" + SFTime(self.tau).XML() + "'"
        if self.tolerance != -1:
            result += " tolerance='" + SFFloat(self.tolerance).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PositionDamper>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PositionDamper2D(_X3DDamperNode):
    """
    PositionDamper2D generates a series of 2D floating-point values that progressively change from initial value to destination value.
    """
    NAME = 'PositionDamper2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PositionDamper2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('initialDestination', (0, 0), FieldType.SFVec2f, AccessType.initializeOnly, 'PositionDamper2D'),
        ('initialValue', (0, 0), FieldType.SFVec2f, AccessType.initializeOnly, 'PositionDamper2D'),
        ('order', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DDamperNode'),
        ('tau', 0.3, FieldType.SFTime, AccessType.inputOutput, 'X3DDamperNode'),
        ('tolerance', -1, FieldType.SFFloat, AccessType.inputOutput, 'X3DDamperNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 initialDestination=(0, 0),
                 initialValue=(0, 0),
                 order=3,
                 tau=0.3,
                 tolerance=-1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PositionDamper2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.initialDestination = initialDestination
        self.initialValue = initialValue
        self.order = order
        self.tau = tau
        self.tolerance = tolerance
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(initialValue)
        self.__initialValue = initialValue
    @property # getter - - - - - - - - - -
    def order(self):
        """[0,5] order defines the number of internal filters (larger means smoother response, longer delay)."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 0)
        assertLessThanEquals('order', order, 5)
        self.__order = order
    @property # getter - - - - - - - - - -
    def tau(self):
        """[0,+infinity) tau is the exponential-decay time constant for filter response in seconds."""
        return self.__tau
    @tau.setter
    def tau(self, tau=None):
        if  tau is None:
            tau = SFTime.DEFAULT_VALUE
        assertValidSFTime(tau)
        assertNonNegative('tau', tau)
        self.__tau = tau
    @property # getter - - - - - - - - - -
    def tolerance(self):
        """[0,+infinity) or -1."""
        return self.__tolerance
    @tolerance.setter
    def tolerance(self, tolerance=None):
        if  tolerance is None:
            tolerance = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(tolerance)
        self.__tolerance = tolerance
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PositionDamper2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PositionDamper2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.initialDestination != (0, 0):
            result += " initialDestination='" + SFVec2f(self.initialDestination).XML() + "'"
        if self.initialValue != (0, 0):
            result += " initialValue='" + SFVec2f(self.initialValue).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.tau != 0.3:
            result += " tau='" + SFTime(self.tau).XML() + "'"
        if self.tolerance != -1:
            result += " tolerance='" + SFFloat(self.tolerance).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PositionDamper2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PositionInterpolator(_X3DInterpolatorNode):
    """
    PositionInterpolator generates a series of 3-tuple SFVec3f values.
    """
    NAME = 'PositionInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PositionInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFVec3f, AccessType.inputOutput, 'PositionInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PositionInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PositionInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PositionInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFVec3f(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PositionInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PositionInterpolator2D(_X3DInterpolatorNode):
    """
    PositionInterpolator2D generates a series of SFVec2f values.
    """
    NAME = 'PositionInterpolator2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PositionInterpolator2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFVec2f, AccessType.inputOutput, 'PositionInterpolator2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PositionInterpolator2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PositionInterpolator2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PositionInterpolator2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFVec2f(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</PositionInterpolator2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class PrimitivePickSensor(_X3DPickSensorNode):
    """
    If a non-uniform scale is applied to the pick sensor, correct results may require level 3 support.
    """
    NAME = 'PrimitivePickSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#PrimitivePickSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('intersectionType', 'BOUNDS', FieldType.SFString, AccessType.initializeOnly, 'X3DPickSensorNode'),
        ('matchCriterion', 'MATCH_ANY', FieldType.SFString, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('objectType', ["ALL"], FieldType.MFString, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('sortOrder', 'CLOSEST', FieldType.SFString, AccessType.initializeOnly, 'X3DPickSensorNode'),
        ('pickingGeometry', None, FieldType.SFNode, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('pickTarget', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 intersectionType='BOUNDS',
                 matchCriterion='MATCH_ANY',
                 objectType=["ALL"],
                 sortOrder='CLOSEST',
                 pickingGeometry=None,
                 pickTarget=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode PrimitivePickSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.intersectionType = intersectionType
        self.matchCriterion = matchCriterion
        self.objectType = objectType
        self.sortOrder = sortOrder
        self.pickingGeometry = pickingGeometry
        self.pickTarget = pickTarget
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def intersectionType(self):
        """intersectionType specifies precision of the collision computation."""
        return self.__intersectionType
    @intersectionType.setter
    def intersectionType(self, intersectionType=None):
        if  intersectionType is None:
            intersectionType = SFString.DEFAULT_VALUE
        assertValidSFString(intersectionType)
        self.__intersectionType = intersectionType
    @property # getter - - - - - - - - - -
    def matchCriterion(self):
        """defines whether the intersection test (i."""
        return self.__matchCriterion
    @matchCriterion.setter
    def matchCriterion(self, matchCriterion=None):
        if  matchCriterion is None:
            matchCriterion = SFString.DEFAULT_VALUE
        assertValidSFString(matchCriterion)
        self.__matchCriterion = matchCriterion
    @property # getter - - - - - - - - - -
    def objectType(self):
        """The objectType field specifies a set of labels used in the picking process."""
        return self.__objectType
    @objectType.setter
    def objectType(self, objectType=None):
        if  objectType is None:
            objectType = MFString.DEFAULT_VALUE
        assertValidMFString(objectType)
        self.__objectType = objectType
    @property # getter - - - - - - - - - -
    def sortOrder(self):
        """The sortOrder field determines the order provided for picked output events."""
        return self.__sortOrder
    @sortOrder.setter
    def sortOrder(self, sortOrder=None):
        if  sortOrder is None:
            sortOrder = SFString.DEFAULT_VALUE
        assertValidSFString(sortOrder)
        self.__sortOrder = sortOrder
    @property # getter - - - - - - - - - -
    def pickingGeometry(self):
        """[Cone|Cylinder|Sphere|Box] pickingGeometry specifies the exact geometry coordinates that are used to perform the intersection testing of the picking operation."""
        return self.__pickingGeometry
    @pickingGeometry.setter
    def pickingGeometry(self, pickingGeometry=None):
        if  pickingGeometry is None:
            pickingGeometry = SFNode.DEFAULT_VALUE
        assertValidSFNode(pickingGeometry)
        if not isinstance(pickingGeometry, object):
            # print(flush=True)
            raise X3DTypeError(str(pickingGeometry) + ' does not have a valid node type object')
        self.__pickingGeometry = pickingGeometry
    @property # getter - - - - - - - - - -
    def pickTarget(self):
        """[X3DGroupingNode|X3DShapeNode|Inline] pickTarget specifies the list of nodes against which picking operations are performed."""
        return self.__pickTarget
    @pickTarget.setter
    def pickTarget(self, pickTarget=None):
        if  pickTarget is None:
            pickTarget = MFNode.DEFAULT_VALUE
        assertValidMFNode(pickTarget)
        self.__pickTarget = pickTarget
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.pickTarget) or bool(self.IS) or bool(self.metadata) or bool(self.pickingGeometry)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function PrimitivePickSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<PrimitivePickSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.intersectionType != 'BOUNDS':
            result += " intersectionType='" + self.intersectionType + "'"
        if self.matchCriterion != 'MATCH_ANY':
            result += " matchCriterion='" + self.matchCriterion + "'"
        if self.objectType != ["ALL"]:
            result += " objectType='" + MFString(self.objectType).XML() + "'"
        if self.sortOrder != 'CLOSEST':
            result += " sortOrder='" + self.sortOrder + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.pickingGeometry: # output this SFNode
                result += self.pickingGeometry.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.pickTarget: # walk each child node, if any
                for each in self.pickTarget:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</PrimitivePickSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ProgramShader(_X3DShaderNode): #  # TODO fix additional inheritance method resolution order (MRO)
    """
    ProgramShader contains no field declarations and no plain-text source code.
    """
    NAME = 'ProgramShader'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ProgramShader'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('language', '', FieldType.SFString, AccessType.initializeOnly, 'X3DShaderNode'),
        ('programs', list(), FieldType.MFNode, AccessType.inputOutput, 'ProgramShader'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 language='',
                 programs=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ProgramShader __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.language = language
        self.programs = programs
    @property # getter - - - - - - - - - -
    def language(self):
        """The language field indicates to the X3D player which shading language is used."""
        return self.__language
    @language.setter
    def language(self, language=None):
        if  language is None:
            language = SFString.DEFAULT_VALUE
        assertValidSFString(language)
        self.__language = language
    @property # getter - - - - - - - - - -
    def programs(self):
        return self.__programs
    @programs.setter
    def programs(self, programs=None):
        if  programs is None:
            programs = MFNode.DEFAULT_VALUE
        assertValidMFNode(programs)
        self.__programs = programs
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.programs) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ProgramShader.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ProgramShader'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.language:
            result += " language='" + self.language + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.programs: # walk each child node, if any
                for each in self.programs:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ProgramShader>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ProjectionVolumeStyle(_X3DVolumeRenderStyleNode):
    """
    ProjectionVolumeStyle uses voxel data to directly generate output color.
    """
    NAME = 'ProjectionVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ProjectionVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('intensityThreshold', 0, FieldType.SFFloat, AccessType.inputOutput, 'ProjectionVolumeStyle'),
        ('type', 'MAX', FieldType.SFString, AccessType.inputOutput, 'ProjectionVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 intensityThreshold=0,
                 type='MAX',
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ProjectionVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.intensityThreshold = intensityThreshold
        self.type = type
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def intensityThreshold(self):
        """[0,1] Threshold value used when type=MIN (LMIP) or type=MAX (MIP)."""
        return self.__intensityThreshold
    @intensityThreshold.setter
    def intensityThreshold(self, intensityThreshold=None):
        if  intensityThreshold is None:
            intensityThreshold = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(intensityThreshold)
        assertZeroToOne('intensityThreshold', intensityThreshold)
        self.__intensityThreshold = intensityThreshold
    @property # getter - - - - - - - - - -
    def type(self):
        """If type=MAX then Maximum Intensity Projection (MIP) or Least MIP (LMIP) algorithm is used to generate output color."""
        return self.__type
    @type.setter
    def type(self, type=None):
        if  type is None:
            type = SFString.DEFAULT_VALUE
        assertValidSFString(type)
        self.__type = type
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ProjectionVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ProjectionVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.intensityThreshold != 0:
            result += " intensityThreshold='" + SFFloat(self.intensityThreshold).XML() + "'"
        if self.type != 'MAX':
            result += " type='" + self.type + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ProjectionVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ProtoInstance(_X3DPrototypeInstance, _X3DChildNode):
    """
    ProtoInstance can override field default values via fieldValue initializations. Non-recursive nested ProtoInstance and ProtoDeclare statements are allowed within a ProtoDeclare.
    """
    NAME = 'ProtoInstance'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ProtoInstance'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('name', '', FieldType.SFString, AccessType.inputOutput, 'ProtoInstance'),
        ('fieldValue', list(), FieldType.MFNode, AccessType.inputOutput, 'ProtoInstance'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 name='',
                 fieldValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ProtoInstance __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.name = name
        self.fieldValue = fieldValue
    @property # getter - - - - - - - - - -
    def name(self):
        """name of the prototype node being instanced."""
        return self.__name
    @name.setter
    def name(self, name=None):
        if  name is None:
            name = SFString.DEFAULT_VALUE
        assertValidSFString(name)
        self.__name = name
    @property # getter - - - - - - - - - -
    def fieldValue(self):
        """Include fieldValue statements if this ProtoInstance overrides default values in any of the original field declarations."""
        return self.__fieldValue
    @fieldValue.setter
    def fieldValue(self, fieldValue=None):
        if  fieldValue is None:
            fieldValue = MFNode.DEFAULT_VALUE
        # TODO type-aware checks for fieldValue
        if fieldValue: # walk each child node, if any
            for each in fieldValue:
                assertValidFieldInitializationValue(each.name, type(each.value), each.value, parent='fieldValue')
        self.__fieldValue = fieldValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.fieldValue) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ProtoInstance.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ProtoInstance'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.name:
            result += " name='" + self.name + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.fieldValue: # walk each child node, if any
                for each in self.fieldValue:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ProtoInstance>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ProximitySensor(_X3DEnvironmentalSensorNode):
    """
    ProximitySensor generates events when the viewer enters, exits and moves within a region of space (defined by a box).
    """
    NAME = 'ProximitySensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ProximitySensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'ProximitySensor'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('size', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DEnvironmentalSensorNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 center=(0, 0, 0),
                 enabled=True,
                 size=(0, 0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ProximitySensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.center = center
        self.enabled = enabled
        self.size = size
    @property # getter - - - - - - - - - -
    def center(self):
        """Position offset from origin of local coordinate system."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def size(self):
        """[0,+infinity) size of Proximity box."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(size)
        assertNonNegative('size', size)
        self.__size = size
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ProximitySensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ProximitySensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.size != (0, 0, 0):
            result += " size='" + SFVec3f(self.size).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ProximitySensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class QuadSet(_X3DComposedGeometryNode):
    """
    QuadSet is a geometry node that defines quadrilaterals.
    """
    NAME = 'QuadSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#QuadSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 normalPerVertex=True,
                 solid=True,
                 color=None,
                 coord=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode QuadSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color|ColorRGBA values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function QuadSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<QuadSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</QuadSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ReceiverPdu(_X3DNetworkSensorNode, _X3DBoundedObject):
    """
    ReceiverPdu is a networked Protocol Data Unit (PDU) information node that transmits the state of radio frequency (RF) receivers modeled in a simulation.
    """
    NAME = 'ReceiverPdu'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ReceiverPdu'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('address', 'localhost', FieldType.SFString, AccessType.inputOutput, 'ReceiverPdu'),
        ('applicationID', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('entityID', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('geoCoords', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'ReceiverPdu'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'ReceiverPdu'),
        ('multicastRelayHost', '', FieldType.SFString, AccessType.inputOutput, 'ReceiverPdu'),
        ('multicastRelayPort', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('networkMode', 'standAlone', FieldType.SFString, AccessType.inputOutput, 'ReceiverPdu'),
        ('port', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('radioID', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('readInterval', 0.1, FieldType.SFTime, AccessType.inputOutput, 'ReceiverPdu'),
        ('receivedPower', 0.0, FieldType.SFFloat, AccessType.inputOutput, 'ReceiverPdu'),
        ('receiverState', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('rtpHeaderExpected', False, FieldType.SFBool, AccessType.initializeOnly, 'ReceiverPdu'),
        ('siteID', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('transmitterApplicationID', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('transmitterEntityID', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('transmitterRadioID', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('transmitterSiteID', 0, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('whichGeometry', 1, FieldType.SFInt32, AccessType.inputOutput, 'ReceiverPdu'),
        ('writeInterval', 1.0, FieldType.SFTime, AccessType.inputOutput, 'ReceiverPdu'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 address='localhost',
                 applicationID=0,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 enabled=True,
                 entityID=0,
                 geoCoords=(0, 0, 0),
                 geoSystem=["GD", "WE"],
                 multicastRelayHost='',
                 multicastRelayPort=0,
                 networkMode='standAlone',
                 port=0,
                 radioID=0,
                 readInterval=0.1,
                 receivedPower=0.0,
                 receiverState=0,
                 rtpHeaderExpected=False,
                 siteID=0,
                 transmitterApplicationID=0,
                 transmitterEntityID=0,
                 transmitterRadioID=0,
                 transmitterSiteID=0,
                 visible=True,
                 whichGeometry=1,
                 writeInterval=1.0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ReceiverPdu __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.address = address
        self.applicationID = applicationID
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.entityID = entityID
        self.geoCoords = geoCoords
        self.geoSystem = geoSystem
        self.multicastRelayHost = multicastRelayHost
        self.multicastRelayPort = multicastRelayPort
        self.networkMode = networkMode
        self.port = port
        self.radioID = radioID
        self.readInterval = readInterval
        self.receivedPower = receivedPower
        self.receiverState = receiverState
        self.rtpHeaderExpected = rtpHeaderExpected
        self.siteID = siteID
        self.transmitterApplicationID = transmitterApplicationID
        self.transmitterEntityID = transmitterEntityID
        self.transmitterRadioID = transmitterRadioID
        self.transmitterSiteID = transmitterSiteID
        self.visible = visible
        self.whichGeometry = whichGeometry
        self.writeInterval = writeInterval
    @property # getter - - - - - - - - - -
    def address(self):
        """Multicast network address, or else "localhost" Example: 224."""
        return self.__address
    @address.setter
    def address(self, address=None):
        if  address is None:
            address = SFString.DEFAULT_VALUE
        assertValidSFString(address)
        self.__address = address
    @property # getter - - - - - - - - - -
    def applicationID(self):
        """Each simulation application that can respond to simulation management PDUs needs to have a unique applicationID."""
        return self.__applicationID
    @applicationID.setter
    def applicationID(self, applicationID=None):
        if  applicationID is None:
            applicationID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(applicationID)
        self.__applicationID = applicationID
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables the sensor node."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def entityID(self):
        """EntityID unique ID for entity within that application."""
        return self.__entityID
    @entityID.setter
    def entityID(self, entityID=None):
        if  entityID is None:
            entityID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entityID)
        self.__entityID = entityID
    @property # getter - - - - - - - - - -
    def geoCoords(self):
        """Geographic location (specified in current geoSystem coordinates) for children geometry (specified in relative coordinate system, in meters)."""
        return self.__geoCoords
    @geoCoords.setter
    def geoCoords(self, geoCoords=None):
        if  geoCoords is None:
            geoCoords = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(geoCoords)
        self.__geoCoords = geoCoords
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def multicastRelayHost(self):
        """Fallback server address if multicast not available locally."""
        return self.__multicastRelayHost
    @multicastRelayHost.setter
    def multicastRelayHost(self, multicastRelayHost=None):
        if  multicastRelayHost is None:
            multicastRelayHost = SFString.DEFAULT_VALUE
        assertValidSFString(multicastRelayHost)
        self.__multicastRelayHost = multicastRelayHost
    @property # getter - - - - - - - - - -
    def multicastRelayPort(self):
        """Fallback server port if multicast not available locally."""
        return self.__multicastRelayPort
    @multicastRelayPort.setter
    def multicastRelayPort(self, multicastRelayPort=None):
        if  multicastRelayPort is None:
            multicastRelayPort = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(multicastRelayPort)
        self.__multicastRelayPort = multicastRelayPort
    @property # getter - - - - - - - - - -
    def networkMode(self):
        """Whether this entity is ignoring the network, sending DIS packets to the network, or receiving DIS packets from the network."""
        return self.__networkMode
    @networkMode.setter
    def networkMode(self, networkMode=None):
        if  networkMode is None:
            networkMode = SFString.DEFAULT_VALUE
        assertValidSFString(networkMode)
        self.__networkMode = networkMode
    @property # getter - - - - - - - - - -
    def port(self):
        """Multicast network port, for example: 3000."""
        return self.__port
    @port.setter
    def port(self, port=None):
        if  port is None:
            port = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(port)
        self.__port = port
    @property # getter - - - - - - - - - -
    def radioID(self):
        """Identifies a particular radio within a given entity."""
        return self.__radioID
    @radioID.setter
    def radioID(self, radioID=None):
        if  radioID is None:
            radioID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(radioID)
        self.__radioID = radioID
    @property # getter - - - - - - - - - -
    def readInterval(self):
        """[0,+infinity) Seconds between read updates, 0 means no reading."""
        return self.__readInterval
    @readInterval.setter
    def readInterval(self, readInterval=None):
        if  readInterval is None:
            readInterval = SFTime.DEFAULT_VALUE
        assertValidSFTime(readInterval)
        assertNonNegative('readInterval', readInterval)
        self.__readInterval = readInterval
    @property # getter - - - - - - - - - -
    def receivedPower(self):
        """receivedPower indicates radio frequency (RF) power received, in units of decibel-milliwatts (dBm), after applying any propagation loss and antenna gain."""
        return self.__receivedPower
    @receivedPower.setter
    def receivedPower(self, receivedPower=None):
        if  receivedPower is None:
            receivedPower = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(receivedPower)
        self.__receivedPower = receivedPower
    @property # getter - - - - - - - - - -
    def receiverState(self):
        """receiverState indicates if receiver is currently idle or busy via one of these enumerated values: 0 = off, 1 = on but not receiving, or 2 = on and receiving."""
        return self.__receiverState
    @receiverState.setter
    def receiverState(self, receiverState=None):
        if  receiverState is None:
            receiverState = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(receiverState)
        self.__receiverState = receiverState
    @property # getter - - - - - - - - - -
    def rtpHeaderExpected(self):
        """Whether RTP headers are prepended to DIS PDUs."""
        return self.__rtpHeaderExpected
    @rtpHeaderExpected.setter
    def rtpHeaderExpected(self, rtpHeaderExpected=None):
        if  rtpHeaderExpected is None:
            rtpHeaderExpected = SFBool.DEFAULT_VALUE
        assertValidSFBool(rtpHeaderExpected)
        self.__rtpHeaderExpected = rtpHeaderExpected
    @property # getter - - - - - - - - - -
    def siteID(self):
        """Simulation/exercise siteID of the participating LAN or organization."""
        return self.__siteID
    @siteID.setter
    def siteID(self, siteID=None):
        if  siteID is None:
            siteID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(siteID)
        self.__siteID = siteID
    @property # getter - - - - - - - - - -
    def transmitterApplicationID(self):
        """Simulation/exercise transmitterApplicationID is unique for transmitter application at that site."""
        return self.__transmitterApplicationID
    @transmitterApplicationID.setter
    def transmitterApplicationID(self, transmitterApplicationID=None):
        if  transmitterApplicationID is None:
            transmitterApplicationID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(transmitterApplicationID)
        self.__transmitterApplicationID = transmitterApplicationID
    @property # getter - - - - - - - - - -
    def transmitterEntityID(self):
        """Simulation/exercise transmitterEntityID is a unique ID for a single entity within that application."""
        return self.__transmitterEntityID
    @transmitterEntityID.setter
    def transmitterEntityID(self, transmitterEntityID=None):
        if  transmitterEntityID is None:
            transmitterEntityID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(transmitterEntityID)
        self.__transmitterEntityID = transmitterEntityID
    @property # getter - - - - - - - - - -
    def transmitterRadioID(self):
        """Identifies a particular radio within a given entity."""
        return self.__transmitterRadioID
    @transmitterRadioID.setter
    def transmitterRadioID(self, transmitterRadioID=None):
        if  transmitterRadioID is None:
            transmitterRadioID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(transmitterRadioID)
        self.__transmitterRadioID = transmitterRadioID
    @property # getter - - - - - - - - - -
    def transmitterSiteID(self):
        """Simulation/exercise transmitterSiteID of the participating LAN or organization."""
        return self.__transmitterSiteID
    @transmitterSiteID.setter
    def transmitterSiteID(self, transmitterSiteID=None):
        if  transmitterSiteID is None:
            transmitterSiteID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(transmitterSiteID)
        self.__transmitterSiteID = transmitterSiteID
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def whichGeometry(self):
        """Select geometry to render: -1 for no geometry, 0 for text trace, 1 for default geometry, (optional) higher values to render different states."""
        return self.__whichGeometry
    @whichGeometry.setter
    def whichGeometry(self, whichGeometry=None):
        if  whichGeometry is None:
            whichGeometry = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(whichGeometry)
        self.__whichGeometry = whichGeometry
    @property # getter - - - - - - - - - -
    def writeInterval(self):
        """[0,+infinity) Seconds between write updates, 0 means no writing (sending)."""
        return self.__writeInterval
    @writeInterval.setter
    def writeInterval(self, writeInterval=None):
        if  writeInterval is None:
            writeInterval = SFTime.DEFAULT_VALUE
        assertValidSFTime(writeInterval)
        assertNonNegative('writeInterval', writeInterval)
        self.__writeInterval = writeInterval
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ReceiverPdu.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ReceiverPdu'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.address != 'localhost':
            result += " address='" + self.address + "'"
        if self.applicationID != 0:
            result += " applicationID='" + SFInt32(self.applicationID).XML() + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.entityID != 0:
            result += " entityID='" + SFInt32(self.entityID).XML() + "'"
        if self.geoCoords != (0, 0, 0):
            result += " geoCoords='" + SFVec3d(self.geoCoords).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.multicastRelayHost:
            result += " multicastRelayHost='" + self.multicastRelayHost + "'"
        if self.multicastRelayPort != 0:
            result += " multicastRelayPort='" + SFInt32(self.multicastRelayPort).XML() + "'"
        if self.networkMode != 'standAlone':
            result += " networkMode='" + self.networkMode + "'"
        if self.port != 0:
            result += " port='" + SFInt32(self.port).XML() + "'"
        if self.radioID != 0:
            result += " radioID='" + SFInt32(self.radioID).XML() + "'"
        if self.readInterval != 0.1:
            result += " readInterval='" + SFTime(self.readInterval).XML() + "'"
        if self.receivedPower != 0.0:
            result += " receivedPower='" + SFFloat(self.receivedPower).XML() + "'"
        if self.receiverState != 0:
            result += " receiverState='" + SFInt32(self.receiverState).XML() + "'"
        if self.rtpHeaderExpected != False:
            result += " rtpHeaderExpected='" + SFBool(self.rtpHeaderExpected).XML() + "'"
        if self.siteID != 0:
            result += " siteID='" + SFInt32(self.siteID).XML() + "'"
        if self.transmitterApplicationID != 0:
            result += " transmitterApplicationID='" + SFInt32(self.transmitterApplicationID).XML() + "'"
        if self.transmitterEntityID != 0:
            result += " transmitterEntityID='" + SFInt32(self.transmitterEntityID).XML() + "'"
        if self.transmitterRadioID != 0:
            result += " transmitterRadioID='" + SFInt32(self.transmitterRadioID).XML() + "'"
        if self.transmitterSiteID != 0:
            result += " transmitterSiteID='" + SFInt32(self.transmitterSiteID).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if self.whichGeometry != 1:
            result += " whichGeometry='" + SFInt32(self.whichGeometry).XML() + "'"
        if self.writeInterval != 1.0:
            result += " writeInterval='" + SFTime(self.writeInterval).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ReceiverPdu>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Rectangle2D(_X3DGeometryNode):
    """
    Rectangle2D is a geometry node that defines a 2D rectangle in X-Y plane.
    """
    NAME = 'Rectangle2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Rectangle2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('size', (2, 2), FieldType.SFVec2f, AccessType.initializeOnly, 'Rectangle2D'),
        ('solid', False, FieldType.SFBool, AccessType.initializeOnly, 'Rectangle2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 size=(2, 2),
                 solid=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Rectangle2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.size = size
        self.solid = solid
    @property # getter - - - - - - - - - -
    def size(self):
        """2D dimensions of Rectangle2D."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(size)
        assertPositive('size', size)
        self.__size = size
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Rectangle2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Rectangle2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.size != (2, 2):
            result += " size='" + SFVec2f(self.size).XML() + "'"
        if self.solid != False:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Rectangle2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class RigidBody(_X3DNode):
    """
    RigidBody describes a collection of shapes with a mass distribution that is affected by the physics model.
    """
    NAME = 'RigidBody'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#RigidBody'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('angularDampingFactor', 0.001, FieldType.SFFloat, AccessType.inputOutput, 'RigidBody'),
        ('angularVelocity', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'RigidBody'),
        ('autoDamp', False, FieldType.SFBool, AccessType.inputOutput, 'RigidBody'),
        ('autoDisable', False, FieldType.SFBool, AccessType.inputOutput, 'RigidBody'),
        ('centerOfMass', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'RigidBody'),
        ('disableAngularSpeed', 0, FieldType.SFFloat, AccessType.inputOutput, 'RigidBody'),
        ('disableLinearSpeed', 0, FieldType.SFFloat, AccessType.inputOutput, 'RigidBody'),
        ('disableTime', 0, FieldType.SFTime, AccessType.inputOutput, 'RigidBody'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'RigidBody'),
        ('finiteRotationAxis', (0, 1, 0), FieldType.SFVec3f, AccessType.inputOutput, 'RigidBody'),
        ('fixed', False, FieldType.SFBool, AccessType.inputOutput, 'RigidBody'),
        ('forces', list(), FieldType.MFVec3f, AccessType.inputOutput, 'RigidBody'),
        ('inertia', (1, 0, 0, 0, 1, 0, 0, 0, 1), FieldType.SFMatrix3f, AccessType.inputOutput, 'RigidBody'),
        ('linearDampingFactor', 0.001, FieldType.SFFloat, AccessType.inputOutput, 'RigidBody'),
        ('linearVelocity', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'RigidBody'),
        ('mass', 1, FieldType.SFFloat, AccessType.inputOutput, 'RigidBody'),
        ('orientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'RigidBody'),
        ('position', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'RigidBody'),
        ('torques', list(), FieldType.MFVec3f, AccessType.inputOutput, 'RigidBody'),
        ('useFiniteRotation', False, FieldType.SFBool, AccessType.inputOutput, 'RigidBody'),
        ('useGlobalGravity', True, FieldType.SFBool, AccessType.inputOutput, 'RigidBody'),
        ('massDensityModel', None, FieldType.SFNode, AccessType.inputOutput, 'RigidBody'),
        ('geometry', list(), FieldType.MFNode, AccessType.inputOutput, 'RigidBody'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 angularDampingFactor=0.001,
                 angularVelocity=(0, 0, 0),
                 autoDamp=False,
                 autoDisable=False,
                 centerOfMass=(0, 0, 0),
                 disableAngularSpeed=0,
                 disableLinearSpeed=0,
                 disableTime=0,
                 enabled=True,
                 finiteRotationAxis=(0, 1, 0),
                 fixed=False,
                 forces=list(),
                 inertia=(1, 0, 0, 0, 1, 0, 0, 0, 1),
                 linearDampingFactor=0.001,
                 linearVelocity=(0, 0, 0),
                 mass=1,
                 orientation=(0, 0, 1, 0),
                 position=(0, 0, 0),
                 torques=list(),
                 useFiniteRotation=False,
                 useGlobalGravity=True,
                 massDensityModel=None,
                 geometry=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode RigidBody __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.angularDampingFactor = angularDampingFactor
        self.angularVelocity = angularVelocity
        self.autoDamp = autoDamp
        self.autoDisable = autoDisable
        self.centerOfMass = centerOfMass
        self.disableAngularSpeed = disableAngularSpeed
        self.disableLinearSpeed = disableLinearSpeed
        self.disableTime = disableTime
        self.enabled = enabled
        self.finiteRotationAxis = finiteRotationAxis
        self.fixed = fixed
        self.forces = forces
        self.inertia = inertia
        self.linearDampingFactor = linearDampingFactor
        self.linearVelocity = linearVelocity
        self.mass = mass
        self.orientation = orientation
        self.position = position
        self.torques = torques
        self.useFiniteRotation = useFiniteRotation
        self.useGlobalGravity = useGlobalGravity
        self.massDensityModel = massDensityModel
        self.geometry = geometry
    @property # getter - - - - - - - - - -
    def angularDampingFactor(self):
        """[0,1] angularDampingFactor automatically damps a portion of body motion over time."""
        return self.__angularDampingFactor
    @angularDampingFactor.setter
    def angularDampingFactor(self, angularDampingFactor=None):
        if  angularDampingFactor is None:
            angularDampingFactor = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(angularDampingFactor)
        self.__angularDampingFactor = angularDampingFactor
    @property # getter - - - - - - - - - -
    def angularVelocity(self):
        """angularVelocity sets constant velocity value to object every frame, and reports updates by physics model."""
        return self.__angularVelocity
    @angularVelocity.setter
    def angularVelocity(self, angularVelocity=None):
        if  angularVelocity is None:
            angularVelocity = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(angularVelocity)
        self.__angularVelocity = angularVelocity
    @property # getter - - - - - - - - - -
    def autoDamp(self):
        """autoDamp enables/disables angularDampingFactor and linearDampingFactor."""
        return self.__autoDamp
    @autoDamp.setter
    def autoDamp(self, autoDamp=None):
        if  autoDamp is None:
            autoDamp = SFBool.DEFAULT_VALUE
        assertValidSFBool(autoDamp)
        self.__autoDamp = autoDamp
    @property # getter - - - - - - - - - -
    def autoDisable(self):
        """autoDisable toggles operation of disableAngularSpeed, disableLinearSpeed, disableTime."""
        return self.__autoDisable
    @autoDisable.setter
    def autoDisable(self, autoDisable=None):
        if  autoDisable is None:
            autoDisable = SFBool.DEFAULT_VALUE
        assertValidSFBool(autoDisable)
        self.__autoDisable = autoDisable
    @property # getter - - - - - - - - - -
    def centerOfMass(self):
        """centerOfMass defines local center of mass for physics calculations."""
        return self.__centerOfMass
    @centerOfMass.setter
    def centerOfMass(self, centerOfMass=None):
        if  centerOfMass is None:
            centerOfMass = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(centerOfMass)
        self.__centerOfMass = centerOfMass
    @property # getter - - - - - - - - - -
    def disableAngularSpeed(self):
        """[0,+infinity) disableAngularSpeed defines lower-limit tolerance value when body is considered at rest and not part of rigid body calculations, reducing numeric instabilities."""
        return self.__disableAngularSpeed
    @disableAngularSpeed.setter
    def disableAngularSpeed(self, disableAngularSpeed=None):
        if  disableAngularSpeed is None:
            disableAngularSpeed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(disableAngularSpeed)
        self.__disableAngularSpeed = disableAngularSpeed
    @property # getter - - - - - - - - - -
    def disableLinearSpeed(self):
        """[0,+infinity) disableLinearSpeed defines lower-limit tolerance value when body is considered at rest and not part of rigid body calculation, reducing numeric instabilitiess."""
        return self.__disableLinearSpeed
    @disableLinearSpeed.setter
    def disableLinearSpeed(self, disableLinearSpeed=None):
        if  disableLinearSpeed is None:
            disableLinearSpeed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(disableLinearSpeed)
        self.__disableLinearSpeed = disableLinearSpeed
    @property # getter - - - - - - - - - -
    def disableTime(self):
        """[0,+infinity) disableTime defines interval when body becomes at rest and not part of rigid body calculations, reducing numeric instabilities."""
        return self.__disableTime
    @disableTime.setter
    def disableTime(self, disableTime=None):
        if  disableTime is None:
            disableTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(disableTime)
        assertNonNegative('disableTime', disableTime)
        self.__disableTime = disableTime
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def finiteRotationAxis(self):
        """finiteRotationAxis specifies vector around which the object rotates."""
        return self.__finiteRotationAxis
    @finiteRotationAxis.setter
    def finiteRotationAxis(self, finiteRotationAxis=None):
        if  finiteRotationAxis is None:
            finiteRotationAxis = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(finiteRotationAxis)
        self.__finiteRotationAxis = finiteRotationAxis
    @property # getter - - - - - - - - - -
    def fixed(self):
        """fixed indicates whether body is able to move."""
        return self.__fixed
    @fixed.setter
    def fixed(self, fixed=None):
        if  fixed is None:
            fixed = SFBool.DEFAULT_VALUE
        assertValidSFBool(fixed)
        self.__fixed = fixed
    @property # getter - - - - - - - - - -
    def forces(self):
        """forces defines linear force values applied to the object every frame."""
        return self.__forces
    @forces.setter
    def forces(self, forces=None):
        if  forces is None:
            forces = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(forces)
        self.__forces = forces
    @property # getter - - - - - - - - - -
    def inertia(self):
        """inertia matrix defines a 3x2 inertia tensor matrix."""
        return self.__inertia
    @inertia.setter
    def inertia(self, inertia=None):
        if  inertia is None:
            inertia = SFMatrix3f.DEFAULT_VALUE
        assertValidSFMatrix3f(inertia)
        self.__inertia = inertia
    @property # getter - - - - - - - - - -
    def linearDampingFactor(self):
        """[0,1] linearDampingFactor automatically damps a portion of body motion over time."""
        return self.__linearDampingFactor
    @linearDampingFactor.setter
    def linearDampingFactor(self, linearDampingFactor=None):
        if  linearDampingFactor is None:
            linearDampingFactor = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(linearDampingFactor)
        self.__linearDampingFactor = linearDampingFactor
    @property # getter - - - - - - - - - -
    def linearVelocity(self):
        """linearVelocity sets constant velocity value to object every frame, and reports updates by physics model."""
        return self.__linearVelocity
    @linearVelocity.setter
    def linearVelocity(self, linearVelocity=None):
        if  linearVelocity is None:
            linearVelocity = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(linearVelocity)
        self.__linearVelocity = linearVelocity
    @property # getter - - - - - - - - - -
    def mass(self):
        """(0,1] mass of the body in kilograms."""
        return self.__mass
    @mass.setter
    def mass(self, mass=None):
        if  mass is None:
            mass = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(mass)
        self.__mass = mass
    @property # getter - - - - - - - - - -
    def orientation(self):
        """orientation sets body direction in world space, then reports physics updates."""
        return self.__orientation
    @orientation.setter
    def orientation(self, orientation=None):
        if  orientation is None:
            orientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(orientation)
        self.__orientation = orientation
    @property # getter - - - - - - - - - -
    def position(self):
        """position sets body location in world space, then reports physics updates."""
        return self.__position
    @position.setter
    def position(self, position=None):
        if  position is None:
            position = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(position)
        self.__position = position
    @property # getter - - - - - - - - - -
    def torques(self):
        """torques defines rotational force values applied to the object every frame."""
        return self.__torques
    @torques.setter
    def torques(self, torques=None):
        if  torques is None:
            torques = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(torques)
        self.__torques = torques
    @property # getter - - - - - - - - - -
    def useFiniteRotation(self):
        """useFiniteRotation enables/disables higher-resolution, higher-cost computational method for calculating rotations."""
        return self.__useFiniteRotation
    @useFiniteRotation.setter
    def useFiniteRotation(self, useFiniteRotation=None):
        if  useFiniteRotation is None:
            useFiniteRotation = SFBool.DEFAULT_VALUE
        assertValidSFBool(useFiniteRotation)
        self.__useFiniteRotation = useFiniteRotation
    @property # getter - - - - - - - - - -
    def useGlobalGravity(self):
        """useGlobalGravity indicates whether this particular body is influenced by parent RigidBodyCollection's gravity setting."""
        return self.__useGlobalGravity
    @useGlobalGravity.setter
    def useGlobalGravity(self, useGlobalGravity=None):
        if  useGlobalGravity is None:
            useGlobalGravity = SFBool.DEFAULT_VALUE
        assertValidSFBool(useGlobalGravity)
        self.__useGlobalGravity = useGlobalGravity
    @property # getter - - - - - - - - - -
    def massDensityModel(self):
        return self.__massDensityModel
    @massDensityModel.setter
    def massDensityModel(self, massDensityModel=None):
        if  massDensityModel is None:
            massDensityModel = SFNode.DEFAULT_VALUE
        assertValidSFNode(massDensityModel)
        if not isinstance(massDensityModel, object):
            # print(flush=True)
            raise X3DTypeError(str(massDensityModel) + ' does not have a valid node type object')
        self.__massDensityModel = massDensityModel
    @property # getter - - - - - - - - - -
    def geometry(self):
        return self.__geometry
    @geometry.setter
    def geometry(self, geometry=None):
        if  geometry is None:
            geometry = MFNode.DEFAULT_VALUE
        assertValidMFNode(geometry)
        self.__geometry = geometry
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.geometry) or bool(self.IS) or bool(self.massDensityModel) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function RigidBody.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<RigidBody'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.angularDampingFactor != 0.001:
            result += " angularDampingFactor='" + SFFloat(self.angularDampingFactor).XML() + "'"
        if self.angularVelocity != (0, 0, 0):
            result += " angularVelocity='" + SFVec3f(self.angularVelocity).XML() + "'"
        if self.autoDamp != False:
            result += " autoDamp='" + SFBool(self.autoDamp).XML() + "'"
        if self.autoDisable != False:
            result += " autoDisable='" + SFBool(self.autoDisable).XML() + "'"
        if self.centerOfMass != (0, 0, 0):
            result += " centerOfMass='" + SFVec3f(self.centerOfMass).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.disableAngularSpeed != 0:
            result += " disableAngularSpeed='" + SFFloat(self.disableAngularSpeed).XML() + "'"
        if self.disableLinearSpeed != 0:
            result += " disableLinearSpeed='" + SFFloat(self.disableLinearSpeed).XML() + "'"
        if self.disableTime != 0:
            result += " disableTime='" + SFTime(self.disableTime).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.finiteRotationAxis != (0, 1, 0):
            result += " finiteRotationAxis='" + SFVec3f(self.finiteRotationAxis).XML() + "'"
        if self.fixed != False:
            result += " fixed='" + SFBool(self.fixed).XML() + "'"
        if self.forces != list():
            result += " forces='" + MFVec3f(self.forces).XML() + "'"
        if self.inertia != (1, 0, 0, 0, 1, 0, 0, 0, 1):
            result += " inertia='" + SFMatrix3f(self.inertia).XML() + "'"
        if self.linearDampingFactor != 0.001:
            result += " linearDampingFactor='" + SFFloat(self.linearDampingFactor).XML() + "'"
        if self.linearVelocity != (0, 0, 0):
            result += " linearVelocity='" + SFVec3f(self.linearVelocity).XML() + "'"
        if self.mass != 1:
            result += " mass='" + SFFloat(self.mass).XML() + "'"
        if self.orientation != (0, 0, 1, 0):
            result += " orientation='" + SFRotation(self.orientation).XML() + "'"
        if self.position != (0, 0, 0):
            result += " position='" + SFVec3f(self.position).XML() + "'"
        if self.torques != list():
            result += " torques='" + MFVec3f(self.torques).XML() + "'"
        if self.useFiniteRotation != False:
            result += " useFiniteRotation='" + SFBool(self.useFiniteRotation).XML() + "'"
        if self.useGlobalGravity != True:
            result += " useGlobalGravity='" + SFBool(self.useGlobalGravity).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.massDensityModel: # output this SFNode
                result += self.massDensityModel.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.geometry: # walk each child node, if any
                for each in self.geometry:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</RigidBody>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class RigidBodyCollection(_X3DChildNode):
    """
    RigidBodyCollection represents a system of bodies that interact within a single physics model.
    """
    NAME = 'RigidBodyCollection'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#RigidBodyCollection'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('autoDisable', False, FieldType.SFBool, AccessType.inputOutput, 'RigidBodyCollection'),
        ('constantForceMix', 0.0001, FieldType.SFFloat, AccessType.inputOutput, 'RigidBodyCollection'),
        ('contactSurfaceThickness', 0, FieldType.SFFloat, AccessType.inputOutput, 'RigidBodyCollection'),
        ('disableAngularSpeed', 0, FieldType.SFFloat, AccessType.inputOutput, 'RigidBodyCollection'),
        ('disableLinearSpeed', 0, FieldType.SFFloat, AccessType.inputOutput, 'RigidBodyCollection'),
        ('disableTime', 0, FieldType.SFTime, AccessType.inputOutput, 'RigidBodyCollection'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'RigidBodyCollection'),
        ('errorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'RigidBodyCollection'),
        ('gravity', (0, -9.8, 0), FieldType.SFVec3f, AccessType.inputOutput, 'RigidBodyCollection'),
        ('iterations', 10, FieldType.SFInt32, AccessType.inputOutput, 'RigidBodyCollection'),
        ('maxCorrectionSpeed', -1, FieldType.SFFloat, AccessType.inputOutput, 'RigidBodyCollection'),
        ('preferAccuracy', False, FieldType.SFBool, AccessType.inputOutput, 'RigidBodyCollection'),
        ('collider', None, FieldType.SFNode, AccessType.initializeOnly, 'RigidBodyCollection'),
        ('bodies', list(), FieldType.MFNode, AccessType.inputOutput, 'RigidBodyCollection'),
        ('joints', list(), FieldType.MFNode, AccessType.inputOutput, 'RigidBodyCollection'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 autoDisable=False,
                 constantForceMix=0.0001,
                 contactSurfaceThickness=0,
                 disableAngularSpeed=0,
                 disableLinearSpeed=0,
                 disableTime=0,
                 enabled=True,
                 errorCorrection=0.8,
                 gravity=(0, -9.8, 0),
                 iterations=10,
                 maxCorrectionSpeed=-1,
                 preferAccuracy=False,
                 collider=None,
                 bodies=list(),
                 joints=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode RigidBodyCollection __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.autoDisable = autoDisable
        self.constantForceMix = constantForceMix
        self.contactSurfaceThickness = contactSurfaceThickness
        self.disableAngularSpeed = disableAngularSpeed
        self.disableLinearSpeed = disableLinearSpeed
        self.disableTime = disableTime
        self.enabled = enabled
        self.errorCorrection = errorCorrection
        self.gravity = gravity
        self.iterations = iterations
        self.maxCorrectionSpeed = maxCorrectionSpeed
        self.preferAccuracy = preferAccuracy
        self.collider = collider
        self.bodies = bodies
        self.joints = joints
    @property # getter - - - - - - - - - -
    def autoDisable(self):
        """autoDisable toggles operation of disableAngularSpeed, disableLinearSpeed, disableTime."""
        return self.__autoDisable
    @autoDisable.setter
    def autoDisable(self, autoDisable=None):
        if  autoDisable is None:
            autoDisable = SFBool.DEFAULT_VALUE
        assertValidSFBool(autoDisable)
        self.__autoDisable = autoDisable
    @property # getter - - - - - - - - - -
    def constantForceMix(self):
        """[0,+infinity) constantForceMix modifies damping calculations by violating normal constraints while applying small, constant forces in those calculations."""
        return self.__constantForceMix
    @constantForceMix.setter
    def constantForceMix(self, constantForceMix=None):
        if  constantForceMix is None:
            constantForceMix = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(constantForceMix)
        self.__constantForceMix = constantForceMix
    @property # getter - - - - - - - - - -
    def contactSurfaceThickness(self):
        """[0,+infinity) contactSurfaceThickness defines how far bodies may interpenetrate after a collision, allowing simulation of softer bodies that deform somewhat during collision."""
        return self.__contactSurfaceThickness
    @contactSurfaceThickness.setter
    def contactSurfaceThickness(self, contactSurfaceThickness=None):
        if  contactSurfaceThickness is None:
            contactSurfaceThickness = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(contactSurfaceThickness)
        self.__contactSurfaceThickness = contactSurfaceThickness
    @property # getter - - - - - - - - - -
    def disableAngularSpeed(self):
        """[0,+infinity) disableAngularSpeed defines lower-limit tolerance value when body is considered at rest and not part of rigid body calculations, reducing numeric instabilities."""
        return self.__disableAngularSpeed
    @disableAngularSpeed.setter
    def disableAngularSpeed(self, disableAngularSpeed=None):
        if  disableAngularSpeed is None:
            disableAngularSpeed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(disableAngularSpeed)
        self.__disableAngularSpeed = disableAngularSpeed
    @property # getter - - - - - - - - - -
    def disableLinearSpeed(self):
        """[0,+infinity) disableLinearSpeed defines lower-limit tolerance value when body is considered at rest and not part of rigid body calculation, reducing numeric instabilitiess."""
        return self.__disableLinearSpeed
    @disableLinearSpeed.setter
    def disableLinearSpeed(self, disableLinearSpeed=None):
        if  disableLinearSpeed is None:
            disableLinearSpeed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(disableLinearSpeed)
        self.__disableLinearSpeed = disableLinearSpeed
    @property # getter - - - - - - - - - -
    def disableTime(self):
        """[0,+infinity) disableTime defines interval when body becomes at rest and not part of rigid body calculations, reducing numeric instabilities."""
        return self.__disableTime
    @disableTime.setter
    def disableTime(self, disableTime=None):
        if  disableTime is None:
            disableTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(disableTime)
        assertNonNegative('disableTime', disableTime)
        self.__disableTime = disableTime
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def errorCorrection(self):
        """[0,1] errorCorrection describes how quickly intersection errors due to floating-point inaccuracies are resolved (0=no correction, 1=all corrected in single step)."""
        return self.__errorCorrection
    @errorCorrection.setter
    def errorCorrection(self, errorCorrection=None):
        if  errorCorrection is None:
            errorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(errorCorrection)
        self.__errorCorrection = errorCorrection
    @property # getter - - - - - - - - - -
    def gravity(self):
        """gravity indicates direction and strength of local gravity vector for this collection of bodies (units m/sec^2)."""
        return self.__gravity
    @gravity.setter
    def gravity(self, gravity=None):
        if  gravity is None:
            gravity = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(gravity)
        self.__gravity = gravity
    @property # getter - - - - - - - - - -
    def iterations(self):
        """[0,+infinity) iterations controls number of iterations performed over collectioned joints and bodies during each evaluation."""
        return self.__iterations
    @iterations.setter
    def iterations(self, iterations=None):
        if  iterations is None:
            iterations = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(iterations)
        self.__iterations = iterations
    @property # getter - - - - - - - - - -
    def maxCorrectionSpeed(self):
        """[0,+infinity) or -1, maxCorrectionSpeed."""
        return self.__maxCorrectionSpeed
    @maxCorrectionSpeed.setter
    def maxCorrectionSpeed(self, maxCorrectionSpeed=None):
        if  maxCorrectionSpeed is None:
            maxCorrectionSpeed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxCorrectionSpeed)
        self.__maxCorrectionSpeed = maxCorrectionSpeed
    @property # getter - - - - - - - - - -
    def preferAccuracy(self):
        """preferAccuracy provides hint for performance preference: higher accuracy or faster computational speed."""
        return self.__preferAccuracy
    @preferAccuracy.setter
    def preferAccuracy(self, preferAccuracy=None):
        if  preferAccuracy is None:
            preferAccuracy = SFBool.DEFAULT_VALUE
        assertValidSFBool(preferAccuracy)
        self.__preferAccuracy = preferAccuracy
    @property # getter - - - - - - - - - -
    def collider(self):
        """[CollisionCollection] The collider field associates a collision collection with this rigid body collection allowing seamless updates and integration without the need to use the X3D event model."""
        return self.__collider
    @collider.setter
    def collider(self, collider=None):
        if  collider is None:
            collider = SFNode.DEFAULT_VALUE
        assertValidSFNode(collider)
        if not isinstance(collider, object):
            # print(flush=True)
            raise X3DTypeError(str(collider) + ' does not have a valid node type object')
        self.__collider = collider
    @property # getter - - - - - - - - - -
    def bodies(self):
        """[RigidBody] Collection of top-level nodes that comprise a set of bodies evaluated as a single set of interactions."""
        return self.__bodies
    @bodies.setter
    def bodies(self, bodies=None):
        if  bodies is None:
            bodies = MFNode.DEFAULT_VALUE
        assertValidMFNode(bodies)
        self.__bodies = bodies
    @property # getter - - - - - - - - - -
    def joints(self):
        """[X3DRigidJointNode] The joints field is used to register all joints between bodies contained in this collection."""
        return self.__joints
    @joints.setter
    def joints(self, joints=None):
        if  joints is None:
            joints = MFNode.DEFAULT_VALUE
        assertValidMFNode(joints)
        self.__joints = joints
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.bodies) or bool(self.joints) or bool(self.collider) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function RigidBodyCollection.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<RigidBodyCollection'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.autoDisable != False:
            result += " autoDisable='" + SFBool(self.autoDisable).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.constantForceMix != 0.0001:
            result += " constantForceMix='" + SFFloat(self.constantForceMix).XML() + "'"
        if self.contactSurfaceThickness != 0:
            result += " contactSurfaceThickness='" + SFFloat(self.contactSurfaceThickness).XML() + "'"
        if self.disableAngularSpeed != 0:
            result += " disableAngularSpeed='" + SFFloat(self.disableAngularSpeed).XML() + "'"
        if self.disableLinearSpeed != 0:
            result += " disableLinearSpeed='" + SFFloat(self.disableLinearSpeed).XML() + "'"
        if self.disableTime != 0:
            result += " disableTime='" + SFTime(self.disableTime).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.errorCorrection != 0.8:
            result += " errorCorrection='" + SFFloat(self.errorCorrection).XML() + "'"
        if self.gravity != (0, -9.8, 0):
            result += " gravity='" + SFVec3f(self.gravity).XML() + "'"
        if self.iterations != 10:
            result += " iterations='" + SFInt32(self.iterations).XML() + "'"
        if self.maxCorrectionSpeed != -1:
            result += " maxCorrectionSpeed='" + SFFloat(self.maxCorrectionSpeed).XML() + "'"
        if self.preferAccuracy != False:
            result += " preferAccuracy='" + SFBool(self.preferAccuracy).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.collider: # output this SFNode
                result += self.collider.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.bodies: # walk each child node, if any
                for each in self.bodies:
                    result += each.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.joints: # walk each child node, if any
                for each in self.joints:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</RigidBodyCollection>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ScalarChaser(_X3DChaserNode):
    """
    ScalarChaser generates a series of single floating-point values that progressively change from initial value to destination value.
    """
    NAME = 'ScalarChaser'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ScalarChaser'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('duration', 1, FieldType.SFTime, AccessType.initializeOnly, 'X3DChaserNode'),
        ('initialDestination', 0, FieldType.SFFloat, AccessType.initializeOnly, 'ScalarChaser'),
        ('initialValue', 0, FieldType.SFFloat, AccessType.initializeOnly, 'ScalarChaser'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 duration=1,
                 initialDestination=0,
                 initialValue=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ScalarChaser __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.duration = duration
        self.initialDestination = initialDestination
        self.initialValue = initialValue
    @property # getter - - - - - - - - - -
    def duration(self):
        """[0,+infinity) duration is the time interval for filter response in seconds."""
        return self.__duration
    @duration.setter
    def duration(self, duration=None):
        if  duration is None:
            duration = SFTime.DEFAULT_VALUE
        assertValidSFTime(duration)
        assertNonNegative('duration', duration)
        self.__duration = duration
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(initialValue)
        self.__initialValue = initialValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ScalarChaser.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ScalarChaser'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.duration != 1:
            result += " duration='" + SFTime(self.duration).XML() + "'"
        if self.initialDestination != 0:
            result += " initialDestination='" + SFFloat(self.initialDestination).XML() + "'"
        if self.initialValue != 0:
            result += " initialValue='" + SFFloat(self.initialValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ScalarChaser>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ScalarDamper(_X3DDamperNode):
    """
    ScalarDamper generates a series of floating-point values that progressively change from initial value to destination value.
    """
    NAME = 'ScalarDamper'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ScalarDamper'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('initialDestination', 0, FieldType.SFFloat, AccessType.initializeOnly, 'ScalarDamper'),
        ('initialValue', 0, FieldType.SFFloat, AccessType.initializeOnly, 'ScalarDamper'),
        ('order', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DDamperNode'),
        ('tau', 0.3, FieldType.SFTime, AccessType.inputOutput, 'X3DDamperNode'),
        ('tolerance', -1, FieldType.SFFloat, AccessType.inputOutput, 'X3DDamperNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 initialDestination=0,
                 initialValue=0,
                 order=3,
                 tau=0.3,
                 tolerance=-1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ScalarDamper __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.initialDestination = initialDestination
        self.initialValue = initialValue
        self.order = order
        self.tau = tau
        self.tolerance = tolerance
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(initialValue)
        self.__initialValue = initialValue
    @property # getter - - - - - - - - - -
    def order(self):
        """[0,5] order defines the number of internal filters (larger means smoother response, longer delay)."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 0)
        assertLessThanEquals('order', order, 5)
        self.__order = order
    @property # getter - - - - - - - - - -
    def tau(self):
        """[0,+infinity) tau is the exponential-decay time constant for filter response in seconds."""
        return self.__tau
    @tau.setter
    def tau(self, tau=None):
        if  tau is None:
            tau = SFTime.DEFAULT_VALUE
        assertValidSFTime(tau)
        assertNonNegative('tau', tau)
        self.__tau = tau
    @property # getter - - - - - - - - - -
    def tolerance(self):
        """[0,+infinity) or -1."""
        return self.__tolerance
    @tolerance.setter
    def tolerance(self, tolerance=None):
        if  tolerance is None:
            tolerance = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(tolerance)
        self.__tolerance = tolerance
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ScalarDamper.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ScalarDamper'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.initialDestination != 0:
            result += " initialDestination='" + SFFloat(self.initialDestination).XML() + "'"
        if self.initialValue != 0:
            result += " initialValue='" + SFFloat(self.initialValue).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.tau != 0.3:
            result += " tau='" + SFTime(self.tau).XML() + "'"
        if self.tolerance != -1:
            result += " tolerance='" + SFFloat(self.tolerance).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ScalarDamper>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ScalarInterpolator(_X3DInterpolatorNode):
    """
    ScalarInterpolator generates piecewise-linear SFFloat values.
    """
    NAME = 'ScalarInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ScalarInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFFloat, AccessType.inputOutput, 'ScalarInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ScalarInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition values for linear-interpolation function input intervals, listed in non-decreasing order and corresponding to a value in the keyValue array."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for linear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(keyValue)
        self.__keyValue = keyValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ScalarInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ScalarInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFFloat(self.keyValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ScalarInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ScreenFontStyle(_X3DFontStyleNode):
    """
    ScreenFontStyle is an X3DFontStyleNode defines the size, family, justification, and other styles used within a screen layout.
    """
    NAME = 'ScreenFontStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ScreenFontStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('family', ["SERIF"], FieldType.MFString, AccessType.initializeOnly, 'ScreenFontStyle'),
        ('horizontal', True, FieldType.SFBool, AccessType.initializeOnly, 'ScreenFontStyle'),
        ('justify', ["BEGIN"], FieldType.MFString, AccessType.initializeOnly, 'ScreenFontStyle'),
        ('language', '', FieldType.SFString, AccessType.initializeOnly, 'ScreenFontStyle'),
        ('leftToRight', True, FieldType.SFBool, AccessType.initializeOnly, 'ScreenFontStyle'),
        ('pointSize', 12.0, FieldType.SFFloat, AccessType.initializeOnly, 'ScreenFontStyle'),
        ('spacing', 1.0, FieldType.SFFloat, AccessType.initializeOnly, 'ScreenFontStyle'),
        ('style', 'PLAIN', FieldType.SFString, AccessType.initializeOnly, 'ScreenFontStyle'),
        ('topToBottom', True, FieldType.SFBool, AccessType.initializeOnly, 'ScreenFontStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 family=["SERIF"],
                 horizontal=True,
                 justify=["BEGIN"],
                 language='',
                 leftToRight=True,
                 pointSize=12.0,
                 spacing=1.0,
                 style='PLAIN',
                 topToBottom=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ScreenFontStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.family = family
        self.horizontal = horizontal
        self.justify = justify
        self.language = language
        self.leftToRight = leftToRight
        self.pointSize = pointSize
        self.spacing = spacing
        self.style = style
        self.topToBottom = topToBottom
    @property # getter - - - - - - - - - -
    def family(self):
        """Array of quoted font family names in preference order, browsers use the first supported family."""
        return self.__family
    @family.setter
    def family(self, family=None):
        if  family is None:
            family = MFString.DEFAULT_VALUE
        assertValidMFString(family)
        self.__family = family
    @property # getter - - - - - - - - - -
    def horizontal(self):
        """Whether text direction is horizontal (true) or vertical (false)."""
        return self.__horizontal
    @horizontal.setter
    def horizontal(self, horizontal=None):
        if  horizontal is None:
            horizontal = SFBool.DEFAULT_VALUE
        assertValidSFBool(horizontal)
        self.__horizontal = horizontal
    @property # getter - - - - - - - - - -
    def justify(self):
        """The justify field determines alignment of the above text layout relative to the origin of the object coordinate system."""
        return self.__justify
    @justify.setter
    def justify(self, justify=None):
        if  justify is None:
            justify = MFString.DEFAULT_VALUE
        assertValidMFString(justify)
        self.__justify = justify
    @property # getter - - - - - - - - - -
    def language(self):
        """Language codes consist of a primary code and a (possibly empty) series of subcodes."""
        return self.__language
    @language.setter
    def language(self, language=None):
        if  language is None:
            language = SFString.DEFAULT_VALUE
        assertValidSFString(language)
        self.__language = language
    @property # getter - - - - - - - - - -
    def leftToRight(self):
        return self.__leftToRight
    @leftToRight.setter
    def leftToRight(self, leftToRight=None):
        if  leftToRight is None:
            leftToRight = SFBool.DEFAULT_VALUE
        assertValidSFBool(leftToRight)
        self.__leftToRight = leftToRight
    @property # getter - - - - - - - - - -
    def pointSize(self):
        """(0,+infinity) pointSize field specifies the size of text in points."""
        return self.__pointSize
    @pointSize.setter
    def pointSize(self, pointSize=None):
        if  pointSize is None:
            pointSize = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(pointSize)
        assertPositive('pointSize', pointSize)
        self.__pointSize = pointSize
    @property # getter - - - - - - - - - -
    def spacing(self):
        """[0,+infinity) Adjustment factor for line spacing between adjacent lines of text."""
        return self.__spacing
    @spacing.setter
    def spacing(self, spacing=None):
        if  spacing is None:
            spacing = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(spacing)
        assertNonNegative('spacing', spacing)
        self.__spacing = spacing
    @property # getter - - - - - - - - - -
    def style(self):
        """Pick one of four values for text style."""
        return self.__style
    @style.setter
    def style(self, style=None):
        if  style is None:
            style = SFString.DEFAULT_VALUE
        assertValidSFString(style)
        self.__style = style
    @property # getter - - - - - - - - - -
    def topToBottom(self):
        """Whether text direction is top-to-bottom (true) or bottom-to-top (false)."""
        return self.__topToBottom
    @topToBottom.setter
    def topToBottom(self, topToBottom=None):
        if  topToBottom is None:
            topToBottom = SFBool.DEFAULT_VALUE
        assertValidSFBool(topToBottom)
        self.__topToBottom = topToBottom
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ScreenFontStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ScreenFontStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.family != ["SERIF"]:
            result += " family='" + MFString(self.family).XML() + "'"
        if self.horizontal != True:
            result += " horizontal='" + SFBool(self.horizontal).XML() + "'"
        if self.justify != ["BEGIN"]:
            result += " justify='" + MFString(self.justify).XML() + "'"
        if self.language:
            result += " language='" + self.language + "'"
        if self.leftToRight != True:
            result += " leftToRight='" + SFBool(self.leftToRight).XML() + "'"
        if self.pointSize != 12.0:
            result += " pointSize='" + SFFloat(self.pointSize).XML() + "'"
        if self.spacing != 1.0:
            result += " spacing='" + SFFloat(self.spacing).XML() + "'"
        if self.style != 'PLAIN':
            result += " style='" + self.style + "'"
        if self.topToBottom != True:
            result += " topToBottom='" + SFBool(self.topToBottom).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ScreenFontStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ScreenGroup(_X3DGroupingNode):
    """
    ScreenGroup is a Grouping node that can contain most nodes.
    """
    NAME = 'ScreenGroup'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ScreenGroup'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ScreenGroup __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ScreenGroup.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ScreenGroup'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ScreenGroup>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Script(_X3DScriptNode):
    """
    Script contains author-programmed event behaviors for a scene.
    """
    NAME = 'Script'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Script'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('directOutput', False, FieldType.SFBool, AccessType.initializeOnly, 'Script'),
        ('mustEvaluate', False, FieldType.SFBool, AccessType.initializeOnly, 'Script'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DScriptNode'),
        ('field', list(), FieldType.MFNode, AccessType.inputOutput, 'Script'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 directOutput=False,
                 mustEvaluate=False,
                 url=list(),
                 field=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Script __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.directOutput = directOutput
        self.mustEvaluate = mustEvaluate
        self.url = url
        self.field = field
    @property # getter - - - - - - - - - -
    def directOutput(self):
        """Set directOutput true if Script has field reference(s) of type SFNode/MFNode, and also uses direct access to modify attributes of a referenced node in the Scene."""
        return self.__directOutput
    @directOutput.setter
    def directOutput(self, directOutput=None):
        if  directOutput is None:
            directOutput = SFBool.DEFAULT_VALUE
        assertValidSFBool(directOutput)
        self.__directOutput = directOutput
    @property # getter - - - - - - - - - -
    def mustEvaluate(self):
        """If mustEvaluate false, then the X3D player may delay sending input events to Script until output events are needed."""
        return self.__mustEvaluate
    @mustEvaluate.setter
    def mustEvaluate(self, mustEvaluate=None):
        if  mustEvaluate is None:
            mustEvaluate = SFBool.DEFAULT_VALUE
        assertValidSFBool(mustEvaluate)
        self.__mustEvaluate = mustEvaluate
    @property # getter - - - - - - - - - -
    def url(self):
        """List of address links for runnable script files."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def field(self):
        """Include a field statement for each field declaration in this Script node."""
        return self.__field
    @field.setter
    def field(self, field=None):
        if  field is None:
            field = MFNode.DEFAULT_VALUE
        # TODO type-aware checks for field
        if field: # walk each child node, if any
            for each in field:
                assertValidFieldInitializationValue(each.name, each.type, each.value, parent='Script')
        self.__field = field
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.field) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Script.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Script'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.directOutput != False:
            result += " directOutput='" + SFBool(self.directOutput).XML() + "'"
        if self.mustEvaluate != False:
            result += " mustEvaluate='" + SFBool(self.mustEvaluate).XML() + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.field: # walk each child node, if any
                for each in self.field:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Script>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SegmentedVolumeData(_X3DVolumeDataNode):
    """
    SegmentedVolumeData displays a segmented voxel dataset with different RenderStyle nodes.
    """
    NAME = 'SegmentedVolumeData'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SegmentedVolumeData'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DVolumeDataNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DVolumeDataNode'),
        ('dimensions', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'X3DVolumeDataNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeDataNode'),
        ('segmentEnabled', list(), FieldType.MFBool, AccessType.inputOutput, 'SegmentedVolumeData'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeDataNode'),
        ('segmentIdentifiers', None, FieldType.SFNode, AccessType.inputOutput, 'SegmentedVolumeData'),
        ('voxels', None, FieldType.SFNode, AccessType.inputOutput, 'SegmentedVolumeData'),
        ('renderStyle', list(), FieldType.MFNode, AccessType.inputOutput, 'SegmentedVolumeData'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 dimensions=(1, 1, 1),
                 displayBBox=False,
                 segmentEnabled=list(),
                 visible=True,
                 segmentIdentifiers=None,
                 voxels=None,
                 renderStyle=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SegmentedVolumeData __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.dimensions = dimensions
        self.displayBBox = displayBBox
        self.segmentEnabled = segmentEnabled
        self.visible = visible
        self.segmentIdentifiers = segmentIdentifiers
        self.voxels = voxels
        self.renderStyle = renderStyle
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def dimensions(self):
        """Actual-size X-Y-Z dimensions of volume data in local coordinate system."""
        return self.__dimensions
    @dimensions.setter
    def dimensions(self, dimensions=None):
        if  dimensions is None:
            dimensions = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(dimensions)
        assertPositive('dimensions', dimensions)
        self.__dimensions = dimensions
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def segmentEnabled(self):
        return self.__segmentEnabled
    @segmentEnabled.setter
    def segmentEnabled(self, segmentEnabled=None):
        if  segmentEnabled is None:
            segmentEnabled = MFBool.DEFAULT_VALUE
        assertValidMFBool(segmentEnabled)
        self.__segmentEnabled = segmentEnabled
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def segmentIdentifiers(self):
        """[X3DTexture3DNode] Single contained X3DTexture3DNode (ComposedTexture3D, ImageTexture3D, PixelTexture3D) holds component texture that provides corresponding segment identifier."""
        return self.__segmentIdentifiers
    @segmentIdentifiers.setter
    def segmentIdentifiers(self, segmentIdentifiers=None):
        if  segmentIdentifiers is None:
            segmentIdentifiers = SFNode.DEFAULT_VALUE
        assertValidSFNode(segmentIdentifiers)
        if not isinstance(segmentIdentifiers, object):
            # print(flush=True)
            raise X3DTypeError(str(segmentIdentifiers) + ' does not have a valid node type object')
        self.__segmentIdentifiers = segmentIdentifiers
    @property # getter - - - - - - - - - -
    def voxels(self):
        """[X3DTexture3DNode] Single contained X3DTexture3DNode (ComposedTexture3D, ImageTexture3D, PixelTexture3D) that provides raw voxel information utilized by corresponding rendering styles."""
        return self.__voxels
    @voxels.setter
    def voxels(self, voxels=None):
        if  voxels is None:
            voxels = SFNode.DEFAULT_VALUE
        assertValidSFNode(voxels)
        if not isinstance(voxels, object):
            # print(flush=True)
            raise X3DTypeError(str(voxels) + ' does not have a valid node type object')
        self.__voxels = voxels
    @property # getter - - - - - - - - - -
    def renderStyle(self):
        """[X3DVolumeRenderStyleNode] Multiple contained X3DVolumeRenderStyleNode nodes corresponding to each isosurface that define specific rendering technique for this volumetric object."""
        return self.__renderStyle
    @renderStyle.setter
    def renderStyle(self, renderStyle=None):
        if  renderStyle is None:
            renderStyle = MFNode.DEFAULT_VALUE
        assertValidMFNode(renderStyle)
        self.__renderStyle = renderStyle
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.renderStyle) or bool(self.IS) or bool(self.metadata) or bool(self.segmentIdentifiers) or bool(self.voxels)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SegmentedVolumeData.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SegmentedVolumeData'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.dimensions != (1, 1, 1):
            result += " dimensions='" + SFVec3f(self.dimensions).XML() + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.segmentEnabled != list():
            result += " segmentEnabled='" + MFBool(self.segmentEnabled).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.segmentIdentifiers: # output this SFNode
                result += self.segmentIdentifiers.XML(indentLevel=indentLevel+1)
            if self.voxels: # output this SFNode
                result += self.voxels.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.renderStyle: # walk each child node, if any
                for each in self.renderStyle:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</SegmentedVolumeData>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ShadedVolumeStyle(_X3DComposableVolumeRenderStyleNode):
    """
    All fields fully supported except shadows supported with at least Phong shading at level 3. All fields fully supported with at least Phong shading and Henyey-Greenstein phase function, shadows fully supported at level 4.
    """
    NAME = 'ShadedVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ShadedVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('lighting', False, FieldType.SFBool, AccessType.inputOutput, 'ShadedVolumeStyle'),
        ('phaseFunction', 'Henyey-Greenstein', FieldType.SFString, AccessType.initializeOnly, 'ShadedVolumeStyle'),
        ('shadows', False, FieldType.SFBool, AccessType.inputOutput, 'ShadedVolumeStyle'),
        ('material', None, FieldType.SFNode, AccessType.inputOutput, 'ShadedVolumeStyle'),
        ('surfaceNormals', None, FieldType.SFNode, AccessType.inputOutput, 'ShadedVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 lighting=False,
                 phaseFunction='Henyey-Greenstein',
                 shadows=False,
                 material=None,
                 surfaceNormals=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ShadedVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.lighting = lighting
        self.phaseFunction = phaseFunction
        self.shadows = shadows
        self.material = material
        self.surfaceNormals = surfaceNormals
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def lighting(self):
        """Whether rendering calculates and applies shading effects to visual output."""
        return self.__lighting
    @lighting.setter
    def lighting(self, lighting=None):
        if  lighting is None:
            lighting = SFBool.DEFAULT_VALUE
        assertValidSFBool(lighting)
        self.__lighting = lighting
    @property # getter - - - - - - - - - -
    def phaseFunction(self):
        """define scattering model for implementations using global illumination (NONE or Henyey-Greenstein phase function)."""
        return self.__phaseFunction
    @phaseFunction.setter
    def phaseFunction(self, phaseFunction=None):
        if  phaseFunction is None:
            phaseFunction = SFString.DEFAULT_VALUE
        assertValidSFString(phaseFunction)
        self.__phaseFunction = phaseFunction
    @property # getter - - - - - - - - - -
    def shadows(self):
        """Whether rendering calculates and applies shadows to visual output (using global illumination model)."""
        return self.__shadows
    @shadows.setter
    def shadows(self, shadows=None):
        if  shadows is None:
            shadows = SFBool.DEFAULT_VALUE
        assertValidSFBool(shadows)
        self.__shadows = shadows
    @property # getter - - - - - - - - - -
    def material(self):
        return self.__material
    @material.setter
    def material(self, material=None):
        if  material is None:
            material = SFNode.DEFAULT_VALUE
        assertValidSFNode(material)
        if not isinstance(material, object):
            # print(flush=True)
            raise X3DTypeError(str(material) + ' does not have a valid node type object')
        self.__material = material
    @property # getter - - - - - - - - - -
    def surfaceNormals(self):
        return self.__surfaceNormals
    @surfaceNormals.setter
    def surfaceNormals(self, surfaceNormals=None):
        if  surfaceNormals is None:
            surfaceNormals = SFNode.DEFAULT_VALUE
        assertValidSFNode(surfaceNormals)
        if not isinstance(surfaceNormals, object):
            # print(flush=True)
            raise X3DTypeError(str(surfaceNormals) + ' does not have a valid node type object')
        self.__surfaceNormals = surfaceNormals
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.material) or bool(self.metadata) or bool(self.surfaceNormals)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ShadedVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ShadedVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.lighting != False:
            result += " lighting='" + SFBool(self.lighting).XML() + "'"
        if self.phaseFunction != 'Henyey-Greenstein':
            result += " phaseFunction='" + self.phaseFunction + "'"
        if self.shadows != False:
            result += " shadows='" + SFBool(self.shadows).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.material: # output this SFNode
                result += self.material.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.surfaceNormals: # output this SFNode
                result += self.surfaceNormals.XML(indentLevel=indentLevel+1)
            result += indent + '</ShadedVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ShaderPart(_X3DNode): # , _X3DUrlObject # TODO fix additional inheritance method resolution order (MRO)
    """
    ShaderPart can contain a CDATA section of plain-text source code.
    """
    NAME = 'ShaderPart'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ShaderPart'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('type', 'VERTEX', FieldType.SFString, AccessType.inputOutput, 'ShaderPart'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 type='VERTEX',
                 url=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ShaderPart __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.type = type
        self.url = url
    @property # getter - - - - - - - - - -
    def type(self):
        """type indicates whether this ShaderProgram is a vertex or fragment (pixel) shader."""
        return self.__type
    @type.setter
    def type(self, type=None):
        if  type is None:
            type = SFString.DEFAULT_VALUE
        assertValidSFString(type)
        self.__type = type
    @property # getter - - - - - - - - - -
    def url(self):
        """Location and filename of shader."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ShaderPart.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ShaderPart'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.type != 'VERTEX':
            result += " type='" + self.type + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</ShaderPart>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ShaderProgram(_X3DNode): # , _X3DUrlObject, _X3DProgrammableShaderObject # TODO fix additional inheritance method resolution order (MRO)
    """
    ShaderProgram can contain field declarations and a CDATA section of plain-text source code.
    """
    NAME = 'ShaderProgram'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ShaderProgram'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('type', 'VERTEX', FieldType.SFString, AccessType.inputOutput, 'ShaderProgram'),
        ('url', list(), FieldType.MFString, AccessType.inputOutput, 'X3DUrlObject'),
        ('field', list(), FieldType.MFNode, AccessType.inputOutput, 'ShaderProgram'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 type='VERTEX',
                 url=list(),
                 field=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ShaderProgram __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.type = type
        self.url = url
        self.field = field
    @property # getter - - - - - - - - - -
    def type(self):
        """type indicates whether this ShaderProgram is a vertex or fragment (pixel) shader."""
        return self.__type
    @type.setter
    def type(self, type=None):
        if  type is None:
            type = SFString.DEFAULT_VALUE
        assertValidSFString(type)
        self.__type = type
    @property # getter - - - - - - - - - -
    def url(self):
        """Location and filename of shader."""
        return self.__url
    @url.setter
    def url(self, url=None):
        if  url is None:
            url = MFString.DEFAULT_VALUE
        assertValidMFString(url)
        self.__url = url
    @property # getter - - - - - - - - - -
    def field(self):
        """Include a field statement for each field declaration in the ShaderProgram node."""
        return self.__field
    @field.setter
    def field(self, field=None):
        if  field is None:
            field = MFNode.DEFAULT_VALUE
        # TODO type-aware checks for field
        if field: # walk each child node, if any
            for each in field:
                assertValidFieldInitializationValue(each.name, each.type, each.value, parent='ShaderProgram')
        self.__field = field
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.field) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ShaderProgram.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ShaderProgram'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.type != 'VERTEX':
            result += " type='" + self.type + "'"
        if self.url != list():
            result += " url='" + MFString(self.url).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.field: # walk each child node, if any
                for each in self.field:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ShaderProgram>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Shape(_X3DShapeNode):
    """
    Shape can appear under any grouping node.
    """
    NAME = 'Shape'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Shape'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DShapeNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DShapeNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DShapeNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DShapeNode'),
        ('appearance', None, FieldType.SFNode, AccessType.inputOutput, 'X3DShapeNode'),
        ('geometry', None, FieldType.SFNode, AccessType.inputOutput, 'X3DShapeNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 visible=True,
                 appearance=None,
                 geometry=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Shape __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.visible = visible
        self.appearance = appearance
        self.geometry = geometry
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def appearance(self):
        """[X3DAppearanceNode] Single contained Appearance node that specifies visual attributes (such as material, texture, fillProperties and lineProperties) applied to corresponding geometry."""
        return self.__appearance
    @appearance.setter
    def appearance(self, appearance=None):
        if  appearance is None:
            appearance = SFNode.DEFAULT_VALUE
        assertValidSFNode(appearance)
        if not isinstance(appearance, object):
            # print(flush=True)
            raise X3DTypeError(str(appearance) + ' does not have a valid node type object')
        self.__appearance = appearance
    @property # getter - - - - - - - - - -
    def geometry(self):
        """[X3DGeometryNode] Single contained geometry node that is rendered according to corresponding appearance."""
        return self.__geometry
    @geometry.setter
    def geometry(self, geometry=None):
        if  geometry is None:
            geometry = SFNode.DEFAULT_VALUE
        assertValidSFNode(geometry)
        if not isinstance(geometry, object):
            # print(flush=True)
            raise X3DTypeError(str(geometry) + ' does not have a valid node type object')
        self.__geometry = geometry
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.appearance) or bool(self.geometry) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Shape.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Shape'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.appearance: # output this SFNode
                result += self.appearance.XML(indentLevel=indentLevel+1)
            if self.geometry: # output this SFNode
                result += self.geometry.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Shape>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SignalPdu(_X3DNetworkSensorNode, _X3DBoundedObject):
    """
    SignalPdu is a networked Protocol Data Unit (PDU) information node that communicates the transmission of voice, audio or other data modeled in a simulation.
    """
    NAME = 'SignalPdu'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SignalPdu'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('address', 'localhost', FieldType.SFString, AccessType.inputOutput, 'SignalPdu'),
        ('applicationID', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('data', list(), FieldType.MFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('dataLength', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('encodingScheme', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('entityID', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('geoCoords', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'SignalPdu'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'SignalPdu'),
        ('multicastRelayHost', '', FieldType.SFString, AccessType.inputOutput, 'SignalPdu'),
        ('multicastRelayPort', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('networkMode', 'standAlone', FieldType.SFString, AccessType.inputOutput, 'SignalPdu'),
        ('port', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('radioID', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('readInterval', 0.1, FieldType.SFTime, AccessType.inputOutput, 'SignalPdu'),
        ('rtpHeaderExpected', False, FieldType.SFBool, AccessType.initializeOnly, 'SignalPdu'),
        ('sampleRate', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('samples', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('siteID', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('tdlType', 0, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('whichGeometry', 1, FieldType.SFInt32, AccessType.inputOutput, 'SignalPdu'),
        ('writeInterval', 1.0, FieldType.SFTime, AccessType.inputOutput, 'SignalPdu'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 address='localhost',
                 applicationID=0,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 data=list(),
                 dataLength=0,
                 displayBBox=False,
                 enabled=True,
                 encodingScheme=0,
                 entityID=0,
                 geoCoords=(0, 0, 0),
                 geoSystem=["GD", "WE"],
                 multicastRelayHost='',
                 multicastRelayPort=0,
                 networkMode='standAlone',
                 port=0,
                 radioID=0,
                 readInterval=0.1,
                 rtpHeaderExpected=False,
                 sampleRate=0,
                 samples=0,
                 siteID=0,
                 tdlType=0,
                 visible=True,
                 whichGeometry=1,
                 writeInterval=1.0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SignalPdu __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.address = address
        self.applicationID = applicationID
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.data = data
        self.dataLength = dataLength
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.encodingScheme = encodingScheme
        self.entityID = entityID
        self.geoCoords = geoCoords
        self.geoSystem = geoSystem
        self.multicastRelayHost = multicastRelayHost
        self.multicastRelayPort = multicastRelayPort
        self.networkMode = networkMode
        self.port = port
        self.radioID = radioID
        self.readInterval = readInterval
        self.rtpHeaderExpected = rtpHeaderExpected
        self.sampleRate = sampleRate
        self.samples = samples
        self.siteID = siteID
        self.tdlType = tdlType
        self.visible = visible
        self.whichGeometry = whichGeometry
        self.writeInterval = writeInterval
    @property # getter - - - - - - - - - -
    def address(self):
        """Multicast network address, or else "localhost" example: 224."""
        return self.__address
    @address.setter
    def address(self, address=None):
        if  address is None:
            address = SFString.DEFAULT_VALUE
        assertValidSFString(address)
        self.__address = address
    @property # getter - - - - - - - - - -
    def applicationID(self):
        """Each simulation application that can respond to simulation management PDUs needs to have a unique applicationID."""
        return self.__applicationID
    @applicationID.setter
    def applicationID(self, applicationID=None):
        if  applicationID is None:
            applicationID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(applicationID)
        self.__applicationID = applicationID
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def data(self):
        """Holds audio or digital data conveyed by the radio transmission."""
        return self.__data
    @data.setter
    def data(self, data=None):
        if  data is None:
            data = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(data)
        self.__data = data
    @property # getter - - - - - - - - - -
    def dataLength(self):
        """number of bits of digital voice audio or digital data being sent in the Signal PDU."""
        return self.__dataLength
    @dataLength.setter
    def dataLength(self, dataLength=None):
        if  dataLength is None:
            dataLength = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(dataLength)
        self.__dataLength = dataLength
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables the sensor node."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def encodingScheme(self):
        """designates both Encoding Class and Encoding Type."""
        return self.__encodingScheme
    @encodingScheme.setter
    def encodingScheme(self, encodingScheme=None):
        if  encodingScheme is None:
            encodingScheme = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(encodingScheme)
        self.__encodingScheme = encodingScheme
    @property # getter - - - - - - - - - -
    def entityID(self):
        """EntityID unique ID for entity within that application."""
        return self.__entityID
    @entityID.setter
    def entityID(self, entityID=None):
        if  entityID is None:
            entityID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entityID)
        self.__entityID = entityID
    @property # getter - - - - - - - - - -
    def geoCoords(self):
        """Geographic location (specified in current geoSystem coordinates) for children geometry (specified in relative coordinate system, in meters)."""
        return self.__geoCoords
    @geoCoords.setter
    def geoCoords(self, geoCoords=None):
        if  geoCoords is None:
            geoCoords = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(geoCoords)
        self.__geoCoords = geoCoords
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def multicastRelayHost(self):
        """Fallback server address if multicast not available locally."""
        return self.__multicastRelayHost
    @multicastRelayHost.setter
    def multicastRelayHost(self, multicastRelayHost=None):
        if  multicastRelayHost is None:
            multicastRelayHost = SFString.DEFAULT_VALUE
        assertValidSFString(multicastRelayHost)
        self.__multicastRelayHost = multicastRelayHost
    @property # getter - - - - - - - - - -
    def multicastRelayPort(self):
        """Fallback server port if multicast not available locally."""
        return self.__multicastRelayPort
    @multicastRelayPort.setter
    def multicastRelayPort(self, multicastRelayPort=None):
        if  multicastRelayPort is None:
            multicastRelayPort = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(multicastRelayPort)
        self.__multicastRelayPort = multicastRelayPort
    @property # getter - - - - - - - - - -
    def networkMode(self):
        """Whether this entity is ignoring the network, sending DIS packets to the network, or receiving DIS packets from the network."""
        return self.__networkMode
    @networkMode.setter
    def networkMode(self, networkMode=None):
        if  networkMode is None:
            networkMode = SFString.DEFAULT_VALUE
        assertValidSFString(networkMode)
        self.__networkMode = networkMode
    @property # getter - - - - - - - - - -
    def port(self):
        """Multicast network port, for example: 3000."""
        return self.__port
    @port.setter
    def port(self, port=None):
        if  port is None:
            port = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(port)
        self.__port = port
    @property # getter - - - - - - - - - -
    def radioID(self):
        """Identifies a particular radio within a given entity."""
        return self.__radioID
    @radioID.setter
    def radioID(self, radioID=None):
        if  radioID is None:
            radioID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(radioID)
        self.__radioID = radioID
    @property # getter - - - - - - - - - -
    def readInterval(self):
        """[0,+infinity) Seconds between read updates, 0 means no reading."""
        return self.__readInterval
    @readInterval.setter
    def readInterval(self, readInterval=None):
        if  readInterval is None:
            readInterval = SFTime.DEFAULT_VALUE
        assertValidSFTime(readInterval)
        assertNonNegative('readInterval', readInterval)
        self.__readInterval = readInterval
    @property # getter - - - - - - - - - -
    def rtpHeaderExpected(self):
        """Whether RTP headers are prepended to DIS PDUs."""
        return self.__rtpHeaderExpected
    @rtpHeaderExpected.setter
    def rtpHeaderExpected(self, rtpHeaderExpected=None):
        if  rtpHeaderExpected is None:
            rtpHeaderExpected = SFBool.DEFAULT_VALUE
        assertValidSFBool(rtpHeaderExpected)
        self.__rtpHeaderExpected = rtpHeaderExpected
    @property # getter - - - - - - - - - -
    def sampleRate(self):
        """sampleRate gives either (1) sample rate in samples per second if Encoding Class is encoded audio, or (2) data rate in bits per second for data transmissions."""
        return self.__sampleRate
    @sampleRate.setter
    def sampleRate(self, sampleRate=None):
        if  sampleRate is None:
            sampleRate = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(sampleRate)
        self.__sampleRate = sampleRate
    @property # getter - - - - - - - - - -
    def samples(self):
        """Number of samples in the PDU if the Encoding Class is encoded voice, otherwise the field is set to zero."""
        return self.__samples
    @samples.setter
    def samples(self, samples=None):
        if  samples is None:
            samples = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(samples)
        self.__samples = samples
    @property # getter - - - - - - - - - -
    def siteID(self):
        """Simulation/exercise siteID of the participating LAN or organization."""
        return self.__siteID
    @siteID.setter
    def siteID(self, siteID=None):
        if  siteID is None:
            siteID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(siteID)
        self.__siteID = siteID
    @property # getter - - - - - - - - - -
    def tdlType(self):
        """Tactical Data Link (TDL) type as an enumerated value when the Encoding Class is voice, raw binary, application-specific, or database index representation of a TDL message."""
        return self.__tdlType
    @tdlType.setter
    def tdlType(self, tdlType=None):
        if  tdlType is None:
            tdlType = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(tdlType)
        self.__tdlType = tdlType
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def whichGeometry(self):
        """Select geometry to render: -1 for no geometry, 0 for text trace, 1 for default geometry, (optional) higher values to render different states."""
        return self.__whichGeometry
    @whichGeometry.setter
    def whichGeometry(self, whichGeometry=None):
        if  whichGeometry is None:
            whichGeometry = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(whichGeometry)
        self.__whichGeometry = whichGeometry
    @property # getter - - - - - - - - - -
    def writeInterval(self):
        """[0,+infinity) Seconds between write updates, 0 means no writing (sending)."""
        return self.__writeInterval
    @writeInterval.setter
    def writeInterval(self, writeInterval=None):
        if  writeInterval is None:
            writeInterval = SFTime.DEFAULT_VALUE
        assertValidSFTime(writeInterval)
        assertNonNegative('writeInterval', writeInterval)
        self.__writeInterval = writeInterval
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SignalPdu.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SignalPdu'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.address != 'localhost':
            result += " address='" + self.address + "'"
        if self.applicationID != 0:
            result += " applicationID='" + SFInt32(self.applicationID).XML() + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.data != list():
            result += " data='" + MFInt32(self.data).XML() + "'"
        if self.dataLength != 0:
            result += " dataLength='" + SFInt32(self.dataLength).XML() + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.encodingScheme != 0:
            result += " encodingScheme='" + SFInt32(self.encodingScheme).XML() + "'"
        if self.entityID != 0:
            result += " entityID='" + SFInt32(self.entityID).XML() + "'"
        if self.geoCoords != (0, 0, 0):
            result += " geoCoords='" + SFVec3d(self.geoCoords).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.multicastRelayHost:
            result += " multicastRelayHost='" + self.multicastRelayHost + "'"
        if self.multicastRelayPort != 0:
            result += " multicastRelayPort='" + SFInt32(self.multicastRelayPort).XML() + "'"
        if self.networkMode != 'standAlone':
            result += " networkMode='" + self.networkMode + "'"
        if self.port != 0:
            result += " port='" + SFInt32(self.port).XML() + "'"
        if self.radioID != 0:
            result += " radioID='" + SFInt32(self.radioID).XML() + "'"
        if self.readInterval != 0.1:
            result += " readInterval='" + SFTime(self.readInterval).XML() + "'"
        if self.rtpHeaderExpected != False:
            result += " rtpHeaderExpected='" + SFBool(self.rtpHeaderExpected).XML() + "'"
        if self.sampleRate != 0:
            result += " sampleRate='" + SFInt32(self.sampleRate).XML() + "'"
        if self.samples != 0:
            result += " samples='" + SFInt32(self.samples).XML() + "'"
        if self.siteID != 0:
            result += " siteID='" + SFInt32(self.siteID).XML() + "'"
        if self.tdlType != 0:
            result += " tdlType='" + SFInt32(self.tdlType).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if self.whichGeometry != 1:
            result += " whichGeometry='" + SFInt32(self.whichGeometry).XML() + "'"
        if self.writeInterval != 1.0:
            result += " writeInterval='" + SFTime(self.writeInterval).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</SignalPdu>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SilhouetteEnhancementVolumeStyle(_X3DComposableVolumeRenderStyleNode):
    """
    SilhouetteEnhancementVolumeStyle specifies that volumetric data is rendered with silhouette enhancement.
    """
    NAME = 'SilhouetteEnhancementVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SilhouetteEnhancementVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('silhouetteBoundaryOpacity', 0, FieldType.SFFloat, AccessType.inputOutput, 'SilhouetteEnhancementVolumeStyle'),
        ('silhouetteRetainedOpacity', 1, FieldType.SFFloat, AccessType.inputOutput, 'SilhouetteEnhancementVolumeStyle'),
        ('silhouetteSharpness', 0.5, FieldType.SFFloat, AccessType.inputOutput, 'SilhouetteEnhancementVolumeStyle'),
        ('surfaceNormals', None, FieldType.SFNode, AccessType.inputOutput, 'SilhouetteEnhancementVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 silhouetteBoundaryOpacity=0,
                 silhouetteRetainedOpacity=1,
                 silhouetteSharpness=0.5,
                 surfaceNormals=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SilhouetteEnhancementVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.silhouetteBoundaryOpacity = silhouetteBoundaryOpacity
        self.silhouetteRetainedOpacity = silhouetteRetainedOpacity
        self.silhouetteSharpness = silhouetteSharpness
        self.surfaceNormals = surfaceNormals
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def silhouetteBoundaryOpacity(self):
        """[0,1] amount of the silhouette enhancement to use."""
        return self.__silhouetteBoundaryOpacity
    @silhouetteBoundaryOpacity.setter
    def silhouetteBoundaryOpacity(self, silhouetteBoundaryOpacity=None):
        if  silhouetteBoundaryOpacity is None:
            silhouetteBoundaryOpacity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(silhouetteBoundaryOpacity)
        assertZeroToOne('silhouetteBoundaryOpacity', silhouetteBoundaryOpacity)
        self.__silhouetteBoundaryOpacity = silhouetteBoundaryOpacity
    @property # getter - - - - - - - - - -
    def silhouetteRetainedOpacity(self):
        """[0,1] scaling of non-silhouette regions."""
        return self.__silhouetteRetainedOpacity
    @silhouetteRetainedOpacity.setter
    def silhouetteRetainedOpacity(self, silhouetteRetainedOpacity=None):
        if  silhouetteRetainedOpacity is None:
            silhouetteRetainedOpacity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(silhouetteRetainedOpacity)
        assertZeroToOne('silhouetteRetainedOpacity', silhouetteRetainedOpacity)
        self.__silhouetteRetainedOpacity = silhouetteRetainedOpacity
    @property # getter - - - - - - - - - -
    def silhouetteSharpness(self):
        """[0,+infinity) power function to control sharpness of the silhouette."""
        return self.__silhouetteSharpness
    @silhouetteSharpness.setter
    def silhouetteSharpness(self, silhouetteSharpness=None):
        if  silhouetteSharpness is None:
            silhouetteSharpness = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(silhouetteSharpness)
        assertNonNegative('silhouetteSharpness', silhouetteSharpness)
        self.__silhouetteSharpness = silhouetteSharpness
    @property # getter - - - - - - - - - -
    def surfaceNormals(self):
        return self.__surfaceNormals
    @surfaceNormals.setter
    def surfaceNormals(self, surfaceNormals=None):
        if  surfaceNormals is None:
            surfaceNormals = SFNode.DEFAULT_VALUE
        assertValidSFNode(surfaceNormals)
        if not isinstance(surfaceNormals, object):
            # print(flush=True)
            raise X3DTypeError(str(surfaceNormals) + ' does not have a valid node type object')
        self.__surfaceNormals = surfaceNormals
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.surfaceNormals)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SilhouetteEnhancementVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SilhouetteEnhancementVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.silhouetteBoundaryOpacity != 0:
            result += " silhouetteBoundaryOpacity='" + SFFloat(self.silhouetteBoundaryOpacity).XML() + "'"
        if self.silhouetteRetainedOpacity != 1:
            result += " silhouetteRetainedOpacity='" + SFFloat(self.silhouetteRetainedOpacity).XML() + "'"
        if self.silhouetteSharpness != 0.5:
            result += " silhouetteSharpness='" + SFFloat(self.silhouetteSharpness).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.surfaceNormals: # output this SFNode
                result += self.surfaceNormals.XML(indentLevel=indentLevel+1)
            result += indent + '</SilhouetteEnhancementVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SingleAxisHingeJoint(_X3DRigidJointNode):
    """
    SingleAxisHingeJoint has single axis about which to rotate, similar to a traditional door hinge. Contains two RigidBody nodes (containerField values body1, body2).
    """
    NAME = 'SingleAxisHingeJoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SingleAxisHingeJoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('anchorPoint', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'SingleAxisHingeJoint'),
        ('axis', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'SingleAxisHingeJoint'),
        ('forceOutput', ["NONE"], FieldType.MFString, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('maxAngle', 3.141592653, FieldType.SFFloat, AccessType.inputOutput, 'SingleAxisHingeJoint'),
        ('minAngle', -3.141592653, FieldType.SFFloat, AccessType.inputOutput, 'SingleAxisHingeJoint'),
        ('stopBounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'SingleAxisHingeJoint'),
        ('stopErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'SingleAxisHingeJoint'),
        ('body1', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('body2', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 anchorPoint=(0, 0, 0),
                 axis=(0, 0, 0),
                 forceOutput=["NONE"],
                 maxAngle=3.141592653,
                 minAngle=-3.141592653,
                 stopBounce=0,
                 stopErrorCorrection=0.8,
                 body1=None,
                 body2=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SingleAxisHingeJoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.anchorPoint = anchorPoint
        self.axis = axis
        self.forceOutput = forceOutput
        self.maxAngle = maxAngle
        self.minAngle = minAngle
        self.stopBounce = stopBounce
        self.stopErrorCorrection = stopErrorCorrection
        self.body1 = body1
        self.body2 = body2
    @property # getter - - - - - - - - - -
    def anchorPoint(self):
        """anchorPoint is joint center, specified in world coordinates."""
        return self.__anchorPoint
    @anchorPoint.setter
    def anchorPoint(self, anchorPoint=None):
        if  anchorPoint is None:
            anchorPoint = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(anchorPoint)
        self.__anchorPoint = anchorPoint
    @property # getter - - - - - - - - - -
    def axis(self):
        """axis defines vector of joint connection between body1 and body2."""
        return self.__axis
    @axis.setter
    def axis(self, axis=None):
        if  axis is None:
            axis = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(axis)
        self.__axis = axis
    @property # getter - - - - - - - - - -
    def forceOutput(self):
        """forceOutput controls which output fields are generated for the next frame."""
        return self.__forceOutput
    @forceOutput.setter
    def forceOutput(self, forceOutput=None):
        if  forceOutput is None:
            forceOutput = MFString.DEFAULT_VALUE
        assertValidMFString(forceOutput)
        self.__forceOutput = forceOutput
    @property # getter - - - - - - - - - -
    def maxAngle(self):
        """[-pi,pi] maxAngle is maximum rotation angle for hinge."""
        return self.__maxAngle
    @maxAngle.setter
    def maxAngle(self, maxAngle=None):
        if  maxAngle is None:
            maxAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxAngle)
        self.__maxAngle = maxAngle
    @property # getter - - - - - - - - - -
    def minAngle(self):
        """[-pi,pi] minAngle is minimum rotation angle for hinge."""
        return self.__minAngle
    @minAngle.setter
    def minAngle(self, minAngle=None):
        if  minAngle is None:
            minAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(minAngle)
        self.__minAngle = minAngle
    @property # getter - - - - - - - - - -
    def stopBounce(self):
        """[0,1] stopBounce is velocity factor for bounce back once stop point is reached."""
        return self.__stopBounce
    @stopBounce.setter
    def stopBounce(self, stopBounce=None):
        if  stopBounce is None:
            stopBounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stopBounce)
        self.__stopBounce = stopBounce
    @property # getter - - - - - - - - - -
    def stopErrorCorrection(self):
        """[0,1] stopErrorCorrection is fraction of error correction performed during time step once stop point is reached."""
        return self.__stopErrorCorrection
    @stopErrorCorrection.setter
    def stopErrorCorrection(self, stopErrorCorrection=None):
        if  stopErrorCorrection is None:
            stopErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stopErrorCorrection)
        self.__stopErrorCorrection = stopErrorCorrection
    @property # getter - - - - - - - - - -
    def body1(self):
        return self.__body1
    @body1.setter
    def body1(self, body1=None):
        if  body1 is None:
            body1 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body1)
        if not isinstance(body1, object):
            # print(flush=True)
            raise X3DTypeError(str(body1) + ' does not have a valid node type object')
        self.__body1 = body1
    @property # getter - - - - - - - - - -
    def body2(self):
        return self.__body2
    @body2.setter
    def body2(self, body2=None):
        if  body2 is None:
            body2 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body2)
        if not isinstance(body2, object):
            # print(flush=True)
            raise X3DTypeError(str(body2) + ' does not have a valid node type object')
        self.__body2 = body2
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.body1) or bool(self.body2) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SingleAxisHingeJoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SingleAxisHingeJoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.anchorPoint != (0, 0, 0):
            result += " anchorPoint='" + SFVec3f(self.anchorPoint).XML() + "'"
        if self.axis != (0, 0, 0):
            result += " axis='" + SFVec3f(self.axis).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.forceOutput != ["NONE"]:
            result += " forceOutput='" + MFString(self.forceOutput).XML() + "'"
        if self.maxAngle != 3.141592653:
            result += " maxAngle='" + SFFloat(self.maxAngle).XML() + "'"
        if self.minAngle != -3.141592653:
            result += " minAngle='" + SFFloat(self.minAngle).XML() + "'"
        if self.stopBounce != 0:
            result += " stopBounce='" + SFFloat(self.stopBounce).XML() + "'"
        if self.stopErrorCorrection != 0.8:
            result += " stopErrorCorrection='" + SFFloat(self.stopErrorCorrection).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.body1: # output this SFNode
                result += self.body1.XML(indentLevel=indentLevel+1)
            if self.body2: # output this SFNode
                result += self.body2.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</SingleAxisHingeJoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SliderJoint(_X3DRigidJointNode):
    """
    SliderJoint constrains all movement between body1 and body2 along a single axis. Contains two RigidBody nodes (containerField values body1, body2).
    """
    NAME = 'SliderJoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SliderJoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('axis', (0, 1, 0), FieldType.SFVec3f, AccessType.inputOutput, 'SliderJoint'),
        ('forceOutput', ["NONE"], FieldType.MFString, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('maxSeparation', 1, FieldType.SFFloat, AccessType.inputOutput, 'SliderJoint'),
        ('minSeparation', 0, FieldType.SFFloat, AccessType.inputOutput, 'SliderJoint'),
        ('sliderForce', 0, FieldType.SFFloat, AccessType.inputOutput, 'SliderJoint'),
        ('stopBounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'SliderJoint'),
        ('stopErrorCorrection', 1, FieldType.SFFloat, AccessType.inputOutput, 'SliderJoint'),
        ('body1', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('body2', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 axis=(0, 1, 0),
                 forceOutput=["NONE"],
                 maxSeparation=1,
                 minSeparation=0,
                 sliderForce=0,
                 stopBounce=0,
                 stopErrorCorrection=1,
                 body1=None,
                 body2=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SliderJoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.axis = axis
        self.forceOutput = forceOutput
        self.maxSeparation = maxSeparation
        self.minSeparation = minSeparation
        self.sliderForce = sliderForce
        self.stopBounce = stopBounce
        self.stopErrorCorrection = stopErrorCorrection
        self.body1 = body1
        self.body2 = body2
    @property # getter - - - - - - - - - -
    def axis(self):
        """[0,1] axis is normalized vector specifying direction of motion."""
        return self.__axis
    @axis.setter
    def axis(self, axis=None):
        if  axis is None:
            axis = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(axis)
        self.__axis = axis
    @property # getter - - - - - - - - - -
    def forceOutput(self):
        """forceOutput controls which output fields are generated for the next frame."""
        return self.__forceOutput
    @forceOutput.setter
    def forceOutput(self, forceOutput=None):
        if  forceOutput is None:
            forceOutput = MFString.DEFAULT_VALUE
        assertValidMFString(forceOutput)
        self.__forceOutput = forceOutput
    @property # getter - - - - - - - - - -
    def maxSeparation(self):
        """maxSeparation is maximum separation distance between the two bodies."""
        return self.__maxSeparation
    @maxSeparation.setter
    def maxSeparation(self, maxSeparation=None):
        if  maxSeparation is None:
            maxSeparation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxSeparation)
        self.__maxSeparation = maxSeparation
    @property # getter - - - - - - - - - -
    def minSeparation(self):
        """minSeparation is minimum separation distance between the two bodies."""
        return self.__minSeparation
    @minSeparation.setter
    def minSeparation(self, minSeparation=None):
        if  minSeparation is None:
            minSeparation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(minSeparation)
        self.__minSeparation = minSeparation
    @property # getter - - - - - - - - - -
    def sliderForce(self):
        return self.__sliderForce
    @sliderForce.setter
    def sliderForce(self, sliderForce=None):
        if  sliderForce is None:
            sliderForce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(sliderForce)
        self.__sliderForce = sliderForce
    @property # getter - - - - - - - - - -
    def stopBounce(self):
        """[0,1] stopBounce is velocity factor for bounce back once stop point is reached."""
        return self.__stopBounce
    @stopBounce.setter
    def stopBounce(self, stopBounce=None):
        if  stopBounce is None:
            stopBounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stopBounce)
        self.__stopBounce = stopBounce
    @property # getter - - - - - - - - - -
    def stopErrorCorrection(self):
        """[0,1] stopErrorCorrection is fraction of error correction performed during time step once stop point is reached."""
        return self.__stopErrorCorrection
    @stopErrorCorrection.setter
    def stopErrorCorrection(self, stopErrorCorrection=None):
        if  stopErrorCorrection is None:
            stopErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stopErrorCorrection)
        self.__stopErrorCorrection = stopErrorCorrection
    @property # getter - - - - - - - - - -
    def body1(self):
        return self.__body1
    @body1.setter
    def body1(self, body1=None):
        if  body1 is None:
            body1 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body1)
        if not isinstance(body1, object):
            # print(flush=True)
            raise X3DTypeError(str(body1) + ' does not have a valid node type object')
        self.__body1 = body1
    @property # getter - - - - - - - - - -
    def body2(self):
        return self.__body2
    @body2.setter
    def body2(self, body2=None):
        if  body2 is None:
            body2 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body2)
        if not isinstance(body2, object):
            # print(flush=True)
            raise X3DTypeError(str(body2) + ' does not have a valid node type object')
        self.__body2 = body2
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.body1) or bool(self.body2) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SliderJoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SliderJoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.axis != (0, 1, 0):
            result += " axis='" + SFVec3f(self.axis).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.forceOutput != ["NONE"]:
            result += " forceOutput='" + MFString(self.forceOutput).XML() + "'"
        if self.maxSeparation != 1:
            result += " maxSeparation='" + SFFloat(self.maxSeparation).XML() + "'"
        if self.minSeparation != 0:
            result += " minSeparation='" + SFFloat(self.minSeparation).XML() + "'"
        if self.sliderForce != 0:
            result += " sliderForce='" + SFFloat(self.sliderForce).XML() + "'"
        if self.stopBounce != 0:
            result += " stopBounce='" + SFFloat(self.stopBounce).XML() + "'"
        if self.stopErrorCorrection != 1:
            result += " stopErrorCorrection='" + SFFloat(self.stopErrorCorrection).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.body1: # output this SFNode
                result += self.body1.XML(indentLevel=indentLevel+1)
            if self.body2: # output this SFNode
                result += self.body2.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</SliderJoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Sound(_X3DSoundNode):
    """
    The Sound node controls the 3D spatialization of sound playback by a child AudioClip or MovieTexture node.
    """
    NAME = 'Sound'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Sound'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('direction', (0, 0, 1), FieldType.SFVec3f, AccessType.inputOutput, 'Sound'),
        ('intensity', 1, FieldType.SFFloat, AccessType.inputOutput, 'Sound'),
        ('location', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'Sound'),
        ('maxBack', 10, FieldType.SFFloat, AccessType.inputOutput, 'Sound'),
        ('maxFront', 10, FieldType.SFFloat, AccessType.inputOutput, 'Sound'),
        ('minBack', 1, FieldType.SFFloat, AccessType.inputOutput, 'Sound'),
        ('minFront', 1, FieldType.SFFloat, AccessType.inputOutput, 'Sound'),
        ('priority', 0, FieldType.SFFloat, AccessType.inputOutput, 'Sound'),
        ('spatialize', True, FieldType.SFBool, AccessType.initializeOnly, 'Sound'),
        ('source', None, FieldType.SFNode, AccessType.inputOutput, 'Sound'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 direction=(0, 0, 1),
                 intensity=1,
                 location=(0, 0, 0),
                 maxBack=10,
                 maxFront=10,
                 minBack=1,
                 minFront=1,
                 priority=0,
                 spatialize=True,
                 source=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Sound __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.direction = direction
        self.intensity = intensity
        self.location = location
        self.maxBack = maxBack
        self.maxFront = maxFront
        self.minBack = minBack
        self.minFront = minFront
        self.priority = priority
        self.spatialize = spatialize
        self.source = source
    @property # getter - - - - - - - - - -
    def direction(self):
        """direction of sound axis, relative to local coordinate system."""
        return self.__direction
    @direction.setter
    def direction(self, direction=None):
        if  direction is None:
            direction = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(direction)
        self.__direction = direction
    @property # getter - - - - - - - - - -
    def intensity(self):
        """Factor [0,1] adjusting loudness (decibels) of emitted sound."""
        return self.__intensity
    @intensity.setter
    def intensity(self, intensity=None):
        if  intensity is None:
            intensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(intensity)
        assertZeroToOne('intensity', intensity)
        self.__intensity = intensity
    @property # getter - - - - - - - - - -
    def location(self):
        """Position of sound ellipsoid center, relative to local coordinate system."""
        return self.__location
    @location.setter
    def location(self, location=None):
        if  location is None:
            location = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(location)
        self.__location = location
    @property # getter - - - - - - - - - -
    def maxBack(self):
        """Outer (zero loudness)ellipsoid distance along back direction."""
        return self.__maxBack
    @maxBack.setter
    def maxBack(self, maxBack=None):
        if  maxBack is None:
            maxBack = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxBack)
        assertNonNegative('maxBack', maxBack)
        self.__maxBack = maxBack
    @property # getter - - - - - - - - - -
    def maxFront(self):
        """Outer (zero loudness)ellipsoid distance along front direction."""
        return self.__maxFront
    @maxFront.setter
    def maxFront(self, maxFront=None):
        if  maxFront is None:
            maxFront = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxFront)
        assertNonNegative('maxFront', maxFront)
        self.__maxFront = maxFront
    @property # getter - - - - - - - - - -
    def minBack(self):
        """Inner (full loudness) ellipsoid distance along back direction."""
        return self.__minBack
    @minBack.setter
    def minBack(self, minBack=None):
        if  minBack is None:
            minBack = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(minBack)
        assertNonNegative('minBack', minBack)
        self.__minBack = minBack
    @property # getter - - - - - - - - - -
    def minFront(self):
        """Inner (full loudness) ellipsoid distance along front direction."""
        return self.__minFront
    @minFront.setter
    def minFront(self, minFront=None):
        if  minFront is None:
            minFront = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(minFront)
        assertNonNegative('minFront', minFront)
        self.__minFront = minFront
    @property # getter - - - - - - - - - -
    def priority(self):
        """Player hint [0,1] if needed to choose which sounds to play."""
        return self.__priority
    @priority.setter
    def priority(self, priority=None):
        if  priority is None:
            priority = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(priority)
        assertZeroToOne('priority', priority)
        self.__priority = priority
    @property # getter - - - - - - - - - -
    def spatialize(self):
        """Whether to spatialize sound playback relative to viewer."""
        return self.__spatialize
    @spatialize.setter
    def spatialize(self, spatialize=None):
        if  spatialize is None:
            spatialize = SFBool.DEFAULT_VALUE
        assertValidSFBool(spatialize)
        self.__spatialize = spatialize
    @property # getter - - - - - - - - - -
    def source(self):
        """[X3DSoundSourceNode] sound source for the Sound node, either an AudioClip node or a MovieTexture node."""
        return self.__source
    @source.setter
    def source(self, source=None):
        if  source is None:
            source = SFNode.DEFAULT_VALUE
        assertValidSFNode(source)
        if not isinstance(source, object):
            # print(flush=True)
            raise X3DTypeError(str(source) + ' does not have a valid node type object')
        self.__source = source
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.source)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Sound.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Sound'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.direction != (0, 0, 1):
            result += " direction='" + SFVec3f(self.direction).XML() + "'"
        if self.intensity != 1:
            result += " intensity='" + SFFloat(self.intensity).XML() + "'"
        if self.location != (0, 0, 0):
            result += " location='" + SFVec3f(self.location).XML() + "'"
        if self.maxBack != 10:
            result += " maxBack='" + SFFloat(self.maxBack).XML() + "'"
        if self.maxFront != 10:
            result += " maxFront='" + SFFloat(self.maxFront).XML() + "'"
        if self.minBack != 1:
            result += " minBack='" + SFFloat(self.minBack).XML() + "'"
        if self.minFront != 1:
            result += " minFront='" + SFFloat(self.minFront).XML() + "'"
        if self.priority != 0:
            result += " priority='" + SFFloat(self.priority).XML() + "'"
        if self.spatialize != True:
            result += " spatialize='" + SFBool(self.spatialize).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.source: # output this SFNode
                result += self.source.XML(indentLevel=indentLevel+1)
            result += indent + '</Sound>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Sphere(_X3DGeometryNode):
    """
    Sphere is a geometry node, representing a perfectly round geometrical object that is the surface of a completely round ball.
    """
    NAME = 'Sphere'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Sphere'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('radius', 1, FieldType.SFFloat, AccessType.initializeOnly, 'Sphere'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'Sphere'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 radius=1,
                 solid=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Sphere __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.radius = radius
        self.solid = solid
    @property # getter - - - - - - - - - -
    def radius(self):
        """(0,+infinity) Size in meters."""
        return self.__radius
    @radius.setter
    def radius(self, radius=None):
        if  radius is None:
            radius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(radius)
        assertPositive('radius', radius)
        self.__radius = radius
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Sphere.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Sphere'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.radius != 1:
            result += " radius='" + SFFloat(self.radius).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Sphere>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SphereSensor(_X3DDragSensorNode):
    """
    SphereSensor converts pointing device motion into a spherical rotation about the origin of the local coordinate system.
    """
    NAME = 'SphereSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SphereSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('autoOffset', True, FieldType.SFBool, AccessType.inputOutput, 'X3DDragSensorNode'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DPointingDeviceSensorNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('offset', (0, 1, 0, 0), FieldType.SFRotation, AccessType.inputOutput, 'SphereSensor'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 autoOffset=True,
                 description='',
                 enabled=True,
                 offset=(0, 1, 0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SphereSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.autoOffset = autoOffset
        self.description = description
        self.enabled = enabled
        self.offset = offset
    @property # getter - - - - - - - - - -
    def autoOffset(self):
        """Determines whether previous offset values are remembered/accumulated."""
        return self.__autoOffset
    @autoOffset.setter
    def autoOffset(self, autoOffset=None):
        if  autoOffset is None:
            autoOffset = SFBool.DEFAULT_VALUE
        assertValidSFBool(autoOffset)
        self.__autoOffset = autoOffset
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def offset(self):
        """Sends event and remembers last value sensed."""
        return self.__offset
    @offset.setter
    def offset(self, offset=None):
        if  offset is None:
            offset = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(offset)
        self.__offset = offset
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SphereSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SphereSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.autoOffset != True:
            result += " autoOffset='" + SFBool(self.autoOffset).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.offset != (0, 1, 0, 0):
            result += " offset='" + SFRotation(self.offset).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</SphereSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SplinePositionInterpolator(_X3DInterpolatorNode):
    """
    SplinePositionInterpolator performs non-linear interpolation among paired lists of 3-tuple values and velocities to produce an SFVec3f value_changed output event.
    """
    NAME = 'SplinePositionInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SplinePositionInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('closed', False, FieldType.SFBool, AccessType.initializeOnly, 'SplinePositionInterpolator'),
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFVec3f, AccessType.inputOutput, 'SplinePositionInterpolator'),
        ('keyVelocity', list(), FieldType.MFVec3f, AccessType.inputOutput, 'SplinePositionInterpolator'),
        ('normalizeVelocity', False, FieldType.SFBool, AccessType.inputOutput, 'SplinePositionInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 closed=False,
                 key=list(),
                 keyValue=list(),
                 keyVelocity=list(),
                 normalizeVelocity=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SplinePositionInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.closed = closed
        self.key = key
        self.keyValue = keyValue
        self.keyVelocity = keyVelocity
        self.normalizeVelocity = normalizeVelocity
    @property # getter - - - - - - - - - -
    def closed(self):
        """Whether or not the curve is closed (i."""
        return self.__closed
    @closed.setter
    def closed(self, closed=None):
        if  closed is None:
            closed = SFBool.DEFAULT_VALUE
        assertValidSFBool(closed)
        self.__closed = closed
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition parameters for nonlinear-interpolation function time intervals, listed in non-decreasing order and corresponding to keyValue, keyVelocity array values."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for nonlinear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(keyValue)
        self.__keyValue = keyValue
    @property # getter - - - - - - - - - -
    def keyVelocity(self):
        """Output values for nonlinear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyVelocity
    @keyVelocity.setter
    def keyVelocity(self, keyVelocity=None):
        if  keyVelocity is None:
            keyVelocity = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(keyVelocity)
        self.__keyVelocity = keyVelocity
    @property # getter - - - - - - - - - -
    def normalizeVelocity(self):
        """normalizeVelocity field specifies whether the velocity vectors are normalized to produce smooth speed transitions, or transformed into tangency vectors."""
        return self.__normalizeVelocity
    @normalizeVelocity.setter
    def normalizeVelocity(self, normalizeVelocity=None):
        if  normalizeVelocity is None:
            normalizeVelocity = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalizeVelocity)
        self.__normalizeVelocity = normalizeVelocity
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SplinePositionInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SplinePositionInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.closed != False:
            result += " closed='" + SFBool(self.closed).XML() + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFVec3f(self.keyValue).XML() + "'"
        if self.keyVelocity != list():
            result += " keyVelocity='" + MFVec3f(self.keyVelocity).XML() + "'"
        if self.normalizeVelocity != False:
            result += " normalizeVelocity='" + SFBool(self.normalizeVelocity).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</SplinePositionInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SplinePositionInterpolator2D(_X3DInterpolatorNode):
    """
    SplinePositionInterpolator2D performs non-linear interpolation among paired lists of 2-tuple values and velocities to produce an SFVec2f value_changed output event.
    """
    NAME = 'SplinePositionInterpolator2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SplinePositionInterpolator2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('closed', False, FieldType.SFBool, AccessType.initializeOnly, 'SplinePositionInterpolator2D'),
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFVec2f, AccessType.inputOutput, 'SplinePositionInterpolator2D'),
        ('keyVelocity', list(), FieldType.MFVec2f, AccessType.inputOutput, 'SplinePositionInterpolator2D'),
        ('normalizeVelocity', False, FieldType.SFBool, AccessType.inputOutput, 'SplinePositionInterpolator2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 closed=False,
                 key=list(),
                 keyValue=list(),
                 keyVelocity=list(),
                 normalizeVelocity=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SplinePositionInterpolator2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.closed = closed
        self.key = key
        self.keyValue = keyValue
        self.keyVelocity = keyVelocity
        self.normalizeVelocity = normalizeVelocity
    @property # getter - - - - - - - - - -
    def closed(self):
        """Whether or not the curve is closed (i."""
        return self.__closed
    @closed.setter
    def closed(self, closed=None):
        if  closed is None:
            closed = SFBool.DEFAULT_VALUE
        assertValidSFBool(closed)
        self.__closed = closed
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition parameters for nonlinear-interpolation function time intervals, listed in non-decreasing order and corresponding to keyValue, keyVelocity array values."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for nonlinear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(keyValue)
        self.__keyValue = keyValue
    @property # getter - - - - - - - - - -
    def keyVelocity(self):
        """Output values for nonlinear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyVelocity
    @keyVelocity.setter
    def keyVelocity(self, keyVelocity=None):
        if  keyVelocity is None:
            keyVelocity = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(keyVelocity)
        self.__keyVelocity = keyVelocity
    @property # getter - - - - - - - - - -
    def normalizeVelocity(self):
        """normalizeVelocity field specifies whether the velocity vectors are normalized to produce smooth speed transitions, or transformed into tangency vectors."""
        return self.__normalizeVelocity
    @normalizeVelocity.setter
    def normalizeVelocity(self, normalizeVelocity=None):
        if  normalizeVelocity is None:
            normalizeVelocity = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalizeVelocity)
        self.__normalizeVelocity = normalizeVelocity
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SplinePositionInterpolator2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SplinePositionInterpolator2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.closed != False:
            result += " closed='" + SFBool(self.closed).XML() + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFVec2f(self.keyValue).XML() + "'"
        if self.keyVelocity != list():
            result += " keyVelocity='" + MFVec2f(self.keyVelocity).XML() + "'"
        if self.normalizeVelocity != False:
            result += " normalizeVelocity='" + SFBool(self.normalizeVelocity).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</SplinePositionInterpolator2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SplineScalarInterpolator(_X3DInterpolatorNode):
    """
    SplineScalarInterpolator performs non-linear interpolation among paired lists of float values and velocities to produce an SFFloat value_changed output event.
    """
    NAME = 'SplineScalarInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SplineScalarInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('closed', False, FieldType.SFBool, AccessType.initializeOnly, 'SplineScalarInterpolator'),
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFFloat, AccessType.inputOutput, 'SplineScalarInterpolator'),
        ('keyVelocity', list(), FieldType.MFFloat, AccessType.inputOutput, 'SplineScalarInterpolator'),
        ('normalizeVelocity', False, FieldType.SFBool, AccessType.inputOutput, 'SplineScalarInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 closed=False,
                 key=list(),
                 keyValue=list(),
                 keyVelocity=list(),
                 normalizeVelocity=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SplineScalarInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.closed = closed
        self.key = key
        self.keyValue = keyValue
        self.keyVelocity = keyVelocity
        self.normalizeVelocity = normalizeVelocity
    @property # getter - - - - - - - - - -
    def closed(self):
        """Whether or not the curve is closed (i."""
        return self.__closed
    @closed.setter
    def closed(self, closed=None):
        if  closed is None:
            closed = SFBool.DEFAULT_VALUE
        assertValidSFBool(closed)
        self.__closed = closed
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition parameters for nonlinear-interpolation function time intervals, listed in non-decreasing order and corresponding to keyValue, keyVelocity array values."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for nonlinear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(keyValue)
        self.__keyValue = keyValue
    @property # getter - - - - - - - - - -
    def keyVelocity(self):
        """Output values for nonlinear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyVelocity
    @keyVelocity.setter
    def keyVelocity(self, keyVelocity=None):
        if  keyVelocity is None:
            keyVelocity = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(keyVelocity)
        self.__keyVelocity = keyVelocity
    @property # getter - - - - - - - - - -
    def normalizeVelocity(self):
        """normalizeVelocity field specifies whether the velocity vectors are normalized to produce smooth speed transitions, or transformed into tangency vectors."""
        return self.__normalizeVelocity
    @normalizeVelocity.setter
    def normalizeVelocity(self, normalizeVelocity=None):
        if  normalizeVelocity is None:
            normalizeVelocity = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalizeVelocity)
        self.__normalizeVelocity = normalizeVelocity
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SplineScalarInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SplineScalarInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.closed != False:
            result += " closed='" + SFBool(self.closed).XML() + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFFloat(self.keyValue).XML() + "'"
        if self.keyVelocity != list():
            result += " keyVelocity='" + MFFloat(self.keyVelocity).XML() + "'"
        if self.normalizeVelocity != False:
            result += " normalizeVelocity='" + SFBool(self.normalizeVelocity).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</SplineScalarInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SpotLight(_X3DLightNode):
    """
    Linear attenuation may occur at level 2, full support at level 3.
    """
    NAME = 'SpotLight'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SpotLight'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ambientIntensity', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DLightNode'),
        ('attenuation', (1, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'SpotLight'),
        ('beamWidth', 0.7854, FieldType.SFFloat, AccessType.inputOutput, 'SpotLight'),
        ('color', (1, 1, 1), FieldType.SFColor, AccessType.inputOutput, 'X3DLightNode'),
        ('cutOffAngle', 1.570796, FieldType.SFFloat, AccessType.inputOutput, 'SpotLight'),
        ('direction', (0, 0, -1), FieldType.SFVec3f, AccessType.inputOutput, 'SpotLight'),
        ('global_', True, FieldType.SFBool, AccessType.inputOutput, 'SpotLight'),
        ('intensity', 1, FieldType.SFFloat, AccessType.inputOutput, 'X3DLightNode'),
        ('location', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'SpotLight'),
        ('on', True, FieldType.SFBool, AccessType.inputOutput, 'X3DLightNode'),
        ('radius', 100, FieldType.SFFloat, AccessType.initializeOnly, 'SpotLight'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ambientIntensity=0,
                 attenuation=(1, 0, 0),
                 beamWidth=0.7854,
                 color=(1, 1, 1),
                 cutOffAngle=1.570796,
                 direction=(0, 0, -1),
                 global_=True,
                 intensity=1,
                 location=(0, 0, 0),
                 on=True,
                 radius=100,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SpotLight __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ambientIntensity = ambientIntensity
        self.attenuation = attenuation
        self.beamWidth = beamWidth
        self.color = color
        self.cutOffAngle = cutOffAngle
        self.direction = direction
        self.global_ = global_
        self.intensity = intensity
        self.location = location
        self.on = on
        self.radius = radius
    @property # getter - - - - - - - - - -
    def ambientIntensity(self):
        """[0,1] Brightness of ambient (nondirectional background) emission from the light."""
        return self.__ambientIntensity
    @ambientIntensity.setter
    def ambientIntensity(self, ambientIntensity=None):
        if  ambientIntensity is None:
            ambientIntensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(ambientIntensity)
        assertZeroToOne('ambientIntensity', ambientIntensity)
        self.__ambientIntensity = ambientIntensity
    @property # getter - - - - - - - - - -
    def attenuation(self):
        """Constant, linear-distance and squared-distance dropoff factors as radial distance increases from the source."""
        return self.__attenuation
    @attenuation.setter
    def attenuation(self, attenuation=None):
        if  attenuation is None:
            attenuation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(attenuation)
        assertNonNegative('attenuation', attenuation)
        self.__attenuation = attenuation
    @property # getter - - - - - - - - - -
    def beamWidth(self):
        """[0,1."""
        return self.__beamWidth
    @beamWidth.setter
    def beamWidth(self, beamWidth=None):
        if  beamWidth is None:
            beamWidth = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(beamWidth)
        assertGreaterThan('beamWidth', beamWidth, 0)
        assertLessThanEquals('beamWidth', beamWidth, 1.570796)
        self.__beamWidth = beamWidth
    @property # getter - - - - - - - - - -
    def color(self):
        """[0,1] color of light, applied to colors of objects."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFColor.DEFAULT_VALUE
        assertValidSFColor(color)
        assertZeroToOne('color', color)
        self.__color = color
    @property # getter - - - - - - - - - -
    def cutOffAngle(self):
        """[0,1."""
        return self.__cutOffAngle
    @cutOffAngle.setter
    def cutOffAngle(self, cutOffAngle=None):
        if  cutOffAngle is None:
            cutOffAngle = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(cutOffAngle)
        assertGreaterThan('cutOffAngle', cutOffAngle, 0)
        assertLessThanEquals('cutOffAngle', cutOffAngle, 1.570796)
        self.__cutOffAngle = cutOffAngle
    @property # getter - - - - - - - - - -
    def direction(self):
        """Orientation vector of light relative to local coordinate system."""
        return self.__direction
    @direction.setter
    def direction(self, direction=None):
        if  direction is None:
            direction = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(direction)
        self.__direction = direction
    @property # getter - - - - - - - - - -
    def global_(self):
        return self.__global_
    @global_.setter
    def global_(self, global_=None):
        if  global_ is None:
            global_ = SFBool.DEFAULT_VALUE
        assertValidSFBool(global_)
        self.__global_ = global_
    @property # getter - - - - - - - - - -
    def intensity(self):
        """[0,1] Brightness of direct emission from the light."""
        return self.__intensity
    @intensity.setter
    def intensity(self, intensity=None):
        if  intensity is None:
            intensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(intensity)
        assertZeroToOne('intensity', intensity)
        self.__intensity = intensity
    @property # getter - - - - - - - - - -
    def location(self):
        """Position of light relative to local coordinate system."""
        return self.__location
    @location.setter
    def location(self, location=None):
        if  location is None:
            location = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(location)
        self.__location = location
    @property # getter - - - - - - - - - -
    def on(self):
        """Enables/disables this light source."""
        return self.__on
    @on.setter
    def on(self, on=None):
        if  on is None:
            on = SFBool.DEFAULT_VALUE
        assertValidSFBool(on)
        self.__on = on
    @property # getter - - - - - - - - - -
    def radius(self):
        """Maximum effective distance of light relative to local light position, affected by ancestor scaling."""
        return self.__radius
    @radius.setter
    def radius(self, radius=None):
        if  radius is None:
            radius = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(radius)
        assertNonNegative('radius', radius)
        self.__radius = radius
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SpotLight.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SpotLight'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ambientIntensity != 0:
            result += " ambientIntensity='" + SFFloat(self.ambientIntensity).XML() + "'"
        if self.attenuation != (1, 0, 0):
            result += " attenuation='" + SFVec3f(self.attenuation).XML() + "'"
        if self.beamWidth != 0.7854:
            result += " beamWidth='" + SFFloat(self.beamWidth).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.color != (1, 1, 1):
            result += " color='" + SFColor(self.color).XML() + "'"
        if self.cutOffAngle != 1.570796:
            result += " cutOffAngle='" + SFFloat(self.cutOffAngle).XML() + "'"
        if self.direction != (0, 0, -1):
            result += " direction='" + SFVec3f(self.direction).XML() + "'"
        if self.global_ != True:
            result += " global_='" + SFBool(self.global_).XML() + "'"
        if self.intensity != 1:
            result += " intensity='" + SFFloat(self.intensity).XML() + "'"
        if self.location != (0, 0, 0):
            result += " location='" + SFVec3f(self.location).XML() + "'"
        if self.on != True:
            result += " on='" + SFBool(self.on).XML() + "'"
        if self.radius != 100:
            result += " radius='" + SFFloat(self.radius).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</SpotLight>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SquadOrientationInterpolator(_X3DInterpolatorNode):
    """
    SquadOrientationInterpolator performs non-linear interpolation among paired lists of rotation values to produce an SFRotation value_changed output event.
    """
    NAME = 'SquadOrientationInterpolator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SquadOrientationInterpolator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('key', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DInterpolatorNode'),
        ('keyValue', list(), FieldType.MFRotation, AccessType.inputOutput, 'SquadOrientationInterpolator'),
        ('normalizeVelocity', False, FieldType.SFBool, AccessType.inputOutput, 'SquadOrientationInterpolator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 key=list(),
                 keyValue=list(),
                 normalizeVelocity=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SquadOrientationInterpolator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.key = key
        self.keyValue = keyValue
        self.normalizeVelocity = normalizeVelocity
    @property # getter - - - - - - - - - -
    def key(self):
        """Definition parameters for nonlinear-interpolation function time intervals, listed in non-decreasing order and corresponding to keyValue, keyVelocity array values."""
        return self.__key
    @key.setter
    def key(self, key=None):
        if  key is None:
            key = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(key)
        self.__key = key
    @property # getter - - - - - - - - - -
    def keyValue(self):
        """Output values for nonlinear interpolation, each corresponding to an input-fraction value in the key array."""
        return self.__keyValue
    @keyValue.setter
    def keyValue(self, keyValue=None):
        if  keyValue is None:
            keyValue = MFRotation.DEFAULT_VALUE
        assertValidMFRotation(keyValue)
        self.__keyValue = keyValue
    @property # getter - - - - - - - - - -
    def normalizeVelocity(self):
        """normalizeVelocity field specifies whether the velocity vectors are normalized to produce smooth speed transitions, or transformed into tangency vectors."""
        return self.__normalizeVelocity
    @normalizeVelocity.setter
    def normalizeVelocity(self, normalizeVelocity=None):
        if  normalizeVelocity is None:
            normalizeVelocity = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalizeVelocity)
        self.__normalizeVelocity = normalizeVelocity
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SquadOrientationInterpolator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SquadOrientationInterpolator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.key != list():
            result += " key='" + MFFloat(self.key).XML() + "'"
        if self.keyValue != list():
            result += " keyValue='" + MFRotation(self.keyValue).XML() + "'"
        if self.normalizeVelocity != False:
            result += " normalizeVelocity='" + SFBool(self.normalizeVelocity).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</SquadOrientationInterpolator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class StaticGroup(_X3DChildNode, _X3DBoundedObject):
    """
    StaticGroup is similar to Group node but does not allow access to children after creation time.
    """
    NAME = 'StaticGroup'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#StaticGroup'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('children', list(), FieldType.MFNode, AccessType.initializeOnly, 'StaticGroup'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode StaticGroup __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function StaticGroup.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<StaticGroup'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</StaticGroup>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class StringSensor(_X3DKeyDeviceSensorNode):
    """
    StringSensor generates events as the user presses keys on the keyboard.
    """
    NAME = 'StringSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#StringSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('deletionAllowed', True, FieldType.SFBool, AccessType.inputOutput, 'StringSensor'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 deletionAllowed=True,
                 enabled=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode StringSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.deletionAllowed = deletionAllowed
        self.enabled = enabled
    @property # getter - - - - - - - - - -
    def deletionAllowed(self):
        """If deletionAllowed is true, then previously entered character in enteredText can be removed."""
        return self.__deletionAllowed
    @deletionAllowed.setter
    def deletionAllowed(self, deletionAllowed=None):
        if  deletionAllowed is None:
            deletionAllowed = SFBool.DEFAULT_VALUE
        assertValidSFBool(deletionAllowed)
        self.__deletionAllowed = deletionAllowed
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function StringSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<StringSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.deletionAllowed != True:
            result += " deletionAllowed='" + SFBool(self.deletionAllowed).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</StringSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class SurfaceEmitter(_X3DParticleEmitterNode):
    """
    SurfaceEmitter generates particles from the surface of an object.
    """
    NAME = 'SurfaceEmitter'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#SurfaceEmitter'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('coordIndex', [-1], FieldType.MFInt32, AccessType.initializeOnly, 'SurfaceEmitter'),
        ('mass', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('speed', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('surfaceArea', 0, FieldType.SFFloat, AccessType.initializeOnly, 'X3DParticleEmitterNode'),
        ('variation', 0.25, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('surface', None, FieldType.SFNode, AccessType.initializeOnly, 'SurfaceEmitter'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 coordIndex=[-1],
                 mass=0,
                 speed=0,
                 surfaceArea=0,
                 variation=0.25,
                 surface=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode SurfaceEmitter __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.coordIndex = coordIndex
        self.mass = mass
        self.speed = speed
        self.surfaceArea = surfaceArea
        self.variation = variation
        self.surface = surface
    @property # getter - - - - - - - - - -
    def coordIndex(self):
        """[-1,+infinity) coordIndex indices are applied to contained Coordinate values in order to define randomly generated initial geometry of the particles."""
        return self.__coordIndex
    @coordIndex.setter
    def coordIndex(self, coordIndex=None):
        if  coordIndex is None:
            coordIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(coordIndex)
        assertGreaterThanEquals('coordIndex', coordIndex, -1)
        self.__coordIndex = coordIndex
    @property # getter - - - - - - - - - -
    def mass(self):
        """[0,+infinity) Basic mass of each particle, defined in mass base units (default is kilograms)."""
        return self.__mass
    @mass.setter
    def mass(self, mass=None):
        if  mass is None:
            mass = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(mass)
        assertNonNegative('mass', mass)
        self.__mass = mass
    @property # getter - - - - - - - - - -
    def speed(self):
        """[0,+infinity) Initial linear speed (default is m/s) imparted to all particles along their direction of movement."""
        return self.__speed
    @speed.setter
    def speed(self, speed=None):
        if  speed is None:
            speed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speed)
        assertNonNegative('speed', speed)
        self.__speed = speed
    @property # getter - - - - - - - - - -
    def surfaceArea(self):
        """[0,+infinity) Particle surface area in area base units (default is meters squared)."""
        return self.__surfaceArea
    @surfaceArea.setter
    def surfaceArea(self, surfaceArea=None):
        if  surfaceArea is None:
            surfaceArea = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(surfaceArea)
        assertNonNegative('surfaceArea', surfaceArea)
        self.__surfaceArea = surfaceArea
    @property # getter - - - - - - - - - -
    def variation(self):
        """[0,+infinity) Multiplier for the randomness used to control the range of possible output values."""
        return self.__variation
    @variation.setter
    def variation(self, variation=None):
        if  variation is None:
            variation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(variation)
        assertNonNegative('variation', variation)
        self.__variation = variation
    @property # getter - - - - - - - - - -
    def surface(self):
        """[X3DGeometryNode] The geometry node provides geometry used as the emitting surface."""
        return self.__surface
    @surface.setter
    def surface(self, surface=None):
        if  surface is None:
            surface = SFNode.DEFAULT_VALUE
        assertValidSFNode(surface)
        if not isinstance(surface, object):
            # print(flush=True)
            raise X3DTypeError(str(surface) + ' does not have a valid node type object')
        self.__surface = surface
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.surface)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function SurfaceEmitter.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<SurfaceEmitter'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.coordIndex != [-1]:
            result += " coordIndex='" + MFInt32(self.coordIndex).XML() + "'"
        if self.mass != 0:
            result += " mass='" + SFFloat(self.mass).XML() + "'"
        if self.speed != 0:
            result += " speed='" + SFFloat(self.speed).XML() + "'"
        if self.surfaceArea != 0:
            result += " surfaceArea='" + SFFloat(self.surfaceArea).XML() + "'"
        if self.variation != 0.25:
            result += " variation='" + SFFloat(self.variation).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.surface: # output this SFNode
                result += self.surface.XML(indentLevel=indentLevel+1)
            result += indent + '</SurfaceEmitter>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Switch(_X3DGroupingNode):
    """
    Switch is a Grouping node that only renders one (or zero) child at a time.
    """
    NAME = 'Switch'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Switch'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('whichChoice', -1, FieldType.SFInt32, AccessType.inputOutput, 'Switch'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 displayBBox=False,
                 visible=True,
                 whichChoice=-1,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Switch __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.displayBBox = displayBBox
        self.visible = visible
        self.whichChoice = whichChoice
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def whichChoice(self):
        """[-1,+infinity) Index of active child choice, counting from 0."""
        return self.__whichChoice
    @whichChoice.setter
    def whichChoice(self, whichChoice=None):
        if  whichChoice is None:
            whichChoice = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(whichChoice)
        assertGreaterThanEquals('whichChoice', whichChoice, -1)
        self.__whichChoice = whichChoice
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Switch.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Switch'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if self.whichChoice != -1:
            result += " whichChoice='" + SFInt32(self.whichChoice).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Switch>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TexCoordChaser2D(_X3DChaserNode):
    """
    TexCoordChaser2D generates a series of single floating-point values that progressively change from initial value to destination value.
    """
    NAME = 'TexCoordChaser2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TexCoordChaser2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('duration', 1, FieldType.SFTime, AccessType.initializeOnly, 'X3DChaserNode'),
        ('initialDestination', list(), FieldType.MFVec2f, AccessType.initializeOnly, 'TexCoordChaser2D'),
        ('initialValue', list(), FieldType.MFVec2f, AccessType.initializeOnly, 'TexCoordChaser2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 duration=1,
                 initialDestination=list(),
                 initialValue=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TexCoordChaser2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.duration = duration
        self.initialDestination = initialDestination
        self.initialValue = initialValue
    @property # getter - - - - - - - - - -
    def duration(self):
        """[0,+infinity) duration is the time interval for filter response in seconds."""
        return self.__duration
    @duration.setter
    def duration(self, duration=None):
        if  duration is None:
            duration = SFTime.DEFAULT_VALUE
        assertValidSFTime(duration)
        assertNonNegative('duration', duration)
        self.__duration = duration
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(initialValue)
        self.__initialValue = initialValue
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TexCoordChaser2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TexCoordChaser2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.duration != 1:
            result += " duration='" + SFTime(self.duration).XML() + "'"
        if self.initialDestination != list():
            result += " initialDestination='" + MFVec2f(self.initialDestination).XML() + "'"
        if self.initialValue != list():
            result += " initialValue='" + MFVec2f(self.initialValue).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TexCoordChaser2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TexCoordDamper2D(_X3DDamperNode):
    """
    TexCoordDamper2D generates a series of 2D floating-point arrays that progressively change from initial value to destination value.
    """
    NAME = 'TexCoordDamper2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TexCoordDamper2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('initialDestination', list(), FieldType.MFVec2f, AccessType.initializeOnly, 'TexCoordDamper2D'),
        ('initialValue', list(), FieldType.MFVec2f, AccessType.initializeOnly, 'TexCoordDamper2D'),
        ('order', 3, FieldType.SFInt32, AccessType.initializeOnly, 'X3DDamperNode'),
        ('tau', 0.3, FieldType.SFTime, AccessType.inputOutput, 'X3DDamperNode'),
        ('tolerance', -1, FieldType.SFFloat, AccessType.inputOutput, 'X3DDamperNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 initialDestination=list(),
                 initialValue=list(),
                 order=3,
                 tau=0.3,
                 tolerance=-1,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TexCoordDamper2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.initialDestination = initialDestination
        self.initialValue = initialValue
        self.order = order
        self.tau = tau
        self.tolerance = tolerance
    @property # getter - - - - - - - - - -
    def initialDestination(self):
        """Initial destination value for this node."""
        return self.__initialDestination
    @initialDestination.setter
    def initialDestination(self, initialDestination=None):
        if  initialDestination is None:
            initialDestination = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(initialDestination)
        self.__initialDestination = initialDestination
    @property # getter - - - - - - - - - -
    def initialValue(self):
        """Initial starting value for this node."""
        return self.__initialValue
    @initialValue.setter
    def initialValue(self, initialValue=None):
        if  initialValue is None:
            initialValue = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(initialValue)
        self.__initialValue = initialValue
    @property # getter - - - - - - - - - -
    def order(self):
        """[0,5] order defines the number of internal filters (larger means smoother response, longer delay)."""
        return self.__order
    @order.setter
    def order(self, order=None):
        if  order is None:
            order = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(order)
        assertGreaterThanEquals('order', order, 0)
        assertLessThanEquals('order', order, 5)
        self.__order = order
    @property # getter - - - - - - - - - -
    def tau(self):
        """[0,+infinity) tau is the exponential-decay time constant for filter response in seconds."""
        return self.__tau
    @tau.setter
    def tau(self, tau=None):
        if  tau is None:
            tau = SFTime.DEFAULT_VALUE
        assertValidSFTime(tau)
        assertNonNegative('tau', tau)
        self.__tau = tau
    @property # getter - - - - - - - - - -
    def tolerance(self):
        """[0,+infinity) or -1."""
        return self.__tolerance
    @tolerance.setter
    def tolerance(self, tolerance=None):
        if  tolerance is None:
            tolerance = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(tolerance)
        self.__tolerance = tolerance
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TexCoordDamper2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TexCoordDamper2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.initialDestination != list():
            result += " initialDestination='" + MFVec2f(self.initialDestination).XML() + "'"
        if self.initialValue != list():
            result += " initialValue='" + MFVec2f(self.initialValue).XML() + "'"
        if self.order != 3:
            result += " order='" + SFInt32(self.order).XML() + "'"
        if self.tau != 0.3:
            result += " tau='" + SFTime(self.tau).XML() + "'"
        if self.tolerance != -1:
            result += " tolerance='" + SFFloat(self.tolerance).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TexCoordDamper2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Text(_X3DGeometryNode):
    """
    Text is a 2D (flat) geometry node that can contain multiple lines of string values.
    """
    NAME = 'Text'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Text'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('length', list(), FieldType.MFFloat, AccessType.inputOutput, 'Text'),
        ('maxExtent', 0.0, FieldType.SFFloat, AccessType.inputOutput, 'Text'),
        ('solid', False, FieldType.SFBool, AccessType.initializeOnly, 'Text'),
        ('string', list(), FieldType.MFString, AccessType.inputOutput, 'Text'),
        ('fontStyle', None, FieldType.SFNode, AccessType.inputOutput, 'Text'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 length=list(),
                 maxExtent=0.0,
                 solid=False,
                 string=list(),
                 fontStyle=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Text __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.length = length
        self.maxExtent = maxExtent
        self.solid = solid
        self.string = string
        self.fontStyle = fontStyle
    @property # getter - - - - - - - - - -
    def length(self):
        """Array of length values for each text string in the local coordinate system."""
        return self.__length
    @length.setter
    def length(self, length=None):
        if  length is None:
            length = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(length)
        assertNonNegative('length', length)
        self.__length = length
    @property # getter - - - - - - - - - -
    def maxExtent(self):
        """Limits/compresses all text strings if max string length is longer than maxExtent, as measured in local coordinate system."""
        return self.__maxExtent
    @maxExtent.setter
    def maxExtent(self, maxExtent=None):
        if  maxExtent is None:
            maxExtent = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(maxExtent)
        assertNonNegative('maxExtent', maxExtent)
        self.__maxExtent = maxExtent
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def string(self):
        """Single or multiple string values to present as Text."""
        return self.__string
    @string.setter
    def string(self, string=None):
        if  string is None:
            string = MFString.DEFAULT_VALUE
        assertValidMFString(string)
        self.__string = string
    @property # getter - - - - - - - - - -
    def fontStyle(self):
        return self.__fontStyle
    @fontStyle.setter
    def fontStyle(self, fontStyle=None):
        if  fontStyle is None:
            fontStyle = SFNode.DEFAULT_VALUE
        assertValidSFNode(fontStyle)
        if not isinstance(fontStyle, object):
            # print(flush=True)
            raise X3DTypeError(str(fontStyle) + ' does not have a valid node type object')
        self.__fontStyle = fontStyle
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.fontStyle) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Text.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Text'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.length != list():
            result += " length='" + MFFloat(self.length).XML() + "'"
        if self.maxExtent != 0.0:
            result += " maxExtent='" + SFFloat(self.maxExtent).XML() + "'"
        if self.solid != False:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.string != list():
            result += " string='" + MFString(self.string).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.fontStyle: # output this SFNode
                result += self.fontStyle.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Text>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TextureBackground(_X3DBackgroundNode):
    """
    TextureBackground simulates ground and sky, using vertical arrays of wraparound color values, TextureBackground can also provide backdrop texture images on all six sides.
    """
    NAME = 'TextureBackground'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TextureBackground'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('groundAngle', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('groundColor', list(), FieldType.MFColor, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('skyAngle', list(), FieldType.MFFloat, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('skyColor', [(0, 0, 0)], FieldType.MFColor, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('transparency', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DBackgroundNode'),
        ('backTexture', None, FieldType.SFNode, AccessType.inputOutput, 'TextureBackground'),
        ('bottomTexture', None, FieldType.SFNode, AccessType.inputOutput, 'TextureBackground'),
        ('frontTexture', None, FieldType.SFNode, AccessType.inputOutput, 'TextureBackground'),
        ('leftTexture', None, FieldType.SFNode, AccessType.inputOutput, 'TextureBackground'),
        ('rightTexture', None, FieldType.SFNode, AccessType.inputOutput, 'TextureBackground'),
        ('topTexture', None, FieldType.SFNode, AccessType.inputOutput, 'TextureBackground'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 groundAngle=list(),
                 groundColor=list(),
                 skyAngle=list(),
                 skyColor=[(0, 0, 0)],
                 transparency=0,
                 backTexture=None,
                 bottomTexture=None,
                 frontTexture=None,
                 leftTexture=None,
                 rightTexture=None,
                 topTexture=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TextureBackground __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.groundAngle = groundAngle
        self.groundColor = groundColor
        self.skyAngle = skyAngle
        self.skyColor = skyColor
        self.transparency = transparency
        self.backTexture = backTexture
        self.bottomTexture = bottomTexture
        self.frontTexture = frontTexture
        self.leftTexture = leftTexture
        self.rightTexture = rightTexture
        self.topTexture = topTexture
    @property # getter - - - - - - - - - -
    def groundAngle(self):
        """[0,pi/2] The angle array values increase from 0."""
        return self.__groundAngle
    @groundAngle.setter
    def groundAngle(self, groundAngle=None):
        if  groundAngle is None:
            groundAngle = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(groundAngle)
        assertGreaterThanEquals('groundAngle', groundAngle, 0)
        assertLessThanEquals('groundAngle', groundAngle, 1.5708)
        self.__groundAngle = groundAngle
    @property # getter - - - - - - - - - -
    def groundColor(self):
        """Color of the ground at the various angles on the ground partial sphere."""
        return self.__groundColor
    @groundColor.setter
    def groundColor(self, groundColor=None):
        if  groundColor is None:
            groundColor = MFColor.DEFAULT_VALUE
        assertValidMFColor(groundColor)
        assertZeroToOne('groundColor', groundColor)
        self.__groundColor = groundColor
    @property # getter - - - - - - - - - -
    def skyAngle(self):
        """[0,pi] The angle array values increase from 0."""
        return self.__skyAngle
    @skyAngle.setter
    def skyAngle(self, skyAngle=None):
        if  skyAngle is None:
            skyAngle = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(skyAngle)
        assertGreaterThanEquals('skyAngle', skyAngle, 0)
        assertLessThanEquals('skyAngle', skyAngle, 3.1416)
        self.__skyAngle = skyAngle
    @property # getter - - - - - - - - - -
    def skyColor(self):
        """Color of the sky at various angles on the sky sphere."""
        return self.__skyColor
    @skyColor.setter
    def skyColor(self, skyColor=None):
        if  skyColor is None:
            skyColor = MFColor.DEFAULT_VALUE
        assertValidMFColor(skyColor)
        assertZeroToOne('skyColor', skyColor)
        self.__skyColor = skyColor
    @property # getter - - - - - - - - - -
    def transparency(self):
        """transparency applied to texture images, enabling an X3D scene to overlay an HTML page or desktop."""
        return self.__transparency
    @transparency.setter
    def transparency(self, transparency=None):
        if  transparency is None:
            transparency = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(transparency)
        assertZeroToOne('transparency', transparency)
        self.__transparency = transparency
    @property # getter - - - - - - - - - -
    def backTexture(self):
        """[X3DTexture2DNode | MultiTexture] Parent TextureBackground element can contain up to six image nodes (ImageTexture PixelTexture MovieTexture MultiTexture)."""
        return self.__backTexture
    @backTexture.setter
    def backTexture(self, backTexture=None):
        if  backTexture is None:
            backTexture = SFNode.DEFAULT_VALUE
        assertValidSFNode(backTexture)
        if not isinstance(backTexture, object):
            # print(flush=True)
            raise X3DTypeError(str(backTexture) + ' does not have a valid node type object')
        self.__backTexture = backTexture
    @property # getter - - - - - - - - - -
    def bottomTexture(self):
        """[X3DTexture2DNode | MultiTexture] Parent TextureBackground element can contain up to six image nodes (ImageTexture PixelTexture MovieTexture MultiTexture)."""
        return self.__bottomTexture
    @bottomTexture.setter
    def bottomTexture(self, bottomTexture=None):
        if  bottomTexture is None:
            bottomTexture = SFNode.DEFAULT_VALUE
        assertValidSFNode(bottomTexture)
        if not isinstance(bottomTexture, object):
            # print(flush=True)
            raise X3DTypeError(str(bottomTexture) + ' does not have a valid node type object')
        self.__bottomTexture = bottomTexture
    @property # getter - - - - - - - - - -
    def frontTexture(self):
        """[X3DTexture2DNode | MultiTexture] Parent TextureBackground element can contain up to six image nodes (ImageTexture PixelTexture MovieTexture MultiTexture)."""
        return self.__frontTexture
    @frontTexture.setter
    def frontTexture(self, frontTexture=None):
        if  frontTexture is None:
            frontTexture = SFNode.DEFAULT_VALUE
        assertValidSFNode(frontTexture)
        if not isinstance(frontTexture, object):
            # print(flush=True)
            raise X3DTypeError(str(frontTexture) + ' does not have a valid node type object')
        self.__frontTexture = frontTexture
    @property # getter - - - - - - - - - -
    def leftTexture(self):
        """[X3DTexture2DNode | MultiTexture] Parent TextureBackground element can contain up to six image nodes (ImageTexture PixelTexture MovieTexture MultiTexture)."""
        return self.__leftTexture
    @leftTexture.setter
    def leftTexture(self, leftTexture=None):
        if  leftTexture is None:
            leftTexture = SFNode.DEFAULT_VALUE
        assertValidSFNode(leftTexture)
        if not isinstance(leftTexture, object):
            # print(flush=True)
            raise X3DTypeError(str(leftTexture) + ' does not have a valid node type object')
        self.__leftTexture = leftTexture
    @property # getter - - - - - - - - - -
    def rightTexture(self):
        """[X3DTexture2DNode | MultiTexture] Parent TextureBackground element can contain up to six image nodes (ImageTexture PixelTexture MovieTexture MultiTexture)."""
        return self.__rightTexture
    @rightTexture.setter
    def rightTexture(self, rightTexture=None):
        if  rightTexture is None:
            rightTexture = SFNode.DEFAULT_VALUE
        assertValidSFNode(rightTexture)
        if not isinstance(rightTexture, object):
            # print(flush=True)
            raise X3DTypeError(str(rightTexture) + ' does not have a valid node type object')
        self.__rightTexture = rightTexture
    @property # getter - - - - - - - - - -
    def topTexture(self):
        """[X3DTexture2DNode | MultiTexture] Parent TextureBackground element can contain up to six image nodes (ImageTexture PixelTexture MovieTexture MultiTexture)."""
        return self.__topTexture
    @topTexture.setter
    def topTexture(self, topTexture=None):
        if  topTexture is None:
            topTexture = SFNode.DEFAULT_VALUE
        assertValidSFNode(topTexture)
        if not isinstance(topTexture, object):
            # print(flush=True)
            raise X3DTypeError(str(topTexture) + ' does not have a valid node type object')
        self.__topTexture = topTexture
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.backTexture) or bool(self.bottomTexture) or bool(self.frontTexture) or bool(self.IS) or bool(self.leftTexture) or bool(self.metadata) or bool(self.rightTexture) or bool(self.topTexture)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TextureBackground.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TextureBackground'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.groundAngle != list():
            result += " groundAngle='" + MFFloat(self.groundAngle).XML() + "'"
        if self.groundColor != list():
            result += " groundColor='" + MFColor(self.groundColor).XML() + "'"
        if self.skyAngle != list():
            result += " skyAngle='" + MFFloat(self.skyAngle).XML() + "'"
        if self.skyColor != [(0, 0, 0)]:
            result += " skyColor='" + MFColor(self.skyColor).XML() + "'"
        if self.transparency != 0:
            result += " transparency='" + SFFloat(self.transparency).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.backTexture: # output this SFNode
                result += self.backTexture.XML(indentLevel=indentLevel+1)
            if self.bottomTexture: # output this SFNode
                result += self.bottomTexture.XML(indentLevel=indentLevel+1)
            if self.frontTexture: # output this SFNode
                result += self.frontTexture.XML(indentLevel=indentLevel+1)
            if self.leftTexture: # output this SFNode
                result += self.leftTexture.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.rightTexture: # output this SFNode
                result += self.rightTexture.XML(indentLevel=indentLevel+1)
            if self.topTexture: # output this SFNode
                result += self.topTexture.XML(indentLevel=indentLevel+1)
            result += indent + '</TextureBackground>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TextureCoordinate(_X3DTextureCoordinateNode):
    """
    TextureCoordinate specifies 2D (s,t) texture-coordinate points, used by vertex-based geometry nodes (such as IndexedFaceSet or ElevationGrid) to map textures to vertices (and patches to NURBS surfaces).
    """
    NAME = 'TextureCoordinate'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TextureCoordinate'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('point', list(), FieldType.MFVec2f, AccessType.inputOutput, 'TextureCoordinate'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 point=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TextureCoordinate __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.point = point
    @property # getter - - - - - - - - - -
    def point(self):
        """pairs of 2D (s,t) texture coordinates, either in range [0,1] or higher if repeating."""
        return self.__point
    @point.setter
    def point(self, point=None):
        if  point is None:
            point = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(point)
        self.__point = point
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TextureCoordinate.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TextureCoordinate'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.point != list():
            result += " point='" + MFVec2f(self.point).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TextureCoordinate>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TextureCoordinate3D(_X3DTextureCoordinateNode):
    """
    TextureCoordinate3D specifies a set of 3D texture coordinates used by vertex-based geometry nodes (such as IndexedFaceSet or ElevationGrid) to map 3D textures to vertices.
    """
    NAME = 'TextureCoordinate3D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TextureCoordinate3D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('point', list(), FieldType.MFVec3f, AccessType.inputOutput, 'TextureCoordinate3D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 point=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TextureCoordinate3D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.point = point
    @property # getter - - - - - - - - - -
    def point(self):
        """triplets of 3D (s,t,r) texture coordinates, either in range [0,1] or higher if repeating."""
        return self.__point
    @point.setter
    def point(self, point=None):
        if  point is None:
            point = MFVec3f.DEFAULT_VALUE
        assertValidMFVec3f(point)
        self.__point = point
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TextureCoordinate3D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TextureCoordinate3D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.point != list():
            result += " point='" + MFVec3f(self.point).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TextureCoordinate3D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TextureCoordinate4D(_X3DTextureCoordinateNode):
    """
    TextureCoordinate4D specifies a set of 4D (homogeneous 3D) texture coordinates used by vertex-based geometry nodes (such as IndexedFaceSet or ElevationGrid) to map 3D textures to vertices.
    """
    NAME = 'TextureCoordinate4D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TextureCoordinate4D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('point', list(), FieldType.MFVec4f, AccessType.inputOutput, 'TextureCoordinate4D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 point=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TextureCoordinate4D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.point = point
    @property # getter - - - - - - - - - -
    def point(self):
        """4-tuple values of 4D texture coordinates, either in range [0,1] or higher if repeating."""
        return self.__point
    @point.setter
    def point(self, point=None):
        if  point is None:
            point = MFVec4f.DEFAULT_VALUE
        assertValidMFVec4f(point)
        self.__point = point
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TextureCoordinate4D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TextureCoordinate4D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.point != list():
            result += " point='" + MFVec4f(self.point).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TextureCoordinate4D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TextureCoordinateGenerator(_X3DTextureCoordinateNode):
    """
    TextureCoordinateGenerator computes 2D (s,t) texture-coordinate points, used by vertex-based geometry nodes (such as IndexedFaceSet or ElevationGrid) to map textures to vertices (and patches to NURBS surfaces).
    """
    NAME = 'TextureCoordinateGenerator'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TextureCoordinateGenerator'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('mode', 'SPHERE', FieldType.SFString, AccessType.inputOutput, 'TextureCoordinateGenerator'),
        ('parameter', list(), FieldType.MFFloat, AccessType.inputOutput, 'TextureCoordinateGenerator'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 mode='SPHERE',
                 parameter=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TextureCoordinateGenerator __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.mode = mode
        self.parameter = parameter
    @property # getter - - - - - - - - - -
    def mode(self):
        """parameter field defines the algorithm used to compute texture coordinates."""
        return self.__mode
    @mode.setter
    def mode(self, mode=None):
        if  mode is None:
            mode = SFString.DEFAULT_VALUE
        assertValidSFString(mode)
        self.__mode = mode
    @property # getter - - - - - - - - - -
    def parameter(self):
        """parameter array contains scale and translation (x y z) values for Perlin NOISE mode, parameter[0] contains index of refraction for SPHERE-REFLECT mode, parameter[0] contains index of refraction and parameter[1 to 3] contains the eye point in local coordinates for SPHERE-REFLECT-LOCAL mode."""
        return self.__parameter
    @parameter.setter
    def parameter(self, parameter=None):
        if  parameter is None:
            parameter = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(parameter)
        self.__parameter = parameter
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TextureCoordinateGenerator.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TextureCoordinateGenerator'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.mode != 'SPHERE':
            result += " mode='" + self.mode + "'"
        if self.parameter != list():
            result += " parameter='" + MFFloat(self.parameter).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TextureCoordinateGenerator>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TextureProperties(_X3DNode):
    """
    TextureProperties allows precise fine-grained control over application of image textures to geometry.
    """
    NAME = 'TextureProperties'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TextureProperties'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('anisotropicDegree', 1, FieldType.SFFloat, AccessType.inputOutput, 'TextureProperties'),
        ('borderColor', (0, 0, 0, 0), FieldType.SFColorRGBA, AccessType.inputOutput, 'TextureProperties'),
        ('borderWidth', 0, FieldType.SFInt32, AccessType.inputOutput, 'TextureProperties'),
        ('boundaryModeR', 'REPEAT', FieldType.SFString, AccessType.inputOutput, 'TextureProperties'),
        ('boundaryModeS', 'REPEAT', FieldType.SFString, AccessType.inputOutput, 'TextureProperties'),
        ('boundaryModeT', 'REPEAT', FieldType.SFString, AccessType.inputOutput, 'TextureProperties'),
        ('generateMipMaps', False, FieldType.SFBool, AccessType.initializeOnly, 'TextureProperties'),
        ('magnificationFilter', 'FASTEST', FieldType.SFString, AccessType.inputOutput, 'TextureProperties'),
        ('minificationFilter', 'FASTEST', FieldType.SFString, AccessType.inputOutput, 'TextureProperties'),
        ('textureCompression', 'FASTEST', FieldType.SFString, AccessType.inputOutput, 'TextureProperties'),
        ('texturePriority', 0, FieldType.SFFloat, AccessType.inputOutput, 'TextureProperties'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 anisotropicDegree=1,
                 borderColor=(0, 0, 0, 0),
                 borderWidth=0,
                 boundaryModeR='REPEAT',
                 boundaryModeS='REPEAT',
                 boundaryModeT='REPEAT',
                 generateMipMaps=False,
                 magnificationFilter='FASTEST',
                 minificationFilter='FASTEST',
                 textureCompression='FASTEST',
                 texturePriority=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TextureProperties __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.anisotropicDegree = anisotropicDegree
        self.borderColor = borderColor
        self.borderWidth = borderWidth
        self.boundaryModeR = boundaryModeR
        self.boundaryModeS = boundaryModeS
        self.boundaryModeT = boundaryModeT
        self.generateMipMaps = generateMipMaps
        self.magnificationFilter = magnificationFilter
        self.minificationFilter = minificationFilter
        self.textureCompression = textureCompression
        self.texturePriority = texturePriority
    @property # getter - - - - - - - - - -
    def anisotropicDegree(self):
        """[1,+infinity) anisotropicDegree defines minimum degree of anisotropy to account for in texture filtering (1=no effect for symmetric filtering, otherwise provide higher value)."""
        return self.__anisotropicDegree
    @anisotropicDegree.setter
    def anisotropicDegree(self, anisotropicDegree=None):
        if  anisotropicDegree is None:
            anisotropicDegree = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(anisotropicDegree)
        assertGreaterThanEquals('anisotropicDegree', anisotropicDegree, 1)
        self.__anisotropicDegree = anisotropicDegree
    @property # getter - - - - - - - - - -
    def borderColor(self):
        """[0,1] borderColor defines border pixel color."""
        return self.__borderColor
    @borderColor.setter
    def borderColor(self, borderColor=None):
        if  borderColor is None:
            borderColor = SFColorRGBA.DEFAULT_VALUE
        assertValidSFColorRGBA(borderColor)
        assertZeroToOne('borderColor', borderColor)
        self.__borderColor = borderColor
    @property # getter - - - - - - - - - -
    def borderWidth(self):
        """[0,+infinity) borderWidth number of pixels for texture border."""
        return self.__borderWidth
    @borderWidth.setter
    def borderWidth(self, borderWidth=None):
        if  borderWidth is None:
            borderWidth = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(borderWidth)
        assertNonNegative('borderWidth', borderWidth)
        self.__borderWidth = borderWidth
    @property # getter - - - - - - - - - -
    def boundaryModeR(self):
        """boundaryModeR describes handling of texture-coordinate boundaries."""
        return self.__boundaryModeR
    @boundaryModeR.setter
    def boundaryModeR(self, boundaryModeR=None):
        if  boundaryModeR is None:
            boundaryModeR = SFString.DEFAULT_VALUE
        assertValidSFString(boundaryModeR)
        self.__boundaryModeR = boundaryModeR
    @property # getter - - - - - - - - - -
    def boundaryModeS(self):
        """boundaryModeS describes handling of texture-coordinate boundaries."""
        return self.__boundaryModeS
    @boundaryModeS.setter
    def boundaryModeS(self, boundaryModeS=None):
        if  boundaryModeS is None:
            boundaryModeS = SFString.DEFAULT_VALUE
        assertValidSFString(boundaryModeS)
        self.__boundaryModeS = boundaryModeS
    @property # getter - - - - - - - - - -
    def boundaryModeT(self):
        """boundaryModeT describes handling of texture-coordinate boundaries."""
        return self.__boundaryModeT
    @boundaryModeT.setter
    def boundaryModeT(self, boundaryModeT=None):
        if  boundaryModeT is None:
            boundaryModeT = SFString.DEFAULT_VALUE
        assertValidSFString(boundaryModeT)
        self.__boundaryModeT = boundaryModeT
    @property # getter - - - - - - - - - -
    def generateMipMaps(self):
        """Determines whether MIPMAPs are generated for texture images."""
        return self.__generateMipMaps
    @generateMipMaps.setter
    def generateMipMaps(self, generateMipMaps=None):
        if  generateMipMaps is None:
            generateMipMaps = SFBool.DEFAULT_VALUE
        assertValidSFBool(generateMipMaps)
        self.__generateMipMaps = generateMipMaps
    @property # getter - - - - - - - - - -
    def magnificationFilter(self):
        """magnificationFilter indicates texture filter when image is smaller than screen space representation."""
        return self.__magnificationFilter
    @magnificationFilter.setter
    def magnificationFilter(self, magnificationFilter=None):
        if  magnificationFilter is None:
            magnificationFilter = SFString.DEFAULT_VALUE
        assertValidSFString(magnificationFilter)
        self.__magnificationFilter = magnificationFilter
    @property # getter - - - - - - - - - -
    def minificationFilter(self):
        """minificationFilter indicates texture filter when image is larger than screen space representation."""
        return self.__minificationFilter
    @minificationFilter.setter
    def minificationFilter(self, minificationFilter=None):
        if  minificationFilter is None:
            minificationFilter = SFString.DEFAULT_VALUE
        assertValidSFString(minificationFilter)
        self.__minificationFilter = minificationFilter
    @property # getter - - - - - - - - - -
    def textureCompression(self):
        """textureCompression indicates compression algorithm selection mode."""
        return self.__textureCompression
    @textureCompression.setter
    def textureCompression(self, textureCompression=None):
        if  textureCompression is None:
            textureCompression = SFString.DEFAULT_VALUE
        assertValidSFString(textureCompression)
        self.__textureCompression = textureCompression
    @property # getter - - - - - - - - - -
    def texturePriority(self):
        """[0,1] texturePriority defines relative priority for this texture when allocating texture memory, an important rendering resource in graphics-card hardware."""
        return self.__texturePriority
    @texturePriority.setter
    def texturePriority(self, texturePriority=None):
        if  texturePriority is None:
            texturePriority = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(texturePriority)
        assertZeroToOne('texturePriority', texturePriority)
        self.__texturePriority = texturePriority
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TextureProperties.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TextureProperties'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.anisotropicDegree != 1:
            result += " anisotropicDegree='" + SFFloat(self.anisotropicDegree).XML() + "'"
        if self.borderColor != (0, 0, 0, 0):
            result += " borderColor='" + SFColorRGBA(self.borderColor).XML() + "'"
        if self.borderWidth != 0:
            result += " borderWidth='" + SFInt32(self.borderWidth).XML() + "'"
        if self.boundaryModeR != 'REPEAT':
            result += " boundaryModeR='" + self.boundaryModeR + "'"
        if self.boundaryModeS != 'REPEAT':
            result += " boundaryModeS='" + self.boundaryModeS + "'"
        if self.boundaryModeT != 'REPEAT':
            result += " boundaryModeT='" + self.boundaryModeT + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.generateMipMaps != False:
            result += " generateMipMaps='" + SFBool(self.generateMipMaps).XML() + "'"
        if self.magnificationFilter != 'FASTEST':
            result += " magnificationFilter='" + self.magnificationFilter + "'"
        if self.minificationFilter != 'FASTEST':
            result += " minificationFilter='" + self.minificationFilter + "'"
        if self.textureCompression != 'FASTEST':
            result += " textureCompression='" + self.textureCompression + "'"
        if self.texturePriority != 0:
            result += " texturePriority='" + SFFloat(self.texturePriority).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TextureProperties>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TextureTransform(_X3DTextureTransformNode):
    """
    TextureTransform shifts 2D texture coordinates for positioning, orienting and scaling image textures on geometry.
    """
    NAME = 'TextureTransform'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TextureTransform'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('center', (0, 0), FieldType.SFVec2f, AccessType.inputOutput, 'TextureTransform'),
        ('rotation', 0, FieldType.SFFloat, AccessType.inputOutput, 'TextureTransform'),
        ('scale', (1, 1), FieldType.SFVec2f, AccessType.inputOutput, 'TextureTransform'),
        ('translation', (0, 0), FieldType.SFVec2f, AccessType.inputOutput, 'TextureTransform'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 center=(0, 0),
                 rotation=0,
                 scale=(1, 1),
                 translation=(0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TextureTransform __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.center = center
        self.rotation = rotation
        self.scale = scale
        self.translation = translation
    @property # getter - - - - - - - - - -
    def center(self):
        """center point in 2D (s,t) texture coordinates for rotation and scaling."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def rotation(self):
        """single rotation angle of texture about center (opposite effect appears on geometry)."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def scale(self):
        """Non-uniform planar scaling of texture about center (opposite effect appears on geometry)."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def translation(self):
        """Lateral/vertical shift in 2D (s,t) texture coordinates (opposite effect appears on geometry)."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec2f.DEFAULT_VALUE
        assertValidSFVec2f(translation)
        self.__translation = translation
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TextureTransform.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TextureTransform'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.center != (0, 0):
            result += " center='" + SFVec2f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.rotation != 0:
            result += " rotation='" + SFFloat(self.rotation).XML() + "'"
        if self.scale != (1, 1):
            result += " scale='" + SFVec2f(self.scale).XML() + "'"
        if self.translation != (0, 0):
            result += " translation='" + SFVec2f(self.translation).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TextureTransform>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TextureTransform3D(_X3DTextureTransformNode):
    """
    TextureTransform3D applies a 3D transformation to texture coordinates.
    """
    NAME = 'TextureTransform3D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TextureTransform3D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'TextureTransform3D'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'TextureTransform3D'),
        ('scale', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'TextureTransform3D'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'TextureTransform3D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 center=(0, 0, 0),
                 rotation=(0, 0, 1, 0),
                 scale=(1, 1, 1),
                 translation=(0, 0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TextureTransform3D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.center = center
        self.rotation = rotation
        self.scale = scale
        self.translation = translation
    @property # getter - - - - - - - - - -
    def center(self):
        """center point in 2D (s,t) texture coordinates for rotation and scaling."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def rotation(self):
        """rotation angle of texture about center (opposite effect appears on geometry)."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def scale(self):
        """Non-uniform planar scaling of texture about center (opposite effect appears on geometry)."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def translation(self):
        """Lateral/vertical shift in 2D (s,t) texture coordinates (opposite effect appears on geometry)."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TextureTransform3D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TextureTransform3D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.scale != (1, 1, 1):
            result += " scale='" + SFVec3f(self.scale).XML() + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TextureTransform3D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TextureTransformMatrix3D(_X3DTextureTransformNode):
    """
    TextureTransformMatrix3D applies a 3D transformation to texture coordinates.
    """
    NAME = 'TextureTransformMatrix3D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TextureTransformMatrix3D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('matrix', (1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1), FieldType.SFMatrix4f, AccessType.inputOutput, 'TextureTransformMatrix3D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 matrix=(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TextureTransformMatrix3D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.matrix = matrix
    @property # getter - - - - - - - - - -
    def matrix(self):
        """matrix is a generalized, unfiltered 4x4 transformation matrix to modify texture (opposite effect appears on geometry)."""
        return self.__matrix
    @matrix.setter
    def matrix(self, matrix=None):
        if  matrix is None:
            matrix = SFMatrix4f.DEFAULT_VALUE
        assertValidSFMatrix4f(matrix)
        self.__matrix = matrix
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TextureTransformMatrix3D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TextureTransformMatrix3D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.matrix != (1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1):
            result += " matrix='" + SFMatrix4f(self.matrix).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TextureTransformMatrix3D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TimeSensor(_X3DTimeDependentNode, _X3DSensorNode):
    """
    TimeSensor continuously generates events as time passes.
    """
    NAME = 'TimeSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TimeSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('cycleInterval', 1.0, FieldType.SFTime, AccessType.inputOutput, 'TimeSensor'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('loop', False, FieldType.SFBool, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('pauseTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('resumeTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('startTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('stopTime', 0, FieldType.SFTime, AccessType.inputOutput, 'X3DTimeDependentNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 cycleInterval=1.0,
                 enabled=True,
                 loop=False,
                 pauseTime=0,
                 resumeTime=0,
                 startTime=0,
                 stopTime=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TimeSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.cycleInterval = cycleInterval
        self.enabled = enabled
        self.loop = loop
        self.pauseTime = pauseTime
        self.resumeTime = resumeTime
        self.startTime = startTime
        self.stopTime = stopTime
    @property # getter - - - - - - - - - -
    def cycleInterval(self):
        """[0,+infinity) cycleInterval is loop duration in seconds."""
        return self.__cycleInterval
    @cycleInterval.setter
    def cycleInterval(self, cycleInterval=None):
        if  cycleInterval is None:
            cycleInterval = SFTime.DEFAULT_VALUE
        assertValidSFTime(cycleInterval)
        assertNonNegative('cycleInterval', cycleInterval)
        self.__cycleInterval = cycleInterval
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def loop(self):
        """Repeat indefinitely when loop=true, repeat only once when loop=false."""
        return self.__loop
    @loop.setter
    def loop(self, loop=None):
        if  loop is None:
            loop = SFBool.DEFAULT_VALUE
        assertValidSFBool(loop)
        self.__loop = loop
    @property # getter - - - - - - - - - -
    def pauseTime(self):
        """When time now >= pauseTime, isPaused becomes true and TimeSensor becomes paused."""
        return self.__pauseTime
    @pauseTime.setter
    def pauseTime(self, pauseTime=None):
        if  pauseTime is None:
            pauseTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(pauseTime)
        self.__pauseTime = pauseTime
    @property # getter - - - - - - - - - -
    def resumeTime(self):
        """When resumeTime becomes <= time now, isPaused becomes false and TimeSensor becomes inactive."""
        return self.__resumeTime
    @resumeTime.setter
    def resumeTime(self, resumeTime=None):
        if  resumeTime is None:
            resumeTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(resumeTime)
        self.__resumeTime = resumeTime
    @property # getter - - - - - - - - - -
    def startTime(self):
        """When time now >= startTime, isActive becomes true and TimeSensor becomes active."""
        return self.__startTime
    @startTime.setter
    def startTime(self, startTime=None):
        if  startTime is None:
            startTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(startTime)
        self.__startTime = startTime
    @property # getter - - - - - - - - - -
    def stopTime(self):
        """When stopTime becomes <= time now, isActive becomes false and TimeSensor becomes inactive."""
        return self.__stopTime
    @stopTime.setter
    def stopTime(self, stopTime=None):
        if  stopTime is None:
            stopTime = SFTime.DEFAULT_VALUE
        assertValidSFTime(stopTime)
        self.__stopTime = stopTime
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TimeSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TimeSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.cycleInterval != 1.0:
            result += " cycleInterval='" + SFTime(self.cycleInterval).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.loop != False:
            result += " loop='" + SFBool(self.loop).XML() + "'"
        if self.pauseTime != 0:
            result += " pauseTime='" + SFTime(self.pauseTime).XML() + "'"
        if self.resumeTime != 0:
            result += " resumeTime='" + SFTime(self.resumeTime).XML() + "'"
        if self.startTime != 0:
            result += " startTime='" + SFTime(self.startTime).XML() + "'"
        if self.stopTime != 0:
            result += " stopTime='" + SFTime(self.stopTime).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TimeSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TimeTrigger(_X3DTriggerNode):
    """
    TimeTrigger converts boolean true events to time events.
    """
    NAME = 'TimeTrigger'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TimeTrigger'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TimeTrigger __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TimeTrigger.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TimeTrigger'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TimeTrigger>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ToneMappedVolumeStyle(_X3DComposableVolumeRenderStyleNode):
    """
    ToneMappedVolumeStyle specifies that volumetric data is rendered with Gooch shading model of two-toned warm/cool coloring.
    """
    NAME = 'ToneMappedVolumeStyle'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ToneMappedVolumeStyle'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('coolColor', (0, 0, 1, 0), FieldType.SFColorRGBA, AccessType.inputOutput, 'ToneMappedVolumeStyle'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeRenderStyleNode'),
        ('warmColor', (1, 1, 0, 0), FieldType.SFColorRGBA, AccessType.inputOutput, 'ToneMappedVolumeStyle'),
        ('surfaceNormals', None, FieldType.SFNode, AccessType.inputOutput, 'ToneMappedVolumeStyle'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 coolColor=(0, 0, 1, 0),
                 enabled=True,
                 warmColor=(1, 1, 0, 0),
                 surfaceNormals=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ToneMappedVolumeStyle __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.coolColor = coolColor
        self.enabled = enabled
        self.warmColor = warmColor
        self.surfaceNormals = surfaceNormals
    @property # getter - - - - - - - - - -
    def coolColor(self):
        """[0,1] coolColor is used for surfaces facing away from the light direction."""
        return self.__coolColor
    @coolColor.setter
    def coolColor(self, coolColor=None):
        if  coolColor is None:
            coolColor = SFColorRGBA.DEFAULT_VALUE
        assertValidSFColorRGBA(coolColor)
        assertZeroToOne('coolColor', coolColor)
        self.__coolColor = coolColor
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def warmColor(self):
        """[0,1] warmColor is used for surfaces facing towards the light."""
        return self.__warmColor
    @warmColor.setter
    def warmColor(self, warmColor=None):
        if  warmColor is None:
            warmColor = SFColorRGBA.DEFAULT_VALUE
        assertValidSFColorRGBA(warmColor)
        assertZeroToOne('warmColor', warmColor)
        self.__warmColor = warmColor
    @property # getter - - - - - - - - - -
    def surfaceNormals(self):
        return self.__surfaceNormals
    @surfaceNormals.setter
    def surfaceNormals(self, surfaceNormals=None):
        if  surfaceNormals is None:
            surfaceNormals = SFNode.DEFAULT_VALUE
        assertValidSFNode(surfaceNormals)
        if not isinstance(surfaceNormals, object):
            # print(flush=True)
            raise X3DTypeError(str(surfaceNormals) + ' does not have a valid node type object')
        self.__surfaceNormals = surfaceNormals
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.surfaceNormals)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ToneMappedVolumeStyle.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ToneMappedVolumeStyle'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.coolColor != (0, 0, 1, 0):
            result += " coolColor='" + SFColorRGBA(self.coolColor).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.warmColor != (1, 1, 0, 0):
            result += " warmColor='" + SFColorRGBA(self.warmColor).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.surfaceNormals: # output this SFNode
                result += self.surfaceNormals.XML(indentLevel=indentLevel+1)
            result += indent + '</ToneMappedVolumeStyle>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TouchSensor(_X3DTouchSensorNode):
    """
    TouchSensor tracks location and state of the pointing device, detecting when a user points at or selects (activates) geometry.
    """
    NAME = 'TouchSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TouchSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DPointingDeviceSensorNode'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 description='',
                 enabled=True,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TouchSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.description = description
        self.enabled = enabled
    @property # getter - - - - - - - - - -
    def description(self):
        """Author-provided text tooltip that tells users the expected action of this node."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TouchSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TouchSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TouchSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Transform(_X3DGroupingNode):
    """
    Transform is a Grouping node that can contain most nodes.
    """
    NAME = 'Transform'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Transform'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'Transform'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('rotation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'Transform'),
        ('scale', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'Transform'),
        ('scaleOrientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'Transform'),
        ('translation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'Transform'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 center=(0, 0, 0),
                 displayBBox=False,
                 rotation=(0, 0, 1, 0),
                 scale=(1, 1, 1),
                 scaleOrientation=(0, 0, 1, 0),
                 translation=(0, 0, 0),
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Transform __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.center = center
        self.displayBBox = displayBBox
        self.rotation = rotation
        self.scale = scale
        self.scaleOrientation = scaleOrientation
        self.translation = translation
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def center(self):
        """Translation offset from origin of local coordinate system, applied prior to rotation or scaling."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def rotation(self):
        """Orientation (axis, angle in radians) of children relative to local coordinate system."""
        return self.__rotation
    @rotation.setter
    def rotation(self, rotation=None):
        if  rotation is None:
            rotation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(rotation)
        self.__rotation = rotation
    @property # getter - - - - - - - - - -
    def scale(self):
        """Non-uniform x-y-z scale of child coordinate system, adjusted by center and scaleOrientation."""
        return self.__scale
    @scale.setter
    def scale(self, scale=None):
        if  scale is None:
            scale = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(scale)
        self.__scale = scale
    @property # getter - - - - - - - - - -
    def scaleOrientation(self):
        """Preliminary rotation of coordinate system before scaling (to allow scaling around arbitrary orientations)."""
        return self.__scaleOrientation
    @scaleOrientation.setter
    def scaleOrientation(self, scaleOrientation=None):
        if  scaleOrientation is None:
            scaleOrientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(scaleOrientation)
        self.__scaleOrientation = scaleOrientation
    @property # getter - - - - - - - - - -
    def translation(self):
        """Position (x, y, z in meters) of children relative to local coordinate system."""
        return self.__translation
    @translation.setter
    def translation(self, translation=None):
        if  translation is None:
            translation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(translation)
        self.__translation = translation
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Transform.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Transform'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.rotation != (0, 0, 1, 0):
            result += " rotation='" + SFRotation(self.rotation).XML() + "'"
        if self.scale != (1, 1, 1):
            result += " scale='" + SFVec3f(self.scale).XML() + "'"
        if self.scaleOrientation != (0, 0, 1, 0):
            result += " scaleOrientation='" + SFRotation(self.scaleOrientation).XML() + "'"
        if self.translation != (0, 0, 0):
            result += " translation='" + SFVec3f(self.translation).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Transform>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TransformSensor(_X3DEnvironmentalSensorNode):
    """
    TransformSensor generates output events when its targetObject enters, exits, and moves within a region in space (defined by a box).
    """
    NAME = 'TransformSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TransformSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'TransformSensor'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('size', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DEnvironmentalSensorNode'),
        ('targetObject', None, FieldType.SFNode, AccessType.inputOutput, 'TransformSensor'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 center=(0, 0, 0),
                 enabled=True,
                 size=(0, 0, 0),
                 targetObject=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TransformSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.center = center
        self.enabled = enabled
        self.size = size
        self.targetObject = targetObject
    @property # getter - - - - - - - - - -
    def center(self):
        """Translation offset from origin of local coordinate system."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def size(self):
        """[0,+infinity) size of intersection box, measured from center in meters."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(size)
        assertNonNegative('size', size)
        self.__size = size
    @property # getter - - - - - - - - - -
    def targetObject(self):
        """[X3DGroupingNode|X3DShapeNode] targetObject is the movable geometry represented by any valid X3DGroupingNode or X3DShapeNode which may enter or exit the box."""
        return self.__targetObject
    @targetObject.setter
    def targetObject(self, targetObject=None):
        if  targetObject is None:
            targetObject = SFNode.DEFAULT_VALUE
        assertValidSFNode(targetObject)
        if not isinstance(targetObject, object):
            # print(flush=True)
            raise X3DTypeError(str(targetObject) + ' does not have a valid node type object')
        self.__targetObject = targetObject
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.targetObject)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TransformSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TransformSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.size != (0, 0, 0):
            result += " size='" + SFVec3f(self.size).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.targetObject: # output this SFNode
                result += self.targetObject.XML(indentLevel=indentLevel+1)
            result += indent + '</TransformSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TransmitterPdu(_X3DNetworkSensorNode, _X3DBoundedObject):
    """
    TransmitterPdu is a networked Protocol Data Unit (PDU) information node that provides detailed information about a radio transmitter modeled in a simulation.
    """
    NAME = 'TransmitterPdu'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TransmitterPdu'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('address', 'localhost', FieldType.SFString, AccessType.inputOutput, 'TransmitterPdu'),
        ('antennaLocation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'TransmitterPdu'),
        ('antennaPatternLength', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('antennaPatternType', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('applicationID', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DBoundedObject'),
        ('cryptoKeyID', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('cryptoSystem', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('entityID', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('frequency', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('geoCoords', (0, 0, 0), FieldType.SFVec3d, AccessType.inputOutput, 'TransmitterPdu'),
        ('geoSystem', ["GD", "WE"], FieldType.MFString, AccessType.initializeOnly, 'TransmitterPdu'),
        ('inputSource', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('lengthOfModulationParameters', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('modulationTypeDetail', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('modulationTypeMajor', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('modulationTypeSpreadSpectrum', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('modulationTypeSystem', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('multicastRelayHost', '', FieldType.SFString, AccessType.inputOutput, 'TransmitterPdu'),
        ('multicastRelayPort', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('networkMode', 'standAlone', FieldType.SFString, AccessType.inputOutput, 'TransmitterPdu'),
        ('port', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('power', 0.0, FieldType.SFFloat, AccessType.inputOutput, 'TransmitterPdu'),
        ('radioEntityTypeCategory', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('radioEntityTypeCountry', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('radioEntityTypeDomain', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('radioEntityTypeKind', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('radioEntityTypeNomenclature', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('radioEntityTypeNomenclatureVersion', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('radioID', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('readInterval', 0.1, FieldType.SFTime, AccessType.inputOutput, 'TransmitterPdu'),
        ('relativeAntennaLocation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'TransmitterPdu'),
        ('rtpHeaderExpected', False, FieldType.SFBool, AccessType.initializeOnly, 'TransmitterPdu'),
        ('siteID', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('transmitFrequencyBandwidth', 0, FieldType.SFFloat, AccessType.inputOutput, 'TransmitterPdu'),
        ('transmitState', 0, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DBoundedObject'),
        ('whichGeometry', 1, FieldType.SFInt32, AccessType.inputOutput, 'TransmitterPdu'),
        ('writeInterval', 1.0, FieldType.SFTime, AccessType.inputOutput, 'TransmitterPdu'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 address='localhost',
                 antennaLocation=(0, 0, 0),
                 antennaPatternLength=0,
                 antennaPatternType=0,
                 applicationID=0,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 cryptoKeyID=0,
                 cryptoSystem=0,
                 displayBBox=False,
                 enabled=True,
                 entityID=0,
                 frequency=0,
                 geoCoords=(0, 0, 0),
                 geoSystem=["GD", "WE"],
                 inputSource=0,
                 lengthOfModulationParameters=0,
                 modulationTypeDetail=0,
                 modulationTypeMajor=0,
                 modulationTypeSpreadSpectrum=0,
                 modulationTypeSystem=0,
                 multicastRelayHost='',
                 multicastRelayPort=0,
                 networkMode='standAlone',
                 port=0,
                 power=0.0,
                 radioEntityTypeCategory=0,
                 radioEntityTypeCountry=0,
                 radioEntityTypeDomain=0,
                 radioEntityTypeKind=0,
                 radioEntityTypeNomenclature=0,
                 radioEntityTypeNomenclatureVersion=0,
                 radioID=0,
                 readInterval=0.1,
                 relativeAntennaLocation=(0, 0, 0),
                 rtpHeaderExpected=False,
                 siteID=0,
                 transmitFrequencyBandwidth=0,
                 transmitState=0,
                 visible=True,
                 whichGeometry=1,
                 writeInterval=1.0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TransmitterPdu __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.address = address
        self.antennaLocation = antennaLocation
        self.antennaPatternLength = antennaPatternLength
        self.antennaPatternType = antennaPatternType
        self.applicationID = applicationID
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.cryptoKeyID = cryptoKeyID
        self.cryptoSystem = cryptoSystem
        self.displayBBox = displayBBox
        self.enabled = enabled
        self.entityID = entityID
        self.frequency = frequency
        self.geoCoords = geoCoords
        self.geoSystem = geoSystem
        self.inputSource = inputSource
        self.lengthOfModulationParameters = lengthOfModulationParameters
        self.modulationTypeDetail = modulationTypeDetail
        self.modulationTypeMajor = modulationTypeMajor
        self.modulationTypeSpreadSpectrum = modulationTypeSpreadSpectrum
        self.modulationTypeSystem = modulationTypeSystem
        self.multicastRelayHost = multicastRelayHost
        self.multicastRelayPort = multicastRelayPort
        self.networkMode = networkMode
        self.port = port
        self.power = power
        self.radioEntityTypeCategory = radioEntityTypeCategory
        self.radioEntityTypeCountry = radioEntityTypeCountry
        self.radioEntityTypeDomain = radioEntityTypeDomain
        self.radioEntityTypeKind = radioEntityTypeKind
        self.radioEntityTypeNomenclature = radioEntityTypeNomenclature
        self.radioEntityTypeNomenclatureVersion = radioEntityTypeNomenclatureVersion
        self.radioID = radioID
        self.readInterval = readInterval
        self.relativeAntennaLocation = relativeAntennaLocation
        self.rtpHeaderExpected = rtpHeaderExpected
        self.siteID = siteID
        self.transmitFrequencyBandwidth = transmitFrequencyBandwidth
        self.transmitState = transmitState
        self.visible = visible
        self.whichGeometry = whichGeometry
        self.writeInterval = writeInterval
    @property # getter - - - - - - - - - -
    def address(self):
        """Multicast network address, or else "localhost" example: 224."""
        return self.__address
    @address.setter
    def address(self, address=None):
        if  address is None:
            address = SFString.DEFAULT_VALUE
        assertValidSFString(address)
        self.__address = address
    @property # getter - - - - - - - - - -
    def antennaLocation(self):
        """World coordinates for antenna location."""
        return self.__antennaLocation
    @antennaLocation.setter
    def antennaLocation(self, antennaLocation=None):
        if  antennaLocation is None:
            antennaLocation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(antennaLocation)
        self.__antennaLocation = antennaLocation
    @property # getter - - - - - - - - - -
    def antennaPatternLength(self):
        """."""
        return self.__antennaPatternLength
    @antennaPatternLength.setter
    def antennaPatternLength(self, antennaPatternLength=None):
        if  antennaPatternLength is None:
            antennaPatternLength = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(antennaPatternLength)
        self.__antennaPatternLength = antennaPatternLength
    @property # getter - - - - - - - - - -
    def antennaPatternType(self):
        """Antenna shape pattern: 0 for omnidirectional, 1 for beam, 2 for spherical harmonic (deprecated), or optional higher value."""
        return self.__antennaPatternType
    @antennaPatternType.setter
    def antennaPatternType(self, antennaPatternType=None):
        if  antennaPatternType is None:
            antennaPatternType = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(antennaPatternType)
        self.__antennaPatternType = antennaPatternType
    @property # getter - - - - - - - - - -
    def applicationID(self):
        """Each simulation application that can respond to simulation management PDUs needs to have a unique applicationID."""
        return self.__applicationID
    @applicationID.setter
    def applicationID(self, applicationID=None):
        if  applicationID is None:
            applicationID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(applicationID)
        self.__applicationID = applicationID
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def cryptoKeyID(self):
        """Nonzero value corresponding to the simulated cryptographic key."""
        return self.__cryptoKeyID
    @cryptoKeyID.setter
    def cryptoKeyID(self, cryptoKeyID=None):
        if  cryptoKeyID is None:
            cryptoKeyID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(cryptoKeyID)
        self.__cryptoKeyID = cryptoKeyID
    @property # getter - - - - - - - - - -
    def cryptoSystem(self):
        """Indicates type of crypto system being used, even if the encryption equipment is not keyed."""
        return self.__cryptoSystem
    @cryptoSystem.setter
    def cryptoSystem(self, cryptoSystem=None):
        if  cryptoSystem is None:
            cryptoSystem = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(cryptoSystem)
        self.__cryptoSystem = cryptoSystem
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables the sensor node."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def entityID(self):
        """EntityID unique ID for entity within that application."""
        return self.__entityID
    @entityID.setter
    def entityID(self, entityID=None):
        if  entityID is None:
            entityID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(entityID)
        self.__entityID = entityID
    @property # getter - - - - - - - - - -
    def frequency(self):
        """Transmission frequency in Hz."""
        return self.__frequency
    @frequency.setter
    def frequency(self, frequency=None):
        if  frequency is None:
            frequency = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(frequency)
        self.__frequency = frequency
    @property # getter - - - - - - - - - -
    def geoCoords(self):
        """Geographic location (specified in current geoSystem coordinates) for children geometry (specified in relative coordinate system, in meters)."""
        return self.__geoCoords
    @geoCoords.setter
    def geoCoords(self, geoCoords=None):
        if  geoCoords is None:
            geoCoords = SFVec3d.DEFAULT_VALUE
        assertValidSFVec3d(geoCoords)
        self.__geoCoords = geoCoords
    @property # getter - - - - - - - - - -
    def geoSystem(self):
        """Identifies spatial reference frame: Geodetic (GD), Geocentric (GC), Universal Transverse Mercator (UTM)."""
        return self.__geoSystem
    @geoSystem.setter
    def geoSystem(self, geoSystem=None):
        if  geoSystem is None:
            geoSystem = MFString.DEFAULT_VALUE
        assertValidMFString(geoSystem)
        self.__geoSystem = geoSystem
    @property # getter - - - - - - - - - -
    def inputSource(self):
        """Source of transmission input."""
        return self.__inputSource
    @inputSource.setter
    def inputSource(self, inputSource=None):
        if  inputSource is None:
            inputSource = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(inputSource)
        self.__inputSource = inputSource
    @property # getter - - - - - - - - - -
    def lengthOfModulationParameters(self):
        """."""
        return self.__lengthOfModulationParameters
    @lengthOfModulationParameters.setter
    def lengthOfModulationParameters(self, lengthOfModulationParameters=None):
        if  lengthOfModulationParameters is None:
            lengthOfModulationParameters = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(lengthOfModulationParameters)
        self.__lengthOfModulationParameters = lengthOfModulationParameters
    @property # getter - - - - - - - - - -
    def modulationTypeDetail(self):
        """Integer enumeration containing detailed information depending on the major modulation type."""
        return self.__modulationTypeDetail
    @modulationTypeDetail.setter
    def modulationTypeDetail(self, modulationTypeDetail=None):
        if  modulationTypeDetail is None:
            modulationTypeDetail = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(modulationTypeDetail)
        self.__modulationTypeDetail = modulationTypeDetail
    @property # getter - - - - - - - - - -
    def modulationTypeMajor(self):
        """Integer enumeration containing major classification of the modulation type."""
        return self.__modulationTypeMajor
    @modulationTypeMajor.setter
    def modulationTypeMajor(self, modulationTypeMajor=None):
        if  modulationTypeMajor is None:
            modulationTypeMajor = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(modulationTypeMajor)
        self.__modulationTypeMajor = modulationTypeMajor
    @property # getter - - - - - - - - - -
    def modulationTypeSpreadSpectrum(self):
        """Indicates the spread spectrum technique or combination of spread spectrum techniques in use."""
        return self.__modulationTypeSpreadSpectrum
    @modulationTypeSpreadSpectrum.setter
    def modulationTypeSpreadSpectrum(self, modulationTypeSpreadSpectrum=None):
        if  modulationTypeSpreadSpectrum is None:
            modulationTypeSpreadSpectrum = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(modulationTypeSpreadSpectrum)
        self.__modulationTypeSpreadSpectrum = modulationTypeSpreadSpectrum
    @property # getter - - - - - - - - - -
    def modulationTypeSystem(self):
        """Specifies radio system associated with this Transmitter PDU and used to interpret other fields whose values depend on a specific radio system."""
        return self.__modulationTypeSystem
    @modulationTypeSystem.setter
    def modulationTypeSystem(self, modulationTypeSystem=None):
        if  modulationTypeSystem is None:
            modulationTypeSystem = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(modulationTypeSystem)
        self.__modulationTypeSystem = modulationTypeSystem
    @property # getter - - - - - - - - - -
    def multicastRelayHost(self):
        """Fallback server address if multicast not available locally."""
        return self.__multicastRelayHost
    @multicastRelayHost.setter
    def multicastRelayHost(self, multicastRelayHost=None):
        if  multicastRelayHost is None:
            multicastRelayHost = SFString.DEFAULT_VALUE
        assertValidSFString(multicastRelayHost)
        self.__multicastRelayHost = multicastRelayHost
    @property # getter - - - - - - - - - -
    def multicastRelayPort(self):
        """Fallback server port if multicast not available locally."""
        return self.__multicastRelayPort
    @multicastRelayPort.setter
    def multicastRelayPort(self, multicastRelayPort=None):
        if  multicastRelayPort is None:
            multicastRelayPort = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(multicastRelayPort)
        self.__multicastRelayPort = multicastRelayPort
    @property # getter - - - - - - - - - -
    def networkMode(self):
        """Whether this entity is ignoring the network, sending DIS packets to the network, or receiving DIS packets from the network."""
        return self.__networkMode
    @networkMode.setter
    def networkMode(self, networkMode=None):
        if  networkMode is None:
            networkMode = SFString.DEFAULT_VALUE
        assertValidSFString(networkMode)
        self.__networkMode = networkMode
    @property # getter - - - - - - - - - -
    def port(self):
        """Multicast network port, for example: 3000."""
        return self.__port
    @port.setter
    def port(self, port=None):
        if  port is None:
            port = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(port)
        self.__port = port
    @property # getter - - - - - - - - - -
    def power(self):
        """Power that radio would be capable of outputting if on and transmitting, independent of actual transmit state of the radio."""
        return self.__power
    @power.setter
    def power(self, power=None):
        if  power is None:
            power = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(power)
        self.__power = power
    @property # getter - - - - - - - - - -
    def radioEntityTypeCategory(self):
        """Integer enumeration containing EntityType of transmitter radio."""
        return self.__radioEntityTypeCategory
    @radioEntityTypeCategory.setter
    def radioEntityTypeCategory(self, radioEntityTypeCategory=None):
        if  radioEntityTypeCategory is None:
            radioEntityTypeCategory = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(radioEntityTypeCategory)
        self.__radioEntityTypeCategory = radioEntityTypeCategory
    @property # getter - - - - - - - - - -
    def radioEntityTypeCountry(self):
        """Integer enumerations value for country to which the design of the entity or its design specification is attributed."""
        return self.__radioEntityTypeCountry
    @radioEntityTypeCountry.setter
    def radioEntityTypeCountry(self, radioEntityTypeCountry=None):
        if  radioEntityTypeCountry is None:
            radioEntityTypeCountry = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(radioEntityTypeCountry)
        self.__radioEntityTypeCountry = radioEntityTypeCountry
    @property # getter - - - - - - - - - -
    def radioEntityTypeDomain(self):
        """Integer enumerations value for domain in which the entity operates: LAND, AIR, SURFACE, SUBSURFACE, SPACE or OTHER."""
        return self.__radioEntityTypeDomain
    @radioEntityTypeDomain.setter
    def radioEntityTypeDomain(self, radioEntityTypeDomain=None):
        if  radioEntityTypeDomain is None:
            radioEntityTypeDomain = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(radioEntityTypeDomain)
        self.__radioEntityTypeDomain = radioEntityTypeDomain
    @property # getter - - - - - - - - - -
    def radioEntityTypeKind(self):
        """Integer enumerations value for whether entity is a PLATFORM, MUNITION, LIFE_FORM, ENVIRONMENTAL, CULTURAL_FEATURE, SUPPLY, RADIO, EXPENDABLE, SENSOR_EMITTER or OTHER."""
        return self.__radioEntityTypeKind
    @radioEntityTypeKind.setter
    def radioEntityTypeKind(self, radioEntityTypeKind=None):
        if  radioEntityTypeKind is None:
            radioEntityTypeKind = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(radioEntityTypeKind)
        self.__radioEntityTypeKind = radioEntityTypeKind
    @property # getter - - - - - - - - - -
    def radioEntityTypeNomenclature(self):
        """Integer enumerations value indicating nomenclature (name) for a particular emitter."""
        return self.__radioEntityTypeNomenclature
    @radioEntityTypeNomenclature.setter
    def radioEntityTypeNomenclature(self, radioEntityTypeNomenclature=None):
        if  radioEntityTypeNomenclature is None:
            radioEntityTypeNomenclature = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(radioEntityTypeNomenclature)
        self.__radioEntityTypeNomenclature = radioEntityTypeNomenclature
    @property # getter - - - - - - - - - -
    def radioEntityTypeNomenclatureVersion(self):
        """Named equipment version number."""
        return self.__radioEntityTypeNomenclatureVersion
    @radioEntityTypeNomenclatureVersion.setter
    def radioEntityTypeNomenclatureVersion(self, radioEntityTypeNomenclatureVersion=None):
        if  radioEntityTypeNomenclatureVersion is None:
            radioEntityTypeNomenclatureVersion = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(radioEntityTypeNomenclatureVersion)
        self.__radioEntityTypeNomenclatureVersion = radioEntityTypeNomenclatureVersion
    @property # getter - - - - - - - - - -
    def radioID(self):
        """Identifies a particular radio within a given entity."""
        return self.__radioID
    @radioID.setter
    def radioID(self, radioID=None):
        if  radioID is None:
            radioID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(radioID)
        self.__radioID = radioID
    @property # getter - - - - - - - - - -
    def readInterval(self):
        """[0,+infinity) Seconds between read updates, 0 means no reading."""
        return self.__readInterval
    @readInterval.setter
    def readInterval(self, readInterval=None):
        if  readInterval is None:
            readInterval = SFTime.DEFAULT_VALUE
        assertValidSFTime(readInterval)
        assertNonNegative('readInterval', readInterval)
        self.__readInterval = readInterval
    @property # getter - - - - - - - - - -
    def relativeAntennaLocation(self):
        """Relative coordinates for antenna location."""
        return self.__relativeAntennaLocation
    @relativeAntennaLocation.setter
    def relativeAntennaLocation(self, relativeAntennaLocation=None):
        if  relativeAntennaLocation is None:
            relativeAntennaLocation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(relativeAntennaLocation)
        self.__relativeAntennaLocation = relativeAntennaLocation
    @property # getter - - - - - - - - - -
    def rtpHeaderExpected(self):
        """Whether RTP headers are prepended to DIS PDUs."""
        return self.__rtpHeaderExpected
    @rtpHeaderExpected.setter
    def rtpHeaderExpected(self, rtpHeaderExpected=None):
        if  rtpHeaderExpected is None:
            rtpHeaderExpected = SFBool.DEFAULT_VALUE
        assertValidSFBool(rtpHeaderExpected)
        self.__rtpHeaderExpected = rtpHeaderExpected
    @property # getter - - - - - - - - - -
    def siteID(self):
        """Simulation/exercise siteID of the participating LAN or organization."""
        return self.__siteID
    @siteID.setter
    def siteID(self, siteID=None):
        if  siteID is None:
            siteID = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(siteID)
        self.__siteID = siteID
    @property # getter - - - - - - - - - -
    def transmitFrequencyBandwidth(self):
        """Bandwidth of the particular transmitter measured between the half-power (-3 dB) points (this value represents total bandwidth, not the deviation from the center frequency)."""
        return self.__transmitFrequencyBandwidth
    @transmitFrequencyBandwidth.setter
    def transmitFrequencyBandwidth(self, transmitFrequencyBandwidth=None):
        if  transmitFrequencyBandwidth is None:
            transmitFrequencyBandwidth = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(transmitFrequencyBandwidth)
        self.__transmitFrequencyBandwidth = transmitFrequencyBandwidth
    @property # getter - - - - - - - - - -
    def transmitState(self):
        """Specify radio transmission state where enumerations value 0 is for off, value 1 for powered but not transmitting, or value 1 is for powered and transmitting,."""
        return self.__transmitState
    @transmitState.setter
    def transmitState(self, transmitState=None):
        if  transmitState is None:
            transmitState = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(transmitState)
        self.__transmitState = transmitState
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def whichGeometry(self):
        """Select geometry to render: -1 for no geometry, 0 for text trace, 1 for default geometry, (optional) higher values to render different states."""
        return self.__whichGeometry
    @whichGeometry.setter
    def whichGeometry(self, whichGeometry=None):
        if  whichGeometry is None:
            whichGeometry = SFInt32.DEFAULT_VALUE
        assertValidSFInt32(whichGeometry)
        self.__whichGeometry = whichGeometry
    @property # getter - - - - - - - - - -
    def writeInterval(self):
        """[0,+infinity) Seconds between write updates, 0 means no writing (sending)."""
        return self.__writeInterval
    @writeInterval.setter
    def writeInterval(self, writeInterval=None):
        if  writeInterval is None:
            writeInterval = SFTime.DEFAULT_VALUE
        assertValidSFTime(writeInterval)
        assertNonNegative('writeInterval', writeInterval)
        self.__writeInterval = writeInterval
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TransmitterPdu.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TransmitterPdu'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.address != 'localhost':
            result += " address='" + self.address + "'"
        if self.antennaLocation != (0, 0, 0):
            result += " antennaLocation='" + SFVec3f(self.antennaLocation).XML() + "'"
        if self.antennaPatternLength != 0:
            result += " antennaPatternLength='" + SFInt32(self.antennaPatternLength).XML() + "'"
        if self.antennaPatternType != 0:
            result += " antennaPatternType='" + SFInt32(self.antennaPatternType).XML() + "'"
        if self.applicationID != 0:
            result += " applicationID='" + SFInt32(self.applicationID).XML() + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.cryptoKeyID != 0:
            result += " cryptoKeyID='" + SFInt32(self.cryptoKeyID).XML() + "'"
        if self.cryptoSystem != 0:
            result += " cryptoSystem='" + SFInt32(self.cryptoSystem).XML() + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.entityID != 0:
            result += " entityID='" + SFInt32(self.entityID).XML() + "'"
        if self.frequency != 0:
            result += " frequency='" + SFInt32(self.frequency).XML() + "'"
        if self.geoCoords != (0, 0, 0):
            result += " geoCoords='" + SFVec3d(self.geoCoords).XML() + "'"
        if self.geoSystem != ["GD", "WE"]:
            result += " geoSystem='" + MFString(self.geoSystem).XML() + "'"
        if self.inputSource != 0:
            result += " inputSource='" + SFInt32(self.inputSource).XML() + "'"
        if self.lengthOfModulationParameters != 0:
            result += " lengthOfModulationParameters='" + SFInt32(self.lengthOfModulationParameters).XML() + "'"
        if self.modulationTypeDetail != 0:
            result += " modulationTypeDetail='" + SFInt32(self.modulationTypeDetail).XML() + "'"
        if self.modulationTypeMajor != 0:
            result += " modulationTypeMajor='" + SFInt32(self.modulationTypeMajor).XML() + "'"
        if self.modulationTypeSpreadSpectrum != 0:
            result += " modulationTypeSpreadSpectrum='" + SFInt32(self.modulationTypeSpreadSpectrum).XML() + "'"
        if self.modulationTypeSystem != 0:
            result += " modulationTypeSystem='" + SFInt32(self.modulationTypeSystem).XML() + "'"
        if self.multicastRelayHost:
            result += " multicastRelayHost='" + self.multicastRelayHost + "'"
        if self.multicastRelayPort != 0:
            result += " multicastRelayPort='" + SFInt32(self.multicastRelayPort).XML() + "'"
        if self.networkMode != 'standAlone':
            result += " networkMode='" + self.networkMode + "'"
        if self.port != 0:
            result += " port='" + SFInt32(self.port).XML() + "'"
        if self.power != 0.0:
            result += " power='" + SFFloat(self.power).XML() + "'"
        if self.radioEntityTypeCategory != 0:
            result += " radioEntityTypeCategory='" + SFInt32(self.radioEntityTypeCategory).XML() + "'"
        if self.radioEntityTypeCountry != 0:
            result += " radioEntityTypeCountry='" + SFInt32(self.radioEntityTypeCountry).XML() + "'"
        if self.radioEntityTypeDomain != 0:
            result += " radioEntityTypeDomain='" + SFInt32(self.radioEntityTypeDomain).XML() + "'"
        if self.radioEntityTypeKind != 0:
            result += " radioEntityTypeKind='" + SFInt32(self.radioEntityTypeKind).XML() + "'"
        if self.radioEntityTypeNomenclature != 0:
            result += " radioEntityTypeNomenclature='" + SFInt32(self.radioEntityTypeNomenclature).XML() + "'"
        if self.radioEntityTypeNomenclatureVersion != 0:
            result += " radioEntityTypeNomenclatureVersion='" + SFInt32(self.radioEntityTypeNomenclatureVersion).XML() + "'"
        if self.radioID != 0:
            result += " radioID='" + SFInt32(self.radioID).XML() + "'"
        if self.readInterval != 0.1:
            result += " readInterval='" + SFTime(self.readInterval).XML() + "'"
        if self.relativeAntennaLocation != (0, 0, 0):
            result += " relativeAntennaLocation='" + SFVec3f(self.relativeAntennaLocation).XML() + "'"
        if self.rtpHeaderExpected != False:
            result += " rtpHeaderExpected='" + SFBool(self.rtpHeaderExpected).XML() + "'"
        if self.siteID != 0:
            result += " siteID='" + SFInt32(self.siteID).XML() + "'"
        if self.transmitFrequencyBandwidth != 0:
            result += " transmitFrequencyBandwidth='" + SFFloat(self.transmitFrequencyBandwidth).XML() + "'"
        if self.transmitState != 0:
            result += " transmitState='" + SFInt32(self.transmitState).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if self.whichGeometry != 1:
            result += " whichGeometry='" + SFInt32(self.whichGeometry).XML() + "'"
        if self.writeInterval != 1.0:
            result += " writeInterval='" + SFTime(self.writeInterval).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TransmitterPdu>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TriangleFanSet(_X3DComposedGeometryNode):
    """
    TriangleFanSet is a geometry node containing a Coordinate|CoordinateDouble node, and can also contain Color|ColorRGBA, Normal and TextureCoordinate nodes.
    """
    NAME = 'TriangleFanSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TriangleFanSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('fanCount', list(), FieldType.MFInt32, AccessType.inputOutput, 'TriangleFanSet'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 fanCount=list(),
                 normalPerVertex=True,
                 solid=True,
                 color=None,
                 coord=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TriangleFanSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.fanCount = fanCount
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color|ColorRGBA values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def fanCount(self):
        """(3,+infinity) fanCount array provides number of vertices in each fan."""
        return self.__fanCount
    @fanCount.setter
    def fanCount(self, fanCount=None):
        if  fanCount is None:
            fanCount = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(fanCount)
        assertGreaterThanEquals('fanCount', fanCount, 3)
        self.__fanCount = fanCount
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TriangleFanSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TriangleFanSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.fanCount != list():
            result += " fanCount='" + MFInt32(self.fanCount).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</TriangleFanSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TriangleSet(_X3DComposedGeometryNode):
    """
    TriangleSet is a geometry node containing a Coordinate|CoordinateDouble node, and can also contain Color|ColorRGBA, Normal and TextureCoordinate nodes.
    """
    NAME = 'TriangleSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TriangleSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 normalPerVertex=True,
                 solid=True,
                 color=None,
                 coord=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TriangleSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color|ColorRGBA values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TriangleSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TriangleSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</TriangleSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TriangleSet2D(_X3DGeometryNode):
    """
    TriangleSet2D is a geometry node that defines a set of filled 2D triangles in X-Y plane.
    """
    NAME = 'TriangleSet2D'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TriangleSet2D'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('solid', False, FieldType.SFBool, AccessType.initializeOnly, 'TriangleSet2D'),
        ('vertices', list(), FieldType.MFVec2f, AccessType.inputOutput, 'TriangleSet2D'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 solid=False,
                 vertices=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TriangleSet2D __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.solid = solid
        self.vertices = vertices
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def vertices(self):
        """2D coordinates of TriangleSet2D vertices."""
        return self.__vertices
    @vertices.setter
    def vertices(self, vertices=None):
        if  vertices is None:
            vertices = MFVec2f.DEFAULT_VALUE
        assertValidMFVec2f(vertices)
        self.__vertices = vertices
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TriangleSet2D.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TriangleSet2D'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.solid != False:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.vertices != list():
            result += " vertices='" + MFVec2f(self.vertices).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TriangleSet2D>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TriangleStripSet(_X3DComposedGeometryNode):
    """
    TriangleStripSet is a geometry node containing a Coordinate|CoordinateDouble node, and can also contain Color|ColorRGBA, Normal and TextureCoordinate nodes.
    """
    NAME = 'TriangleStripSet'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TriangleStripSet'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ccw', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('colorPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('normalPerVertex', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('solid', True, FieldType.SFBool, AccessType.initializeOnly, 'X3DComposedGeometryNode'),
        ('stripCount', list(), FieldType.MFInt32, AccessType.inputOutput, 'TriangleStripSet'),
        ('color', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('fogCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('normal', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('texCoord', None, FieldType.SFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('attrib', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DComposedGeometryNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ccw=True,
                 colorPerVertex=True,
                 normalPerVertex=True,
                 solid=True,
                 stripCount=list(),
                 color=None,
                 coord=None,
                 fogCoord=None,
                 normal=None,
                 texCoord=None,
                 attrib=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TriangleStripSet __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ccw = ccw
        self.colorPerVertex = colorPerVertex
        self.normalPerVertex = normalPerVertex
        self.solid = solid
        self.stripCount = stripCount
        self.color = color
        self.coord = coord
        self.fogCoord = fogCoord
        self.normal = normal
        self.texCoord = texCoord
        self.attrib = attrib
    @property # getter - - - - - - - - - -
    def ccw(self):
        """ccw defines clockwise/counterclockwise ordering of vertex coordinates, which in turn defines front/back orientation of polygon normals according to Right-Hand Rule (RHR)."""
        return self.__ccw
    @ccw.setter
    def ccw(self, ccw=None):
        if  ccw is None:
            ccw = SFBool.DEFAULT_VALUE
        assertValidSFBool(ccw)
        self.__ccw = ccw
    @property # getter - - - - - - - - - -
    def colorPerVertex(self):
        """Whether Color|ColorRGBA values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__colorPerVertex
    @colorPerVertex.setter
    def colorPerVertex(self, colorPerVertex=None):
        if  colorPerVertex is None:
            colorPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(colorPerVertex)
        self.__colorPerVertex = colorPerVertex
    @property # getter - - - - - - - - - -
    def normalPerVertex(self):
        """Whether Normal node vector values are applied to each point vertex (true) or to each polygon face (false)."""
        return self.__normalPerVertex
    @normalPerVertex.setter
    def normalPerVertex(self, normalPerVertex=None):
        if  normalPerVertex is None:
            normalPerVertex = SFBool.DEFAULT_VALUE
        assertValidSFBool(normalPerVertex)
        self.__normalPerVertex = normalPerVertex
    @property # getter - - - - - - - - - -
    def solid(self):
        """Setting solid true means draw only one side of polygons (backface culling on), setting solid false means draw both sides of polygons (backface culling off)."""
        return self.__solid
    @solid.setter
    def solid(self, solid=None):
        if  solid is None:
            solid = SFBool.DEFAULT_VALUE
        assertValidSFBool(solid)
        self.__solid = solid
    @property # getter - - - - - - - - - -
    def stripCount(self):
        """(3,+infinity) stripCount array provides number of vertices in each strip."""
        return self.__stripCount
    @stripCount.setter
    def stripCount(self, stripCount=None):
        if  stripCount is None:
            stripCount = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(stripCount)
        assertGreaterThanEquals('stripCount', stripCount, 3)
        self.__stripCount = stripCount
    @property # getter - - - - - - - - - -
    def color(self):
        """[X3DColorNode] Single contained Color or ColorRGBA node that specifies color values applied to corresponding vertices according to colorIndex and colorPerVertex fields."""
        return self.__color
    @color.setter
    def color(self, color=None):
        if  color is None:
            color = SFNode.DEFAULT_VALUE
        assertValidSFNode(color)
        if not isinstance(color, object):
            # print(flush=True)
            raise X3DTypeError(str(color) + ' does not have a valid node type object')
        self.__color = color
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Single contained Coordinate or CoordinateDouble node that specifies a list of vertex values."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    @property # getter - - - - - - - - - -
    def fogCoord(self):
        """[FogCoordinate] Single contained FogCoordinate node that specifies depth parameters for fog in corresponding geometry."""
        return self.__fogCoord
    @fogCoord.setter
    def fogCoord(self, fogCoord=None):
        if  fogCoord is None:
            fogCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(fogCoord)
        if not isinstance(fogCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(fogCoord) + ' does not have a valid node type object')
        self.__fogCoord = fogCoord
    @property # getter - - - - - - - - - -
    def normal(self):
        """[X3DNormalNode] Single contained Normal node that specifies perpendicular vectors for corresponding vertices to support rendering computations, applied according to the normalPerVertex field."""
        return self.__normal
    @normal.setter
    def normal(self, normal=None):
        if  normal is None:
            normal = SFNode.DEFAULT_VALUE
        assertValidSFNode(normal)
        if not isinstance(normal, object):
            # print(flush=True)
            raise X3DTypeError(str(normal) + ' does not have a valid node type object')
        self.__normal = normal
    @property # getter - - - - - - - - - -
    def texCoord(self):
        """[X3DTextureCoordinateNode] Single contained TextureCoordinate, TextureCoordinateGenerator or MultiTextureCoordinate node that specifies coordinates for texture mapping onto corresponding geometry."""
        return self.__texCoord
    @texCoord.setter
    def texCoord(self, texCoord=None):
        if  texCoord is None:
            texCoord = SFNode.DEFAULT_VALUE
        assertValidSFNode(texCoord)
        if not isinstance(texCoord, object):
            # print(flush=True)
            raise X3DTypeError(str(texCoord) + ' does not have a valid node type object')
        self.__texCoord = texCoord
    @property # getter - - - - - - - - - -
    def attrib(self):
        """[X3DVertexAttributeNode] Single contained FloatVertexAttribute node that specifies list of per-vertex attribute information for programmable shaders."""
        return self.__attrib
    @attrib.setter
    def attrib(self, attrib=None):
        if  attrib is None:
            attrib = MFNode.DEFAULT_VALUE
        assertValidMFNode(attrib)
        self.__attrib = attrib
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.attrib) or bool(self.color) or bool(self.coord) or bool(self.fogCoord) or bool(self.IS) or bool(self.metadata) or bool(self.normal) or bool(self.texCoord)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TriangleStripSet.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TriangleStripSet'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ccw != True:
            result += " ccw='" + SFBool(self.ccw).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.colorPerVertex != True:
            result += " colorPerVertex='" + SFBool(self.colorPerVertex).XML() + "'"
        if self.normalPerVertex != True:
            result += " normalPerVertex='" + SFBool(self.normalPerVertex).XML() + "'"
        if self.solid != True:
            result += " solid='" + SFBool(self.solid).XML() + "'"
        if self.stripCount != list():
            result += " stripCount='" + MFInt32(self.stripCount).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.color: # output this SFNode
                result += self.color.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.fogCoord: # output this SFNode
                result += self.fogCoord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.normal: # output this SFNode
                result += self.normal.XML(indentLevel=indentLevel+1)
            if self.texCoord: # output this SFNode
                result += self.texCoord.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.attrib: # walk each child node, if any
                for each in self.attrib:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</TriangleStripSet>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class TwoSidedMaterial(_X3DMaterialNode):
    """
    TwoSidedMaterial specifies surface rendering properties for associated geometry nodes, for outer (front) and inner (back) sides of polygons.
    """
    NAME = 'TwoSidedMaterial'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#TwoSidedMaterial'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('ambientIntensity', 0.2, FieldType.SFFloat, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('backAmbientIntensity', 0.2, FieldType.SFFloat, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('backDiffuseColor', (0.8, 0.8, 0.8), FieldType.SFColor, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('backEmissiveColor', (0, 0, 0), FieldType.SFColor, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('backShininess', 0.2, FieldType.SFFloat, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('backSpecularColor', (0, 0, 0), FieldType.SFColor, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('backTransparency', 0, FieldType.SFFloat, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('diffuseColor', (0.8, 0.8, 0.8), FieldType.SFColor, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('emissiveColor', (0, 0, 0), FieldType.SFColor, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('separateBackColor', False, FieldType.SFBool, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('shininess', 0.2, FieldType.SFFloat, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('specularColor', (0, 0, 0), FieldType.SFColor, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('transparency', 0, FieldType.SFFloat, AccessType.inputOutput, 'TwoSidedMaterial'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 ambientIntensity=0.2,
                 backAmbientIntensity=0.2,
                 backDiffuseColor=(0.8, 0.8, 0.8),
                 backEmissiveColor=(0, 0, 0),
                 backShininess=0.2,
                 backSpecularColor=(0, 0, 0),
                 backTransparency=0,
                 diffuseColor=(0.8, 0.8, 0.8),
                 emissiveColor=(0, 0, 0),
                 separateBackColor=False,
                 shininess=0.2,
                 specularColor=(0, 0, 0),
                 transparency=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode TwoSidedMaterial __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.ambientIntensity = ambientIntensity
        self.backAmbientIntensity = backAmbientIntensity
        self.backDiffuseColor = backDiffuseColor
        self.backEmissiveColor = backEmissiveColor
        self.backShininess = backShininess
        self.backSpecularColor = backSpecularColor
        self.backTransparency = backTransparency
        self.diffuseColor = diffuseColor
        self.emissiveColor = emissiveColor
        self.separateBackColor = separateBackColor
        self.shininess = shininess
        self.specularColor = specularColor
        self.transparency = transparency
    @property # getter - - - - - - - - - -
    def ambientIntensity(self):
        """[0,1] how much ambient omnidirectional light is reflected from all light sources."""
        return self.__ambientIntensity
    @ambientIntensity.setter
    def ambientIntensity(self, ambientIntensity=None):
        if  ambientIntensity is None:
            ambientIntensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(ambientIntensity)
        assertZeroToOne('ambientIntensity', ambientIntensity)
        self.__ambientIntensity = ambientIntensity
    @property # getter - - - - - - - - - -
    def backAmbientIntensity(self):
        """[0,1] how much ambient omnidirectional light is reflected from all light sources."""
        return self.__backAmbientIntensity
    @backAmbientIntensity.setter
    def backAmbientIntensity(self, backAmbientIntensity=None):
        if  backAmbientIntensity is None:
            backAmbientIntensity = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(backAmbientIntensity)
        assertZeroToOne('backAmbientIntensity', backAmbientIntensity)
        self.__backAmbientIntensity = backAmbientIntensity
    @property # getter - - - - - - - - - -
    def backDiffuseColor(self):
        """[0,1] how much direct, angle-dependent light is reflected from all light sources."""
        return self.__backDiffuseColor
    @backDiffuseColor.setter
    def backDiffuseColor(self, backDiffuseColor=None):
        if  backDiffuseColor is None:
            backDiffuseColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(backDiffuseColor)
        assertZeroToOne('backDiffuseColor', backDiffuseColor)
        self.__backDiffuseColor = backDiffuseColor
    @property # getter - - - - - - - - - -
    def backEmissiveColor(self):
        """[0,1] how much glowing light is emitted from this object."""
        return self.__backEmissiveColor
    @backEmissiveColor.setter
    def backEmissiveColor(self, backEmissiveColor=None):
        if  backEmissiveColor is None:
            backEmissiveColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(backEmissiveColor)
        assertZeroToOne('backEmissiveColor', backEmissiveColor)
        self.__backEmissiveColor = backEmissiveColor
    @property # getter - - - - - - - - - -
    def backShininess(self):
        """[0,1] Lower shininess values provide soft specular glows, while higher values result in sharper, smaller highlights."""
        return self.__backShininess
    @backShininess.setter
    def backShininess(self, backShininess=None):
        if  backShininess is None:
            backShininess = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(backShininess)
        assertZeroToOne('backShininess', backShininess)
        self.__backShininess = backShininess
    @property # getter - - - - - - - - - -
    def backSpecularColor(self):
        """[0,1] specular highlights are brightness reflections (example: shiny spots on an apple)."""
        return self.__backSpecularColor
    @backSpecularColor.setter
    def backSpecularColor(self, backSpecularColor=None):
        if  backSpecularColor is None:
            backSpecularColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(backSpecularColor)
        assertZeroToOne('backSpecularColor', backSpecularColor)
        self.__backSpecularColor = backSpecularColor
    @property # getter - - - - - - - - - -
    def backTransparency(self):
        """[0,1] how "clear" an object is: 1."""
        return self.__backTransparency
    @backTransparency.setter
    def backTransparency(self, backTransparency=None):
        if  backTransparency is None:
            backTransparency = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(backTransparency)
        assertZeroToOne('backTransparency', backTransparency)
        self.__backTransparency = backTransparency
    @property # getter - - - - - - - - - -
    def diffuseColor(self):
        """[0,1] how much direct, angle-dependent light is reflected from all light sources."""
        return self.__diffuseColor
    @diffuseColor.setter
    def diffuseColor(self, diffuseColor=None):
        if  diffuseColor is None:
            diffuseColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(diffuseColor)
        assertZeroToOne('diffuseColor', diffuseColor)
        self.__diffuseColor = diffuseColor
    @property # getter - - - - - - - - - -
    def emissiveColor(self):
        """[0,1] how much glowing light is emitted from this object."""
        return self.__emissiveColor
    @emissiveColor.setter
    def emissiveColor(self, emissiveColor=None):
        if  emissiveColor is None:
            emissiveColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(emissiveColor)
        assertZeroToOne('emissiveColor', emissiveColor)
        self.__emissiveColor = emissiveColor
    @property # getter - - - - - - - - - -
    def separateBackColor(self):
        """separateBackColor determines whether separate Material values are used for back faces."""
        return self.__separateBackColor
    @separateBackColor.setter
    def separateBackColor(self, separateBackColor=None):
        if  separateBackColor is None:
            separateBackColor = SFBool.DEFAULT_VALUE
        assertValidSFBool(separateBackColor)
        self.__separateBackColor = separateBackColor
    @property # getter - - - - - - - - - -
    def shininess(self):
        """[0,1] Lower shininess values provide soft specular glows, while higher values result in sharper, smaller highlights."""
        return self.__shininess
    @shininess.setter
    def shininess(self, shininess=None):
        if  shininess is None:
            shininess = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(shininess)
        assertZeroToOne('shininess', shininess)
        self.__shininess = shininess
    @property # getter - - - - - - - - - -
    def specularColor(self):
        """[0,1] specular highlights are brightness reflections (example: shiny spots on an apple)."""
        return self.__specularColor
    @specularColor.setter
    def specularColor(self, specularColor=None):
        if  specularColor is None:
            specularColor = SFColor.DEFAULT_VALUE
        assertValidSFColor(specularColor)
        assertZeroToOne('specularColor', specularColor)
        self.__specularColor = specularColor
    @property # getter - - - - - - - - - -
    def transparency(self):
        """[0,1] how "clear" an object is: 1."""
        return self.__transparency
    @transparency.setter
    def transparency(self, transparency=None):
        if  transparency is None:
            transparency = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(transparency)
        assertZeroToOne('transparency', transparency)
        self.__transparency = transparency
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function TwoSidedMaterial.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<TwoSidedMaterial'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.ambientIntensity != 0.2:
            result += " ambientIntensity='" + SFFloat(self.ambientIntensity).XML() + "'"
        if self.backAmbientIntensity != 0.2:
            result += " backAmbientIntensity='" + SFFloat(self.backAmbientIntensity).XML() + "'"
        if self.backDiffuseColor != (0.8, 0.8, 0.8):
            result += " backDiffuseColor='" + SFColor(self.backDiffuseColor).XML() + "'"
        if self.backEmissiveColor != (0, 0, 0):
            result += " backEmissiveColor='" + SFColor(self.backEmissiveColor).XML() + "'"
        if self.backShininess != 0.2:
            result += " backShininess='" + SFFloat(self.backShininess).XML() + "'"
        if self.backSpecularColor != (0, 0, 0):
            result += " backSpecularColor='" + SFColor(self.backSpecularColor).XML() + "'"
        if self.backTransparency != 0:
            result += " backTransparency='" + SFFloat(self.backTransparency).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.diffuseColor != (0.8, 0.8, 0.8):
            result += " diffuseColor='" + SFColor(self.diffuseColor).XML() + "'"
        if self.emissiveColor != (0, 0, 0):
            result += " emissiveColor='" + SFColor(self.emissiveColor).XML() + "'"
        if self.separateBackColor != False:
            result += " separateBackColor='" + SFBool(self.separateBackColor).XML() + "'"
        if self.shininess != 0.2:
            result += " shininess='" + SFFloat(self.shininess).XML() + "'"
        if self.specularColor != (0, 0, 0):
            result += " specularColor='" + SFColor(self.specularColor).XML() + "'"
        if self.transparency != 0:
            result += " transparency='" + SFFloat(self.transparency).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</TwoSidedMaterial>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class UniversalJoint(_X3DRigidJointNode):
    """
    UniversalJoint is like a BallJoint that constrains an extra degree of rotational freedom.
    """
    NAME = 'UniversalJoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#UniversalJoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('anchorPoint', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'UniversalJoint'),
        ('axis1', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'UniversalJoint'),
        ('axis2', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'UniversalJoint'),
        ('forceOutput', ["NONE"], FieldType.MFString, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('stop1Bounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'UniversalJoint'),
        ('stop1ErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'UniversalJoint'),
        ('stop2Bounce', 0, FieldType.SFFloat, AccessType.inputOutput, 'UniversalJoint'),
        ('stop2ErrorCorrection', 0.8, FieldType.SFFloat, AccessType.inputOutput, 'UniversalJoint'),
        ('body1', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('body2', None, FieldType.SFNode, AccessType.inputOutput, 'X3DRigidJointNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 anchorPoint=(0, 0, 0),
                 axis1=(0, 0, 0),
                 axis2=(0, 0, 0),
                 forceOutput=["NONE"],
                 stop1Bounce=0,
                 stop1ErrorCorrection=0.8,
                 stop2Bounce=0,
                 stop2ErrorCorrection=0.8,
                 body1=None,
                 body2=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode UniversalJoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.anchorPoint = anchorPoint
        self.axis1 = axis1
        self.axis2 = axis2
        self.forceOutput = forceOutput
        self.stop1Bounce = stop1Bounce
        self.stop1ErrorCorrection = stop1ErrorCorrection
        self.stop2Bounce = stop2Bounce
        self.stop2ErrorCorrection = stop2ErrorCorrection
        self.body1 = body1
        self.body2 = body2
    @property # getter - - - - - - - - - -
    def anchorPoint(self):
        """anchorPoint is joint center, specified in world coordinates."""
        return self.__anchorPoint
    @anchorPoint.setter
    def anchorPoint(self, anchorPoint=None):
        if  anchorPoint is None:
            anchorPoint = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(anchorPoint)
        self.__anchorPoint = anchorPoint
    @property # getter - - - - - - - - - -
    def axis1(self):
        """axis1 defines axis vector of joint connection to body1."""
        return self.__axis1
    @axis1.setter
    def axis1(self, axis1=None):
        if  axis1 is None:
            axis1 = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(axis1)
        self.__axis1 = axis1
    @property # getter - - - - - - - - - -
    def axis2(self):
        """axis2 defines axis vector of joint connection to body2."""
        return self.__axis2
    @axis2.setter
    def axis2(self, axis2=None):
        if  axis2 is None:
            axis2 = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(axis2)
        self.__axis2 = axis2
    @property # getter - - - - - - - - - -
    def forceOutput(self):
        """forceOutput controls which output fields are generated for the next frame."""
        return self.__forceOutput
    @forceOutput.setter
    def forceOutput(self, forceOutput=None):
        if  forceOutput is None:
            forceOutput = MFString.DEFAULT_VALUE
        assertValidMFString(forceOutput)
        self.__forceOutput = forceOutput
    @property # getter - - - - - - - - - -
    def stop1Bounce(self):
        """[0,1] stop1Bounce is velocity factor for bounce back once stop point is reached."""
        return self.__stop1Bounce
    @stop1Bounce.setter
    def stop1Bounce(self, stop1Bounce=None):
        if  stop1Bounce is None:
            stop1Bounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop1Bounce)
        assertZeroToOne('stop1Bounce', stop1Bounce)
        self.__stop1Bounce = stop1Bounce
    @property # getter - - - - - - - - - -
    def stop1ErrorCorrection(self):
        """[0,1] stop1ErrorCorrection is fraction of error correction performed during time step once stop point is reached."""
        return self.__stop1ErrorCorrection
    @stop1ErrorCorrection.setter
    def stop1ErrorCorrection(self, stop1ErrorCorrection=None):
        if  stop1ErrorCorrection is None:
            stop1ErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop1ErrorCorrection)
        assertZeroToOne('stop1ErrorCorrection', stop1ErrorCorrection)
        self.__stop1ErrorCorrection = stop1ErrorCorrection
    @property # getter - - - - - - - - - -
    def stop2Bounce(self):
        """[0,1] stop2Bounce is velocity factor for bounce back once stop point is reached."""
        return self.__stop2Bounce
    @stop2Bounce.setter
    def stop2Bounce(self, stop2Bounce=None):
        if  stop2Bounce is None:
            stop2Bounce = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop2Bounce)
        assertZeroToOne('stop2Bounce', stop2Bounce)
        self.__stop2Bounce = stop2Bounce
    @property # getter - - - - - - - - - -
    def stop2ErrorCorrection(self):
        """[0,1] stop2ErrorCorrection is fraction of error correction performed during time step once stop point is reached."""
        return self.__stop2ErrorCorrection
    @stop2ErrorCorrection.setter
    def stop2ErrorCorrection(self, stop2ErrorCorrection=None):
        if  stop2ErrorCorrection is None:
            stop2ErrorCorrection = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(stop2ErrorCorrection)
        assertZeroToOne('stop2ErrorCorrection', stop2ErrorCorrection)
        self.__stop2ErrorCorrection = stop2ErrorCorrection
    @property # getter - - - - - - - - - -
    def body1(self):
        return self.__body1
    @body1.setter
    def body1(self, body1=None):
        if  body1 is None:
            body1 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body1)
        if not isinstance(body1, object):
            # print(flush=True)
            raise X3DTypeError(str(body1) + ' does not have a valid node type object')
        self.__body1 = body1
    @property # getter - - - - - - - - - -
    def body2(self):
        return self.__body2
    @body2.setter
    def body2(self, body2=None):
        if  body2 is None:
            body2 = SFNode.DEFAULT_VALUE
        assertValidSFNode(body2)
        if not isinstance(body2, object):
            # print(flush=True)
            raise X3DTypeError(str(body2) + ' does not have a valid node type object')
        self.__body2 = body2
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.body1) or bool(self.body2) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function UniversalJoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<UniversalJoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.anchorPoint != (0, 0, 0):
            result += " anchorPoint='" + SFVec3f(self.anchorPoint).XML() + "'"
        if self.axis1 != (0, 0, 0):
            result += " axis1='" + SFVec3f(self.axis1).XML() + "'"
        if self.axis2 != (0, 0, 0):
            result += " axis2='" + SFVec3f(self.axis2).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.forceOutput != ["NONE"]:
            result += " forceOutput='" + MFString(self.forceOutput).XML() + "'"
        if self.stop1Bounce != 0:
            result += " stop1Bounce='" + SFFloat(self.stop1Bounce).XML() + "'"
        if self.stop1ErrorCorrection != 0.8:
            result += " stop1ErrorCorrection='" + SFFloat(self.stop1ErrorCorrection).XML() + "'"
        if self.stop2Bounce != 0:
            result += " stop2Bounce='" + SFFloat(self.stop2Bounce).XML() + "'"
        if self.stop2ErrorCorrection != 0.8:
            result += " stop2ErrorCorrection='" + SFFloat(self.stop2ErrorCorrection).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.body1: # output this SFNode
                result += self.body1.XML(indentLevel=indentLevel+1)
            if self.body2: # output this SFNode
                result += self.body2.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</UniversalJoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Viewpoint(_X3DViewpointNode):
    """
    Viewpoint provides a specific location and direction where the user may view the scene.
    """
    NAME = 'Viewpoint'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Viewpoint'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('centerOfRotation', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'Viewpoint'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'X3DViewpointNode'),
        ('fieldOfView', 0.7854, FieldType.SFFloat, AccessType.inputOutput, 'Viewpoint'),
        ('jump', True, FieldType.SFBool, AccessType.inputOutput, 'X3DViewpointNode'),
        ('orientation', (0, 0, 1, 0), FieldType.SFRotation, AccessType.inputOutput, 'X3DViewpointNode'),
        ('position', (0, 0, 10), FieldType.SFVec3f, AccessType.inputOutput, 'Viewpoint'),
        ('retainUserOffsets', False, FieldType.SFBool, AccessType.inputOutput, 'X3DViewpointNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 centerOfRotation=(0, 0, 0),
                 description='',
                 fieldOfView=0.7854,
                 jump=True,
                 orientation=(0, 0, 1, 0),
                 position=(0, 0, 10),
                 retainUserOffsets=False,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Viewpoint __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.centerOfRotation = centerOfRotation
        self.description = description
        self.fieldOfView = fieldOfView
        self.jump = jump
        self.orientation = orientation
        self.position = position
        self.retainUserOffsets = retainUserOffsets
    @property # getter - - - - - - - - - -
    def centerOfRotation(self):
        """centerOfRotation specifies center point about which to rotate user's eyepoint when in EXAMINE or LOOKAT mode."""
        return self.__centerOfRotation
    @centerOfRotation.setter
    def centerOfRotation(self, centerOfRotation=None):
        if  centerOfRotation is None:
            centerOfRotation = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(centerOfRotation)
        self.__centerOfRotation = centerOfRotation
    @property # getter - - - - - - - - - -
    def description(self):
        """Text description or navigation hint to describe the significance of this model Viewpoint."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def fieldOfView(self):
        """Preferred minimum viewing angle from this viewpoint in radians, providing minimum height or minimum width (whichever is smaller)."""
        return self.__fieldOfView
    @fieldOfView.setter
    def fieldOfView(self, fieldOfView=None):
        if  fieldOfView is None:
            fieldOfView = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(fieldOfView)
        assertGreaterThan('fieldOfView', fieldOfView, 0)
        assertLessThan('fieldOfView', fieldOfView, 3.1416)
        self.__fieldOfView = fieldOfView
    @property # getter - - - - - - - - - -
    def jump(self):
        """Transition instantly by jumping, otherwise smoothly adjust offsets in place when changing to this Viewpoint."""
        return self.__jump
    @jump.setter
    def jump(self, jump=None):
        if  jump is None:
            jump = SFBool.DEFAULT_VALUE
        assertValidSFBool(jump)
        self.__jump = jump
    @property # getter - - - - - - - - - -
    def orientation(self):
        """Rotation (axis, angle in radians) of Viewpoint, relative to default -Z axis direction in local coordinate system."""
        return self.__orientation
    @orientation.setter
    def orientation(self, orientation=None):
        if  orientation is None:
            orientation = SFRotation.DEFAULT_VALUE
        assertValidSFRotation(orientation)
        self.__orientation = orientation
    @property # getter - - - - - - - - - -
    def position(self):
        """position (x, y, z in meters) relative to local coordinate system."""
        return self.__position
    @position.setter
    def position(self, position=None):
        if  position is None:
            position = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(position)
        self.__position = position
    @property # getter - - - - - - - - - -
    def retainUserOffsets(self):
        """Retain (true) or reset to zero (false) any prior user navigation offsets from defined viewpoint position, orientation."""
        return self.__retainUserOffsets
    @retainUserOffsets.setter
    def retainUserOffsets(self, retainUserOffsets=None):
        if  retainUserOffsets is None:
            retainUserOffsets = SFBool.DEFAULT_VALUE
        assertValidSFBool(retainUserOffsets)
        self.__retainUserOffsets = retainUserOffsets
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Viewpoint.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Viewpoint'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.centerOfRotation != (0, 0, 0):
            result += " centerOfRotation='" + SFVec3f(self.centerOfRotation).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.fieldOfView != 0.7854:
            result += " fieldOfView='" + SFFloat(self.fieldOfView).XML() + "'"
        if self.jump != True:
            result += " jump='" + SFBool(self.jump).XML() + "'"
        if self.orientation != (0, 0, 1, 0):
            result += " orientation='" + SFRotation(self.orientation).XML() + "'"
        if self.position != (0, 0, 10):
            result += " position='" + SFVec3f(self.position).XML() + "'"
        if self.retainUserOffsets != False:
            result += " retainUserOffsets='" + SFBool(self.retainUserOffsets).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</Viewpoint>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class ViewpointGroup(_X3DChildNode):
    """
    ViewpointGroup can contain Viewpoint, OrthoViewpoint, GeoViewpoint and other ViewpointGroup nodes for better user-navigation support with a shared description on the viewpoint list.
    """
    NAME = 'ViewpointGroup'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#ViewpointGroup'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'ViewpointGroup'),
        ('description', '', FieldType.SFString, AccessType.inputOutput, 'ViewpointGroup'),
        ('displayed', True, FieldType.SFBool, AccessType.inputOutput, 'ViewpointGroup'),
        ('retainUserOffsets', False, FieldType.SFBool, AccessType.inputOutput, 'ViewpointGroup'),
        ('size', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'ViewpointGroup'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'ViewpointGroup'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 center=(0, 0, 0),
                 description='',
                 displayed=True,
                 retainUserOffsets=False,
                 size=(0, 0, 0),
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode ViewpointGroup __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.center = center
        self.description = description
        self.displayed = displayed
        self.retainUserOffsets = retainUserOffsets
        self.size = size
        self.children = children
    @property # getter - - - - - - - - - -
    def center(self):
        """center specifies center point of proximity box within which ViewpointGroup is usable and displayed on viewpoint list."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def description(self):
        """Text description or navigation hint to identify this ViewpointGroup."""
        return self.__description
    @description.setter
    def description(self, description=None):
        if  description is None:
            description = SFString.DEFAULT_VALUE
        assertValidSFString(description)
        self.__description = description
    @property # getter - - - - - - - - - -
    def displayed(self):
        """displayed determines whether this ViewpointGroup is displayed in the current viewpoint list."""
        return self.__displayed
    @displayed.setter
    def displayed(self, displayed=None):
        if  displayed is None:
            displayed = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayed)
        self.__displayed = displayed
    @property # getter - - - - - - - - - -
    def retainUserOffsets(self):
        """Retain (true) or reset to zero (false) any prior user navigation offsets from defined viewpoint position, orientation."""
        return self.__retainUserOffsets
    @retainUserOffsets.setter
    def retainUserOffsets(self, retainUserOffsets=None):
        if  retainUserOffsets is None:
            retainUserOffsets = SFBool.DEFAULT_VALUE
        assertValidSFBool(retainUserOffsets)
        self.__retainUserOffsets = retainUserOffsets
    @property # getter - - - - - - - - - -
    def size(self):
        """[0,+infinity) Size of proximity box around center location within which ViewpointGroup is usable and displayed on viewpoint list."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(size)
        self.__size = size
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] ViewpointGroup contains Viewpoint, OrthoViewpoint, GeoViewpoint and other ViewpointGroup nodes that each have containerField='children' default value."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function ViewpointGroup.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<ViewpointGroup'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.description:
            result += " description='" + self.description + "'"
        if self.displayed != True:
            result += " displayed='" + SFBool(self.displayed).XML() + "'"
        if self.retainUserOffsets != False:
            result += " retainUserOffsets='" + SFBool(self.retainUserOffsets).XML() + "'"
        if self.size != (0, 0, 0):
            result += " size='" + SFVec3f(self.size).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</ViewpointGroup>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class Viewport(_X3DViewportNode):
    """
    Viewport is a Grouping node that can contain most nodes.
    """
    NAME = 'Viewport'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#Viewport'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DGroupingNode'),
        ('clipBoundary', [0, 1, 0, 1], FieldType.MFFloat, AccessType.inputOutput, 'Viewport'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DGroupingNode'),
        ('children', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DGroupingNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 clipBoundary=[0, 1, 0, 1],
                 displayBBox=False,
                 visible=True,
                 children=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode Viewport __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.clipBoundary = clipBoundary
        self.displayBBox = displayBBox
        self.visible = visible
        self.children = children
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def clipBoundary(self):
        """[0,1] clipBoundary is specified in fractions of the normal render surface in the sequence left/right/bottom/top."""
        return self.__clipBoundary
    @clipBoundary.setter
    def clipBoundary(self, clipBoundary=None):
        if  clipBoundary is None:
            clipBoundary = MFFloat.DEFAULT_VALUE
        assertValidMFFloat(clipBoundary)
        assertZeroToOne('clipBoundary', clipBoundary)
        self.__clipBoundary = clipBoundary
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def children(self):
        """[X3DChildNode] Grouping nodes contain an ordered list of children nodes."""
        return self.__children
    @children.setter
    def children(self, children=None):
        if  children is None:
            children = MFNode.DEFAULT_VALUE
        assertValidMFNode(children)
        self.__children = children
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.children) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function Viewport.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<Viewport'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.clipBoundary != [0, 1, 0, 1]:
            result += " clipBoundary='" + MFFloat(self.clipBoundary).XML() + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.children: # walk each child node, if any
                for each in self.children:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</Viewport>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class VisibilitySensor(_X3DEnvironmentalSensorNode):
    """
    VisibilitySensor detects when user can see a specific object or region as they navigate the world.
    """
    NAME = 'VisibilitySensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#VisibilitySensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('center', (0, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'VisibilitySensor'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('size', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DEnvironmentalSensorNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 center=(0, 0, 0),
                 enabled=True,
                 size=(0, 0, 0),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode VisibilitySensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.center = center
        self.enabled = enabled
        self.size = size
    @property # getter - - - - - - - - - -
    def center(self):
        """Translation offset from origin of local coordinate system."""
        return self.__center
    @center.setter
    def center(self, center=None):
        if  center is None:
            center = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(center)
        self.__center = center
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def size(self):
        """[0,+infinity) size of visibility box, measured from center in meters."""
        return self.__size
    @size.setter
    def size(self, size=None):
        if  size is None:
            size = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(size)
        assertNonNegative('size', size)
        self.__size = size
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function VisibilitySensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<VisibilitySensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.center != (0, 0, 0):
            result += " center='" + SFVec3f(self.center).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.size != (0, 0, 0):
            result += " size='" + SFVec3f(self.size).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</VisibilitySensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class VolumeData(_X3DVolumeDataNode):
    """
    VolumeData displays a simple non-segmented voxel dataset with a single RenderStyle node.
    """
    NAME = 'VolumeData'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#VolumeData'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('bboxCenter', (0, 0, 0), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DVolumeDataNode'),
        ('bboxSize', (-1, -1, -1), FieldType.SFVec3f, AccessType.initializeOnly, 'X3DVolumeDataNode'),
        ('dimensions', (1, 1, 1), FieldType.SFVec3f, AccessType.inputOutput, 'X3DVolumeDataNode'),
        ('displayBBox', False, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeDataNode'),
        ('visible', True, FieldType.SFBool, AccessType.inputOutput, 'X3DVolumeDataNode'),
        ('renderStyle', None, FieldType.SFNode, AccessType.inputOutput, 'VolumeData'),
        ('voxels', None, FieldType.SFNode, AccessType.inputOutput, 'VolumeData'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 bboxCenter=(0, 0, 0),
                 bboxSize=(-1, -1, -1),
                 dimensions=(1, 1, 1),
                 displayBBox=False,
                 visible=True,
                 renderStyle=None,
                 voxels=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode VolumeData __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.bboxCenter = bboxCenter
        self.bboxSize = bboxSize
        self.dimensions = dimensions
        self.displayBBox = displayBBox
        self.visible = visible
        self.renderStyle = renderStyle
        self.voxels = voxels
    @property # getter - - - - - - - - - -
    def bboxCenter(self):
        """Bounding box center accompanies bboxSize and provides an optional hint for bounding box position offset from origin of local coordinate system."""
        return self.__bboxCenter
    @bboxCenter.setter
    def bboxCenter(self, bboxCenter=None):
        if  bboxCenter is None:
            bboxCenter = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxCenter)
        self.__bboxCenter = bboxCenter
    @property # getter - - - - - - - - - -
    def bboxSize(self):
        """Bounding box size is usually omitted, and can easily be calculated automatically by an X3D player at scene-loading time with minimal computational cost."""
        return self.__bboxSize
    @bboxSize.setter
    def bboxSize(self, bboxSize=None):
        if  bboxSize is None:
            bboxSize = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(bboxSize)
        assertBoundingBox('bboxSize', bboxSize)
        self.__bboxSize = bboxSize
    @property # getter - - - - - - - - - -
    def dimensions(self):
        """Actual-size X-Y-Z dimensions of volume data in local coordinate system."""
        return self.__dimensions
    @dimensions.setter
    def dimensions(self, dimensions=None):
        if  dimensions is None:
            dimensions = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(dimensions)
        assertPositive('dimensions', dimensions)
        self.__dimensions = dimensions
    @property # getter - - - - - - - - - -
    def displayBBox(self):
        return self.__displayBBox
    @displayBBox.setter
    def displayBBox(self, displayBBox=None):
        if  displayBBox is None:
            displayBBox = SFBool.DEFAULT_VALUE
        assertValidSFBool(displayBBox)
        self.__displayBBox = displayBBox
    @property # getter - - - - - - - - - -
    def visible(self):
        return self.__visible
    @visible.setter
    def visible(self, visible=None):
        if  visible is None:
            visible = SFBool.DEFAULT_VALUE
        assertValidSFBool(visible)
        self.__visible = visible
    @property # getter - - - - - - - - - -
    def renderStyle(self):
        """[X3DVolumeRenderStyleNode] Single contained X3DVolumeRenderStyleNode node that defines specific rendering technique for this volumetric object."""
        return self.__renderStyle
    @renderStyle.setter
    def renderStyle(self, renderStyle=None):
        if  renderStyle is None:
            renderStyle = SFNode.DEFAULT_VALUE
        assertValidSFNode(renderStyle)
        if not isinstance(renderStyle, object):
            # print(flush=True)
            raise X3DTypeError(str(renderStyle) + ' does not have a valid node type object')
        self.__renderStyle = renderStyle
    @property # getter - - - - - - - - - -
    def voxels(self):
        """[X3DTexture3DNode] Single contained X3DTexture3DNode (ComposedTexture3D, ImageTexture3D, PixelTexture3D) that provides raw voxel information utilized by corresponding rendering styles."""
        return self.__voxels
    @voxels.setter
    def voxels(self, voxels=None):
        if  voxels is None:
            voxels = SFNode.DEFAULT_VALUE
        assertValidSFNode(voxels)
        if not isinstance(voxels, object):
            # print(flush=True)
            raise X3DTypeError(str(voxels) + ' does not have a valid node type object')
        self.__voxels = voxels
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata) or bool(self.renderStyle) or bool(self.voxels)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function VolumeData.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<VolumeData'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.bboxCenter != (0, 0, 0):
            result += " bboxCenter='" + SFVec3f(self.bboxCenter).XML() + "'"
        if self.bboxSize != (-1, -1, -1):
            result += " bboxSize='" + SFVec3f(self.bboxSize).XML() + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.dimensions != (1, 1, 1):
            result += " dimensions='" + SFVec3f(self.dimensions).XML() + "'"
        if self.displayBBox != False:
            result += " displayBBox='" + SFBool(self.displayBBox).XML() + "'"
        if self.visible != True:
            result += " visible='" + SFBool(self.visible).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.renderStyle: # output this SFNode
                result += self.renderStyle.XML(indentLevel=indentLevel+1)
            if self.voxels: # output this SFNode
                result += self.voxels.XML(indentLevel=indentLevel+1)
            result += indent + '</VolumeData>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class VolumeEmitter(_X3DParticleEmitterNode):
    """
    VolumeEmitter emits particles from a random position confined within the given closed geometry volume.
    """
    NAME = 'VolumeEmitter'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#VolumeEmitter'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('coordIndex', [-1], FieldType.MFInt32, AccessType.initializeOnly, 'VolumeEmitter'),
        ('direction', (0, 1, 0), FieldType.SFVec3f, AccessType.inputOutput, 'VolumeEmitter'),
        ('internal', True, FieldType.SFBool, AccessType.initializeOnly, 'VolumeEmitter'),
        ('mass', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('speed', 0, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('surfaceArea', 0, FieldType.SFFloat, AccessType.initializeOnly, 'X3DParticleEmitterNode'),
        ('variation', 0.25, FieldType.SFFloat, AccessType.inputOutput, 'X3DParticleEmitterNode'),
        ('coord', None, FieldType.SFNode, AccessType.inputOutput, 'VolumeEmitter'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 coordIndex=[-1],
                 direction=(0, 1, 0),
                 internal=True,
                 mass=0,
                 speed=0,
                 surfaceArea=0,
                 variation=0.25,
                 coord=None,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode VolumeEmitter __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.coordIndex = coordIndex
        self.direction = direction
        self.internal = internal
        self.mass = mass
        self.speed = speed
        self.surfaceArea = surfaceArea
        self.variation = variation
        self.coord = coord
    @property # getter - - - - - - - - - -
    def coordIndex(self):
        """[-1,+infinity) coordIndex indices are applied to contained Coordinate values in order to define randomly generated initial geometry of the particles."""
        return self.__coordIndex
    @coordIndex.setter
    def coordIndex(self, coordIndex=None):
        if  coordIndex is None:
            coordIndex = MFInt32.DEFAULT_VALUE
        assertValidMFInt32(coordIndex)
        assertGreaterThanEquals('coordIndex', coordIndex, -1)
        self.__coordIndex = coordIndex
    @property # getter - - - - - - - - - -
    def direction(self):
        """Initial direction from which particles emanate."""
        return self.__direction
    @direction.setter
    def direction(self, direction=None):
        if  direction is None:
            direction = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(direction)
        assertGreaterThanEquals('direction', direction, -1)
        assertLessThanEquals('direction', direction, 1)
        self.__direction = direction
    @property # getter - - - - - - - - - -
    def internal(self):
        """TODO, X3D specification is undefined."""
        return self.__internal
    @internal.setter
    def internal(self, internal=None):
        if  internal is None:
            internal = SFBool.DEFAULT_VALUE
        assertValidSFBool(internal)
        self.__internal = internal
    @property # getter - - - - - - - - - -
    def mass(self):
        """[0,+infinity) Basic mass of each particle, defined in mass base units (default is kilograms)."""
        return self.__mass
    @mass.setter
    def mass(self, mass=None):
        if  mass is None:
            mass = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(mass)
        assertNonNegative('mass', mass)
        self.__mass = mass
    @property # getter - - - - - - - - - -
    def speed(self):
        """[0,+infinity) Initial linear speed (default is m/s) imparted to all particles along their direction of movement."""
        return self.__speed
    @speed.setter
    def speed(self, speed=None):
        if  speed is None:
            speed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speed)
        assertNonNegative('speed', speed)
        self.__speed = speed
    @property # getter - - - - - - - - - -
    def surfaceArea(self):
        """[0,+infinity) Particle surface area in area base units (default is meters squared)."""
        return self.__surfaceArea
    @surfaceArea.setter
    def surfaceArea(self, surfaceArea=None):
        if  surfaceArea is None:
            surfaceArea = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(surfaceArea)
        assertNonNegative('surfaceArea', surfaceArea)
        self.__surfaceArea = surfaceArea
    @property # getter - - - - - - - - - -
    def variation(self):
        """[0,+infinity) Multiplier for the randomness used to control the range of possible output values."""
        return self.__variation
    @variation.setter
    def variation(self, variation=None):
        if  variation is None:
            variation = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(variation)
        assertNonNegative('variation', variation)
        self.__variation = variation
    @property # getter - - - - - - - - - -
    def coord(self):
        """[X3DCoordinateNode] Coordinates for the geometry used as the emitting volume."""
        return self.__coord
    @coord.setter
    def coord(self, coord=None):
        if  coord is None:
            coord = SFNode.DEFAULT_VALUE
        assertValidSFNode(coord)
        if not isinstance(coord, object):
            # print(flush=True)
            raise X3DTypeError(str(coord) + ' does not have a valid node type object')
        self.__coord = coord
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.coord) or bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function VolumeEmitter.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<VolumeEmitter'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.coordIndex != [-1]:
            result += " coordIndex='" + MFInt32(self.coordIndex).XML() + "'"
        if self.direction != (0, 1, 0):
            result += " direction='" + SFVec3f(self.direction).XML() + "'"
        if self.internal != True:
            result += " internal='" + SFBool(self.internal).XML() + "'"
        if self.mass != 0:
            result += " mass='" + SFFloat(self.mass).XML() + "'"
        if self.speed != 0:
            result += " speed='" + SFFloat(self.speed).XML() + "'"
        if self.surfaceArea != 0:
            result += " surfaceArea='" + SFFloat(self.surfaceArea).XML() + "'"
        if self.variation != 0.25:
            result += " variation='" + SFFloat(self.variation).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.coord: # output this SFNode
                result += self.coord.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</VolumeEmitter>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class VolumePickSensor(_X3DPickSensorNode):
    """
    VolumePickSensor tests picking intersections using the pickingGeometry against the pickTarget geometry volume.
    """
    NAME = 'VolumePickSensor'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#VolumePickSensor'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DSensorNode'),
        ('intersectionType', 'BOUNDS', FieldType.SFString, AccessType.initializeOnly, 'X3DPickSensorNode'),
        ('matchCriterion', 'MATCH_ANY', FieldType.SFString, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('objectType', ["ALL"], FieldType.MFString, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('sortOrder', 'CLOSEST', FieldType.SFString, AccessType.initializeOnly, 'X3DPickSensorNode'),
        ('pickingGeometry', None, FieldType.SFNode, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('pickTarget', list(), FieldType.MFNode, AccessType.inputOutput, 'X3DPickSensorNode'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 enabled=True,
                 intersectionType='BOUNDS',
                 matchCriterion='MATCH_ANY',
                 objectType=["ALL"],
                 sortOrder='CLOSEST',
                 pickingGeometry=None,
                 pickTarget=list(),
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode VolumePickSensor __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.enabled = enabled
        self.intersectionType = intersectionType
        self.matchCriterion = matchCriterion
        self.objectType = objectType
        self.sortOrder = sortOrder
        self.pickingGeometry = pickingGeometry
        self.pickTarget = pickTarget
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def intersectionType(self):
        """intersectionType specifies precision of the collision computation."""
        return self.__intersectionType
    @intersectionType.setter
    def intersectionType(self, intersectionType=None):
        if  intersectionType is None:
            intersectionType = SFString.DEFAULT_VALUE
        assertValidSFString(intersectionType)
        self.__intersectionType = intersectionType
    @property # getter - - - - - - - - - -
    def matchCriterion(self):
        """defines whether the intersection test (i."""
        return self.__matchCriterion
    @matchCriterion.setter
    def matchCriterion(self, matchCriterion=None):
        if  matchCriterion is None:
            matchCriterion = SFString.DEFAULT_VALUE
        assertValidSFString(matchCriterion)
        self.__matchCriterion = matchCriterion
    @property # getter - - - - - - - - - -
    def objectType(self):
        """The objectType field specifies a set of labels used in the picking process."""
        return self.__objectType
    @objectType.setter
    def objectType(self, objectType=None):
        if  objectType is None:
            objectType = MFString.DEFAULT_VALUE
        assertValidMFString(objectType)
        self.__objectType = objectType
    @property # getter - - - - - - - - - -
    def sortOrder(self):
        """The sortOrder field determines the order provided for picked output events."""
        return self.__sortOrder
    @sortOrder.setter
    def sortOrder(self, sortOrder=None):
        if  sortOrder is None:
            sortOrder = SFString.DEFAULT_VALUE
        assertValidSFString(sortOrder)
        self.__sortOrder = sortOrder
    @property # getter - - - - - - - - - -
    def pickingGeometry(self):
        """[X3DGeometryNode] pickingGeometry specifies the exact geometry coordinates that are used to perform the intersection testing of the picking operation."""
        return self.__pickingGeometry
    @pickingGeometry.setter
    def pickingGeometry(self, pickingGeometry=None):
        if  pickingGeometry is None:
            pickingGeometry = SFNode.DEFAULT_VALUE
        assertValidSFNode(pickingGeometry)
        if not isinstance(pickingGeometry, object):
            # print(flush=True)
            raise X3DTypeError(str(pickingGeometry) + ' does not have a valid node type object')
        self.__pickingGeometry = pickingGeometry
    @property # getter - - - - - - - - - -
    def pickTarget(self):
        """[X3DGroupingNode|X3DShapeNode|Inline] pickTarget specifies the list of nodes against which picking operations are performed."""
        return self.__pickTarget
    @pickTarget.setter
    def pickTarget(self, pickTarget=None):
        if  pickTarget is None:
            pickTarget = MFNode.DEFAULT_VALUE
        assertValidMFNode(pickTarget)
        self.__pickTarget = pickTarget
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.pickTarget) or bool(self.IS) or bool(self.metadata) or bool(self.pickingGeometry)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function VolumePickSensor.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<VolumePickSensor'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.intersectionType != 'BOUNDS':
            result += " intersectionType='" + self.intersectionType + "'"
        if self.matchCriterion != 'MATCH_ANY':
            result += " matchCriterion='" + self.matchCriterion + "'"
        if self.objectType != ["ALL"]:
            result += " objectType='" + MFString(self.objectType).XML() + "'"
        if self.sortOrder != 'CLOSEST':
            result += " sortOrder='" + self.sortOrder + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            if self.pickingGeometry: # output this SFNode
                result += self.pickingGeometry.XML(indentLevel=indentLevel+1)
            ## result += indent + '  ' + 'TODO iterate over each child element' + '\n'
            if self.pickTarget: # walk each child node, if any
                for each in self.pickTarget:
                    result += each.XML(indentLevel=indentLevel+1)
            result += indent + '</VolumePickSensor>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class WindPhysicsModel(_X3DParticlePhysicsModelNode):
    """
    WindPhysicsModel applies a wind effect to the particles.
    """
    NAME = 'WindPhysicsModel'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#WindPhysicsModel'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('direction', (1, 0, 0), FieldType.SFVec3f, AccessType.inputOutput, 'WindPhysicsModel'),
        ('enabled', True, FieldType.SFBool, AccessType.inputOutput, 'X3DParticlePhysicsModelNode'),
        ('gustiness', 0.1, FieldType.SFFloat, AccessType.inputOutput, 'WindPhysicsModel'),
        ('speed', 0.1, FieldType.SFFloat, AccessType.inputOutput, 'WindPhysicsModel'),
        ('turbulence', 0, FieldType.SFFloat, AccessType.inputOutput, 'WindPhysicsModel'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 direction=(1, 0, 0),
                 enabled=True,
                 gustiness=0.1,
                 speed=0.1,
                 turbulence=0,
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode WindPhysicsModel __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.direction = direction
        self.enabled = enabled
        self.gustiness = gustiness
        self.speed = speed
        self.turbulence = turbulence
    @property # getter - - - - - - - - - -
    def direction(self):
        """direction in which wind is travelling in the form of a normalized, unit vector."""
        return self.__direction
    @direction.setter
    def direction(self, direction=None):
        if  direction is None:
            direction = SFVec3f.DEFAULT_VALUE
        assertValidSFVec3f(direction)
        self.__direction = direction
    @property # getter - - - - - - - - - -
    def enabled(self):
        """Enables/disables node operation."""
        return self.__enabled
    @enabled.setter
    def enabled(self, enabled=None):
        if  enabled is None:
            enabled = SFBool.DEFAULT_VALUE
        assertValidSFBool(enabled)
        self.__enabled = enabled
    @property # getter - - - - - - - - - -
    def gustiness(self):
        """[0,+infinity) gustiness specifies how much wind speed varies from the average speed."""
        return self.__gustiness
    @gustiness.setter
    def gustiness(self, gustiness=None):
        if  gustiness is None:
            gustiness = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(gustiness)
        assertNonNegative('gustiness', gustiness)
        self.__gustiness = gustiness
    @property # getter - - - - - - - - - -
    def speed(self):
        """[0,+infinity) Initial linear speed (default is m/s) imparted to all particles along their direction of movement."""
        return self.__speed
    @speed.setter
    def speed(self, speed=None):
        if  speed is None:
            speed = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(speed)
        assertNonNegative('speed', speed)
        self.__speed = speed
    @property # getter - - - - - - - - - -
    def turbulence(self):
        """[0,1] turbulence field specifies how much the wind acts directly in line with the direction, and how much variation is applied in directions other than the wind direction."""
        return self.__turbulence
    @turbulence.setter
    def turbulence(self, turbulence=None):
        if  turbulence is None:
            turbulence = SFFloat.DEFAULT_VALUE
        assertValidSFFloat(turbulence)
        assertZeroToOne('turbulence', turbulence)
        self.__turbulence = turbulence
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function WindPhysicsModel.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<WindPhysicsModel'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.direction != (1, 0, 0):
            result += " direction='" + SFVec3f(self.direction).XML() + "'"
        if self.enabled != True:
            result += " enabled='" + SFBool(self.enabled).XML() + "'"
        if self.gustiness != 0.1:
            result += " gustiness='" + SFFloat(self.gustiness).XML() + "'"
        if self.speed != 0.1:
            result += " speed='" + SFFloat(self.speed).XML() + "'"
        if self.turbulence != 0:
            result += " turbulence='" + SFFloat(self.turbulence).XML() + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</WindPhysicsModel>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

class WorldInfo(_X3DInfoNode):
    """
    WorldInfo contains a title and simple persistent metadata information about an X3D scene. This node is strictly for documentation purposes and has no effect on the visual appearance or behaviour of the world.
    """
    NAME = 'WorldInfo'
    SPECIFICATION_URL = ''
    TOOLTIP_URL = 'https://www.web3d.org/x3d/tooltips/X3dTooltips.html#WorldInfo'
    FIELD_DECLARATIONS = [ # name, defaultValue, type, accessType, inheritedFrom
        ('info', list(), FieldType.MFString, AccessType.inputOutput, 'WorldInfo'),
        ('title', '', FieldType.SFString, AccessType.inputOutput, 'WorldInfo'),
        ('DEF', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('USE', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('class_', '', FieldType.SFString, AccessType.inputOutput, 'X3DNode'),
        ('IS', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode'),
        ('metadata', None, FieldType.SFNode, AccessType.inputOutput, 'X3DNode')]
    def __init__(self,
                 info=list(),
                 title='',
                 DEF='',
                 USE='',
                 class_='',
                 IS=None,
                 metadata=None):
        # if _DEBUG: print('... in ConcreteNode WorldInfo __init__ calling super.__init__(' + str(DEF) + ',' + str(USE) + ',' + str(class_) + ',' + str(metadata) + ',' + str(IS) + ')', flush=True)
        super().__init__(DEF, USE, class_, IS, metadata) # fields for _X3DNode only
        self.info = info
        self.title = title
    @property # getter - - - - - - - - - -
    def info(self):
        """Additional information about this model."""
        return self.__info
    @info.setter
    def info(self, info=None):
        if  info is None:
            info = MFString.DEFAULT_VALUE
        assertValidMFString(info)
        self.__info = info
    @property # getter - - - - - - - - - -
    def title(self):
        """title of this world, placed in window title."""
        return self.__title
    @title.setter
    def title(self, title=None):
        if  title is None:
            title = SFString.DEFAULT_VALUE
        assertValidSFString(title)
        self.__title = title
    # hasChild() function - - - - - - - - - -
    def hasChild(self):
        ''' Whether or not this node has a child node, statement or comment '''
        return bool(self.IS) or bool(self.metadata)
    # output function - - - - - - - - - -
    def XML(self, indentLevel=0):
        """ Provide Canonical X3D output serialization using XML encoding. """
        indent = '  ' * indentLevel
        result = ''
        result = indent ### confirm
        # if _DEBUG: result += indent + '# invoked class function WorldInfo.XML(self=' + str(self) + ', indentLevel=' + str(indentLevel) + '), indent="' + indent + '"'
        # print(result)
        result += '<WorldInfo'
        if self.DEF:
            result += " DEF='" + self.DEF + "'"
        if self.USE:
            result += " USE='" + self.USE + "'"
        if self.class_:
            result += " class_='" + self.class_ + "'"
        if self.info != list():
            result += " info='" + MFString(self.info).XML() + "'"
        if self.title:
            result += " title='" + self.title + "'"
        if not self.hasChild():
            result += '/>' + '\n'
        else:
            result += '>' + '\n'
            if self.IS: # output this SFNode
                result += self.IS.XML(indentLevel=indentLevel+1)
            if self.metadata: # output this SFNode
                result += self.metadata.XML(indentLevel=indentLevel+1)
            result += indent + '</WorldInfo>' + '\n'
#       print('XML serialization complete.', flush=True)
        return result

###############################################

# Exceptions

class X3DError(Exception):
    """ Base class for all exceptions raised by this module.
        Reference: X3D Scene Access Interface (SAI), 5.3 Error types
        https://www.web3d.org/documents/specifications/19775-2/V3.3/Part02/dataRef.html
    """

class X3DTypeError(X3DError):
    """ Type error for simple fields (SFBool, SFInt32, SFVec3f etc.) or contained nodes (SFNode, MFNode) according to content model."""

class X3DValueError(X3DError):
    """ Value error for a given X3D type."""

###############################################

# Python x3d Package Loading Complete

print("x3d.py package loaded, have fun with X3D Graphics!")

###############################################
