Files
Copilot d525bc3f28 Bound reconnect cleanup and organize samples by domain (#4276)
# Description

This PR fixes bounded ManagedSession reconnect cleanup and reorganizes
the sample applications into domain-focused folders.

## Reconnect cleanup

- Bounds reconnect integration cleanup with independent 30-second close
and dispose limits.
- Sends `CloseSession` through the awaited transport request path during
`Session.DisposeAsync`.
- Preserves explicit `Session.CloseAsync` behavior that waits for or
cancels outstanding publish requests.
- Covers the disposal request path with a regression test.

## Sample organization

- `samples/OpenUsd`: `GeneratorServer`, `SiteCompositionServer`
- `samples/Redundancy`: `RedundantClient`, `RedundantServer`,
`RedundantPubSub`
- `samples/Isa95`: `MinimalIsa95Server`
- `samples/MinimalApi`: `MinimalBoilerServer`, `MinimalCalcServer`,
`MinimalClient`
- `samples/DI`: `PumpDeviceIntegrationServer`
- `samples/Lds`: `ConsoleLdsServer`
- `samples/Reference`: `ConsoleReferenceClient`,
`ConsoleReferenceServer`
- `samples/PubSub`: `ConsoleReferencePubSubClient`

`UA.slnx` now exposes the same requested domain groups. Project
references, tests, runtime sample probes, CI workflows, Dockerfiles,
Compose files, helper scripts, and documentation were updated to the new
paths. `samples/Robotics/MinimalRobotServer` remains under `Robotics`.

## Validation

- `dotnet build UA.slnx`
- 3 Redundancy short-haul sample tests
- 70 DI sample tests
- 914 OpenUSD tests
- 1 WotCon model-materialization test
- 137 AOT tests
- `docker compose config` for all 6 moved Redundancy Compose files

## Related Issues

- Fixes #4273

## Checklist

- [ ] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [x] I have added all necessary documentation.
- [x] I have verified that my changes do not introduce new build or
analyzer warnings.
- [x] I built the complete `UA.slnx` solution locally.
- [ ] I ran all tests locally against at least .NET Framework and .NET
10.
- [ ] I fixed all failing and flaky tests in the CI pipelines and all
CodeQL warnings.
- [x] I have addressed all PR feedback received.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
Co-authored-by: Marc Schier <mschier@microsoft.com>
Co-authored-by: Marc Schier <marcschier@users.noreply.github.com>
Copilot-Session: a2c2838f-74ae-4997-a1d4-50574d9e0636
2026-08-21 04:35:47 +00:00

1267 lines
49 KiB
Plaintext

#usda 1.0
(
doc = """Reusable single-pump USD asset for the OPC UA - OpenUSD Bindings
pump twin. The server composes one referenced </Pump> prim per configured
pump (--pumps N), so the rendered hall holds exactly the pumps the connected
server simulates - nothing else (spec 5.12, CompositionArc = Reference).
Generated by generate_pump_assets.py from the /Plant/Pumps/P101 master in
Plant.usda, so every composed pump renders at the same fidelity: an EN 733
size 65-200 end-suction centrifugal pump (Grundfos NK / KSB Etanorm
proportions) driven by an IEC 160M motor on a 1.80 x 0.46 m baseplate, shaft
centreline 0.160 m above the baseplate. Do not edit by hand - edit P101 and
re-run the generator.
The asset carries its own instrumentation and indications - pressure and
bearing-temperature gauges, suction vessel, cooling fan, the alarm ring and
the two fault halos - because each composed pump is driven by its own
bindings and has to show its own state.
The root prim declares an identity xformOp:transform and lists it in
xformOpOrder because that is what makes the bay position binding work. A
connector resolves a Translation render target into a single matrix op, and
USD only evaluates ops named in xformOpOrder - a list that is uniform, so the
connector cannot add itself to it from a stronger layer. If the asset omits
the op, the bay position is silently discarded, every composed pump renders
on the origin, and the hall looks like it holds a single machine."""
defaultPrim = "Pump"
metersPerUnit = 1
upAxis = "Z"
)
def Xform "Pump" (
kind = "component"
)
{
matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
def Scope "Looks"
{
def Material "PumpBlue"
{
token outputs:surface.connect = </Pump/Looks/PumpBlue/Surface.outputs:surface>
def Shader "Surface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor = (0.02, 0.24, 0.60)
float inputs:metallic = 0.1
float inputs:roughness = 0.45
token outputs:surface
}
}
def Material "MotorGrey"
{
token outputs:surface.connect = </Pump/Looks/MotorGrey/Surface.outputs:surface>
def Shader "Surface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor = (0.60, 0.61, 0.60)
float inputs:metallic = 0.2
float inputs:roughness = 0.50
token outputs:surface
}
}
def Material "Galvanised"
{
token outputs:surface.connect = </Pump/Looks/Galvanised/Surface.outputs:surface>
def Shader "Surface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor = (0.68, 0.70, 0.72)
float inputs:metallic = 0.8
float inputs:roughness = 0.35
token outputs:surface
}
}
def Material "DarkSteel"
{
token outputs:surface.connect = </Pump/Looks/DarkSteel/Surface.outputs:surface>
def Shader "Surface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor = (0.16, 0.17, 0.19)
float inputs:metallic = 0.6
float inputs:roughness = 0.55
token outputs:surface
}
}
def Material "Bronze"
{
token outputs:surface.connect = </Pump/Looks/Bronze/Surface.outputs:surface>
def Shader "Surface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor = (0.72, 0.53, 0.24)
float inputs:metallic = 0.9
float inputs:roughness = 0.30
token outputs:surface
}
}
}
def Xform "Baseplate"
{
def Cube "Plate" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.20, 0.21, 0.23)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (-0.08, 0, 0.06)
double3 xformOp:scale = (1.80, 0.46, 0.12)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "PumpPad" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.26, 0.27, 0.29)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (-0.62, 0, 0.135)
double3 xformOp:scale = (0.44, 0.40, 0.03)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "MotorRailA" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.26, 0.27, 0.29)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0.31, -0.105, 0.1365)
double3 xformOp:scale = (0.62, 0.07, 0.033)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "MotorRailB" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.26, 0.27, 0.29)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0.31, 0.105, 0.1365)
double3 xformOp:scale = (0.62, 0.07, 0.033)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "LiftingLugA" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.24, 0.25, 0.27)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (-0.86, -0.24, 0.10)
double3 xformOp:scale = (0.10, 0.014, 0.05)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "LiftingLugB" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.24, 0.25, 0.27)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0.70, 0.24, 0.10)
double3 xformOp:scale = (0.10, 0.014, 0.05)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
}
def Cylinder "Body" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.110
double radius = 0.1775
color3f[] primvars:displayColor = [(0.02, 0.24, 0.60)]
rel material:binding = </Pump/Body/Mat>
double3 xformOp:translate = (-0.645, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
def Material "Mat"
{
token outputs:surface.connect = </Pump/Body/Mat/Surface.outputs:surface>
def Shader "Surface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor = (0.02, 0.24, 0.60)
float inputs:metallic = 0.1
float inputs:roughness = 0.45
token outputs:surface
}
}
}
def Xform "Casing"
{
def Cylinder "VoluteShoulder" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.070
double radius = 0.196
color3f[] primvars:displayColor = [(0.02, 0.22, 0.55)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.645, 0.014, 0.293)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cube "Foot" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.02, 0.22, 0.55)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.645, 0, 0.1875)
double3 xformOp:scale = (0.11, 0.30, 0.135)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "FootPad" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.02, 0.20, 0.50)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.645, 0, 0.159)
double3 xformOp:scale = (0.16, 0.36, 0.018)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cylinder "DrainPlug" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.022
double radius = 0.016
color3f[] primvars:displayColor = [(0.72, 0.53, 0.24)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (-0.700, 0, 0.115)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
}
def Xform "Suction"
{
def Cylinder "Flange" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.020
double radius = 0.100
color3f[] primvars:displayColor = [(0.02, 0.22, 0.55)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.860, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "Neck" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.055
double radius = 0.051
color3f[] primvars:displayColor = [(0.02, 0.22, 0.55)]
rel material:binding = </Pump/Suction/Neck/Mat>
double3 xformOp:translate = (-0.822, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
# Own material, so the suction line can be tinted by the
# pumped fluid temperature without recolouring every other
# blue casting that shares the Looks scope.
def Material "Mat"
{
token outputs:surface.connect = </Pump/Suction/Neck/Mat/Surface.outputs:surface>
def Shader "Surface"
{
uniform token info:id = "UsdPreviewSurface"
color3f inputs:diffuseColor = (0.02, 0.22, 0.55)
float inputs:metallic = 0.1
float inputs:roughness = 0.45
token outputs:surface
}
}
}
# Cavitation indication, at the suction eye where the fault is.
# Hidden until the supervision state asserts.
def Sphere "CavitationHalo"
{
double radius = 0.090
color3f[] primvars:displayColor = [(0.95, 0.85, 0.15)]
token visibility = "invisible"
double3 xformOp:translate = (-0.845, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "BoltTop" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.034
double radius = 0.009
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.860, 0, 0.360)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "BoltBottom" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.034
double radius = 0.009
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.860, 0, 0.200)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "BoltLeft" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.034
double radius = 0.009
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.860, -0.080, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "BoltRight" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.034
double radius = 0.009
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.860, 0.080, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
}
def Xform "SuctionVessel"
{
double3 xformOp:translate = (-1.35, 0, 0)
uniform token[] xformOpOrder = ["xformOp:translate"]
def Cylinder "Shell" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 1.05
double radius = 0.30
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (0, 0, 0.525)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "Skirt" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.04
double radius = 0.32
color3f[] primvars:displayColor = [(0.30, 0.31, 0.33)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0, 0, 0.020)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
# The liquid surface. Its height above the vessel floor is driven
# by the published suction level, so the twin shows the pump
# running down its supply and refilling.
def Cylinder "Surface" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.012
double radius = 0.285
color3f[] primvars:displayColor = [(0.10, 0.42, 0.72)]
rel material:binding = </Pump/Looks/PumpBlue>
matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0.5, 1) )
uniform token[] xformOpOrder = ["xformOp:transform"]
}
def Cylinder "DownPipe" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.42
double radius = 0.040
color3f[] primvars:displayColor = [(0.02, 0.22, 0.55)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (0.28, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
}
def Xform "Discharge"
{
def Cylinder "Neck" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.150
double radius = 0.043
color3f[] primvars:displayColor = [(0.02, 0.22, 0.55)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.645, 0, 0.455)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "Flange" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.018
double radius = 0.0925
color3f[] primvars:displayColor = [(0.02, 0.22, 0.55)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.645, 0, 0.539)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "BoltFront" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.032
double radius = 0.009
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.5725, 0, 0.539)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "BoltBack" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.032
double radius = 0.009
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.7175, 0, 0.539)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "BoltLeft" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.032
double radius = 0.009
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.645, 0.0725, 0.539)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "BoltRight" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.032
double radius = 0.009
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.645, -0.0725, 0.539)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Xform "Gauge"
{
def Cylinder "Stem" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Y"
double height = 0.055
double radius = 0.007
color3f[] primvars:displayColor = [(0.55, 0.56, 0.58)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.645, 0.070, 0.470)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "Dial" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Y"
double height = 0.022
double radius = 0.041
color3f[] primvars:displayColor = [(0.90, 0.90, 0.88)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.645, 0.108, 0.470)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
# Discharge pressure needle. The binding contract drives
# xformOp:rotateZ, but this dial faces +Y, so a static rotateX
# lays the needle's local Z along the world Y axis before the
# driven rotation - the same trick the impeller uses to put a
# horizontal shaft on a rotateZ binding.
def Xform "Needle"
{
double3 xformOp:translate = (-0.645, 0.121, 0.470)
double xformOp:rotateX = 90
double xformOp:rotateZ = 0
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateX", "xformOp:rotateZ"
]
def Cube "Pointer" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.75, 0.10, 0.08)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0.015, 0, 0)
double3 xformOp:scale = (0.030, 0.0035, 0.0035)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
}
}
}
def Xform "PowerEnd"
{
def Cylinder "SealHousing" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.060
double radius = 0.046
color3f[] primvars:displayColor = [(0.02, 0.22, 0.55)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.560, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "Lantern" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.040
double radius = 0.058
color3f[] primvars:displayColor = [(0.02, 0.20, 0.50)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.510, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "Bracket" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.220
double radius = 0.0625
color3f[] primvars:displayColor = [(0.02, 0.22, 0.55)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.380, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cube "BracketFoot" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.02, 0.20, 0.50)]
rel material:binding = </Pump/Looks/PumpBlue>
double3 xformOp:translate = (-0.360, 0, 0.1875)
double3 xformOp:scale = (0.16, 0.20, 0.105)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cylinder "SightGlass" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Y"
double height = 0.020
double radius = 0.015
color3f[] primvars:displayColor = [(0.85, 0.86, 0.62)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (-0.330, 0.064, 0.245)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
# Bearing-temperature gauge on the bracket. Same rotateX trick as
# the discharge gauge: the dial faces +Y, the binding drives Z.
def Xform "TempGauge"
{
def Cylinder "Dial" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Y"
double height = 0.018
double radius = 0.032
color3f[] primvars:displayColor = [(0.90, 0.90, 0.88)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.300, 0.070, 0.345)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Xform "Needle"
{
double3 xformOp:translate = (-0.300, 0.081, 0.345)
double xformOp:rotateX = 90
double xformOp:rotateZ = 0
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateX", "xformOp:rotateZ"
]
def Cube "Pointer" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.75, 0.10, 0.08)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0.012, 0, 0)
double3 xformOp:scale = (0.024, 0.003, 0.003)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
}
}
}
def Cylinder "Bearing" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.036
double radius = 0.052
color3f[] primvars:displayColor = [(0.30, 0.31, 0.33)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (-0.300, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Sphere "OverheatHalo"
{
double radius = 0.105
color3f[] primvars:displayColor = [(1.0, 0.18, 0.08)]
token visibility = "invisible"
double3 xformOp:translate = (-0.300, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Xform "Impeller"
{
double3 xformOp:translate = (0, 0, 0.28)
double xformOp:rotateY = 90
double xformOp:rotateZ = 0
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateY", "xformOp:rotateZ"
]
custom double inputs:speedSetpoint = 0
def Cylinder "Shaft" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.760
double radius = 0.019
color3f[] primvars:displayColor = [(0.62, 0.63, 0.65)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (0, 0, -0.300)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "Shroud" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.012
double radius = 0.099
color3f[] primvars:displayColor = [(0.66, 0.48, 0.22)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (0, 0, 0.664)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "Hub" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.034
double radius = 0.030
color3f[] primvars:displayColor = [(0.66, 0.48, 0.22)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (0, 0, 0.645)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cube "VaneA" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.70, 0.52, 0.24)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (0.052, 0.014, 0.646)
double3 xformOp:rotateXYZ = (0, 0, 22)
double3 xformOp:scale = (0.086, 0.010, 0.026)
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"
]
}
def Cube "VaneB" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.70, 0.52, 0.24)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (0.014, 0.052, 0.646)
double3 xformOp:rotateXYZ = (0, 0, 82)
double3 xformOp:scale = (0.086, 0.010, 0.026)
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"
]
}
def Cube "VaneC" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.70, 0.52, 0.24)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (-0.038, 0.038, 0.646)
double3 xformOp:rotateXYZ = (0, 0, 142)
double3 xformOp:scale = (0.086, 0.010, 0.026)
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"
]
}
def Cube "VaneD" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.70, 0.52, 0.24)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (-0.052, -0.014, 0.646)
double3 xformOp:rotateXYZ = (0, 0, 202)
double3 xformOp:scale = (0.086, 0.010, 0.026)
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"
]
}
def Cube "VaneE" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.70, 0.52, 0.24)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (-0.014, -0.052, 0.646)
double3 xformOp:rotateXYZ = (0, 0, 262)
double3 xformOp:scale = (0.086, 0.010, 0.026)
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"
]
}
def Cube "VaneF" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.70, 0.52, 0.24)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (0.038, -0.038, 0.646)
double3 xformOp:rotateXYZ = (0, 0, 322)
double3 xformOp:scale = (0.086, 0.010, 0.026)
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"
]
}
def Cylinder "CouplingHubPump" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.052
double radius = 0.070
color3f[] primvars:displayColor = [(0.34, 0.35, 0.37)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0, 0, -0.196)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "CouplingSpider" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.014
double radius = 0.058
color3f[] primvars:displayColor = [(0.92, 0.66, 0.06)]
rel material:binding = </Pump/Looks/Bronze>
double3 xformOp:translate = (0, 0, -0.163)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "CouplingHubMotor" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.052
double radius = 0.070
color3f[] primvars:displayColor = [(0.34, 0.35, 0.37)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0, 0, -0.130)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cube "CouplingKey" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.94, 0.94, 0.95)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (0, 0, -0.168)
double3 xformOp:scale = (0.020, 0.140, 0.010)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
}
def Xform "CouplingGuard"
{
def Cylinder "RingPump" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.012
double radius = 0.110
color3f[] primvars:displayColor = [(0.66, 0.68, 0.70)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.264, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "RingMotor" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.012
double radius = 0.110
color3f[] primvars:displayColor = [(0.66, 0.68, 0.70)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.006, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cube "BarTop" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.66, 0.68, 0.70)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.135, 0, 0.388)
double3 xformOp:scale = (0.264, 0.030, 0.008)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "BarBottom" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.66, 0.68, 0.70)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.135, 0, 0.172)
double3 xformOp:scale = (0.264, 0.030, 0.008)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "BarLeft" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.66, 0.68, 0.70)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.135, -0.108, 0.28)
double3 xformOp:scale = (0.264, 0.008, 0.030)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "BarRight" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.66, 0.68, 0.70)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (-0.135, 0.108, 0.28)
double3 xformOp:scale = (0.264, 0.008, 0.030)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
}
def Xform "Motor"
{
def Cylinder "Frame" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.615
double radius = 0.127
color3f[] primvars:displayColor = [(0.60, 0.61, 0.60)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.3125, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "DriveEndShield" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.050
double radius = 0.132
color3f[] primvars:displayColor = [(0.55, 0.56, 0.55)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.030, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "NonDriveEndShield" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.050
double radius = 0.132
color3f[] primvars:displayColor = [(0.55, 0.56, 0.55)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.595, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "FanCowl" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "X"
double height = 0.080
double radius = 0.140
color3f[] primvars:displayColor = [(0.48, 0.49, 0.50)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.660, 0, 0.28)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
# Cooling fan inside the cowl. It sits on the motor shaft, so it
# turns with the duty point: a pump that is barely moving fluid is
# visibly loafing. Same rotateY-then-rotateZ trick as the impeller,
# because the shaft is horizontal but the binding drives Z.
def Xform "FanBlades"
{
double3 xformOp:translate = (0.660, 0, 0.28)
double xformOp:rotateY = 90
double xformOp:rotateZ = 0
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateY", "xformOp:rotateZ"
]
def Cylinder "Hub" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.030
double radius = 0.028
color3f[] primvars:displayColor = [(0.20, 0.21, 0.23)]
rel material:binding = </Pump/Looks/DarkSteel>
uniform token[] xformOpOrder = []
}
def Cube "BladeA" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.30, 0.31, 0.33)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0.055, 0, 0)
double3 xformOp:scale = (0.110, 0.028, 0.008)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "BladeB" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.30, 0.31, 0.33)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (-0.055, 0, 0)
double3 xformOp:scale = (0.110, 0.028, 0.008)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "BladeC" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.30, 0.31, 0.33)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0, 0.055, 0)
double3 xformOp:scale = (0.028, 0.110, 0.008)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "BladeD" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.30, 0.31, 0.33)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0, -0.055, 0)
double3 xformOp:scale = (0.028, 0.110, 0.008)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
}
def Cube "FinTop" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.56, 0.57, 0.56)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.3125, 0, 0.412)
double3 xformOp:scale = (0.615, 0.030, 0.024)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "FinUpperLeft" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.56, 0.57, 0.56)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.3125, -0.098, 0.372)
double3 xformOp:rotateXYZ = (40, 0, 0)
double3 xformOp:scale = (0.615, 0.024, 0.030)
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"
]
}
def Cube "FinUpperRight" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.56, 0.57, 0.56)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.3125, 0.098, 0.372)
double3 xformOp:rotateXYZ = (-40, 0, 0)
double3 xformOp:scale = (0.615, 0.024, 0.030)
uniform token[] xformOpOrder = [
"xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale"
]
}
def Cube "FinLeft" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.56, 0.57, 0.56)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.3125, -0.132, 0.28)
double3 xformOp:scale = (0.615, 0.024, 0.030)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "FinRight" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.56, 0.57, 0.56)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.3125, 0.132, 0.28)
double3 xformOp:scale = (0.615, 0.024, 0.030)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "TerminalBox" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.52, 0.53, 0.52)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.230, 0, 0.452)
double3 xformOp:scale = (0.120, 0.120, 0.080)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cylinder "CableGland" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Y"
double height = 0.040
double radius = 0.016
color3f[] primvars:displayColor = [(0.30, 0.31, 0.33)]
rel material:binding = </Pump/Looks/DarkSteel>
double3 xformOp:translate = (0.230, -0.078, 0.440)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cylinder "EyeBolt" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
uniform token axis = "Z"
double height = 0.046
double radius = 0.012
color3f[] primvars:displayColor = [(0.62, 0.63, 0.65)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (0.470, 0, 0.428)
uniform token[] xformOpOrder = ["xformOp:translate"]
}
def Cube "Nameplate" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.86, 0.87, 0.88)]
rel material:binding = </Pump/Looks/Galvanised>
double3 xformOp:translate = (0.150, -0.129, 0.318)
double3 xformOp:scale = (0.090, 0.004, 0.055)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "FootLeft" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.55, 0.56, 0.55)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.310, -0.105, 0.179)
double3 xformOp:scale = (0.300, 0.044, 0.052)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
def Cube "FootRight" (
prepend apiSchemas = ["MaterialBindingAPI"]
)
{
double size = 1.0
color3f[] primvars:displayColor = [(0.55, 0.56, 0.55)]
rel material:binding = </Pump/Looks/MotorGrey>
double3 xformOp:translate = (0.310, 0.105, 0.179)
double3 xformOp:scale = (0.300, 0.044, 0.052)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:scale"]
}
}
def Mesh "AlarmRing"
{
int[] faceVertexCounts = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
int[] faceVertexIndices = [0, 2, 3, 1, 2, 4, 5, 3, 4, 6, 7, 5, 6, 8, 9, 7, 8, 10, 11, 9, 10, 12, 13, 11, 12, 14, 15, 13, 14, 16, 17, 15, 16, 18, 19, 17, 18, 20, 21, 19, 20, 22, 23, 21, 22, 24, 25, 23, 24, 26, 27, 25, 26, 28, 29, 27, 28, 30, 31, 29, 30, 32, 33, 31, 32, 34, 35, 33, 34, 36, 37, 35, 36, 38, 39, 37, 38, 40, 41, 39, 40, 42, 43, 41, 42, 44, 45, 43, 44, 46, 47, 45, 46, 48, 49, 47, 48, 50, 51, 49, 50, 52, 53, 51, 52, 54, 55, 53, 54, 56, 57, 55, 56, 58, 59, 57, 58, 60, 61, 59, 60, 62, 63, 61, 62, 64, 65, 63, 64, 66, 67, 65, 66, 68, 69, 67, 68, 70, 71, 69, 70, 72, 73, 71, 72, 74, 75, 73, 74, 76, 77, 75, 76, 78, 79, 77, 78, 80, 81, 79, 80, 82, 83, 81, 82, 84, 85, 83, 84, 86, 87, 85, 86, 88, 89, 87, 88, 90, 91, 89, 90, 92, 93, 91, 92, 94, 95, 93, 94, 0, 1, 95]
point3f[] points = [
(1.0200, 0.0000, 0.0150), (0.8800, 0.0000, 0.0150), (1.0106, 0.1436, 0.0150), (0.8718, 0.1253, 0.0150), (0.9825, 0.2847, 0.0150), (0.8473, 0.2485, 0.0150),
(0.9363, 0.4210, 0.0150), (0.8069, 0.3674, 0.0150), (0.8726, 0.5500, 0.0150), (0.7514, 0.4800, 0.0150), (0.7927, 0.6696, 0.0150), (0.6816, 0.5844, 0.0150),
(0.6978, 0.7778, 0.0150), (0.5988, 0.6788, 0.0150), (0.5896, 0.8727, 0.0150), (0.5044, 0.7616, 0.0150), (0.4700, 0.9526, 0.0150), (0.4000, 0.8314, 0.0150),
(0.3410, 1.0163, 0.0150), (0.2874, 0.8869, 0.0150), (0.2047, 1.0625, 0.0150), (0.1685, 0.9273, 0.0150), (0.0636, 1.0906, 0.0150), (0.0453, 0.9518, 0.0150),
(-0.0800, 1.1000, 0.0150), (-0.0800, 0.9600, 0.0150), (-0.2236, 1.0906, 0.0150), (-0.2053, 0.9518, 0.0150), (-0.3647, 1.0625, 0.0150), (-0.3285, 0.9273, 0.0150),
(-0.5010, 1.0163, 0.0150), (-0.4474, 0.8869, 0.0150), (-0.6300, 0.9526, 0.0150), (-0.5600, 0.8314, 0.0150), (-0.7496, 0.8727, 0.0150), (-0.6644, 0.7616, 0.0150),
(-0.8578, 0.7778, 0.0150), (-0.7588, 0.6788, 0.0150), (-0.9527, 0.6696, 0.0150), (-0.8416, 0.5844, 0.0150), (-1.0326, 0.5500, 0.0150), (-0.9114, 0.4800, 0.0150),
(-1.0963, 0.4210, 0.0150), (-0.9669, 0.3674, 0.0150), (-1.1425, 0.2847, 0.0150), (-1.0073, 0.2485, 0.0150), (-1.1706, 0.1436, 0.0150), (-1.0318, 0.1253, 0.0150),
(-1.1800, 0.0000, 0.0150), (-1.0400, 0.0000, 0.0150), (-1.1706, -0.1436, 0.0150), (-1.0318, -0.1253, 0.0150), (-1.1425, -0.2847, 0.0150), (-1.0073, -0.2485, 0.0150),
(-1.0963, -0.4210, 0.0150), (-0.9669, -0.3674, 0.0150), (-1.0326, -0.5500, 0.0150), (-0.9114, -0.4800, 0.0150), (-0.9527, -0.6696, 0.0150), (-0.8416, -0.5844, 0.0150),
(-0.8578, -0.7778, 0.0150), (-0.7588, -0.6788, 0.0150), (-0.7496, -0.8727, 0.0150), (-0.6644, -0.7616, 0.0150), (-0.6300, -0.9526, 0.0150), (-0.5600, -0.8314, 0.0150),
(-0.5010, -1.0163, 0.0150), (-0.4474, -0.8869, 0.0150), (-0.3647, -1.0625, 0.0150), (-0.3285, -0.9273, 0.0150), (-0.2236, -1.0906, 0.0150), (-0.2053, -0.9518, 0.0150),
(-0.0800, -1.1000, 0.0150), (-0.0800, -0.9600, 0.0150), (0.0636, -1.0906, 0.0150), (0.0453, -0.9518, 0.0150), (0.2047, -1.0625, 0.0150), (0.1685, -0.9273, 0.0150),
(0.3410, -1.0163, 0.0150), (0.2874, -0.8869, 0.0150), (0.4700, -0.9526, 0.0150), (0.4000, -0.8314, 0.0150), (0.5896, -0.8727, 0.0150), (0.5044, -0.7616, 0.0150),
(0.6978, -0.7778, 0.0150), (0.5988, -0.6788, 0.0150), (0.7927, -0.6696, 0.0150), (0.6816, -0.5844, 0.0150), (0.8726, -0.5500, 0.0150), (0.7514, -0.4800, 0.0150),
(0.9363, -0.4210, 0.0150), (0.8069, -0.3674, 0.0150), (0.9825, -0.2847, 0.0150), (0.8473, -0.2485, 0.0150), (1.0106, -0.1436, 0.0150), (0.8718, -0.1253, 0.0150)
]
color3f[] primvars:displayColor = [(0.90, 0.05, 0.05)]
token visibility = "invisible"
}
}