diff --git a/src/ExampleNets/regression/Renderer/negative_tensors_normals_deubg.srn5 b/src/ExampleNets/regression/Renderer/negative_tensors_normals_deubg.srn5
new file mode 100644
index 0000000000..91ba02e7c8
--- /dev/null
+++ b/src/ExampleNets/regression/Renderer/negative_tensors_normals_deubg.srn5
@@ -0,0 +1,2288 @@
+
+
+
+
+
+
+ 6
+ 0
+ -
+ CreateFieldData:9
+
+
+ SCIRun
+ ChangeFieldData
+ CreateFieldData
+
+
+
+ 4
+ 0
+
-
+
+ BasisString
+
+
+ BasisString
+
+ 2
+ Linear
+
+
+
+ -
+
+ FormatString
+
+
+ FormatString
+
+ 2
+ Tensor
+
+
+
+ -
+
+ FunctionString
+
+
+ FunctionString
+
+ 2
+ RESULT = tensor(vector(1, 0, 0), vector(0, 1, 0), X,Y,Z);
+
+
+
+ -
+
+ ProgrammableInputPortEnabled
+
+
+ ProgrammableInputPortEnabled
+
+ 3
+ 0
+
+
+
+
+
+
+
+ -
+ CreateLatVol:3
+
+
+ SCIRun
+ NewField
+ CreateLatVol
+
+
+
+ 7
+ 0
+
-
+
+ DataAtLocation
+
+
+ DataAtLocation
+
+ 0
+ 0
+
+
+
+ -
+
+ ElementSizeNormalized
+
+
+ ElementSizeNormalized
+
+ 0
+ 0
+
+
+
+ -
+
+ PadPercent
+
+
+ PadPercent
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+ -
+
+ ProgrammableInputPortEnabled
+
+
+ ProgrammableInputPortEnabled
+
+ 3
+ 0
+
+
+
+ -
+
+ XSize
+
+
+ XSize
+
+ 0
+ 7
+
+
+
+ -
+
+ YSize
+
+
+ YSize
+
+ 0
+ 7
+
+
+
+ -
+
+ ZSize
+
+
+ ZSize
+
+ 0
+ 7
+
+
+
+
+
+
+
+ -
+ CreateStandardColorMap:1
+
+
+ SCIRun
+ Visualization
+ CreateStandardColorMap
+
+
+
+ 8
+ 0
+
-
+
+ AlphaUserPointsVector
+
+
+ AlphaUserPointsVector
+
+ 5
+
+ 0
+ 0
+
+
+
+
+ -
+
+ ColorMapInvert
+
+
+ ColorMapInvert
+
+ 3
+ 0
+
+
+
+ -
+
+ ColorMapName
+
+
+ ColorMapName
+
+ 2
+ Rainbow
+
+
+
+ -
+
+ ColorMapResolution
+
+
+ ColorMapResolution
+
+ 0
+ 8
+
+
+
+ -
+
+ ColorMapShift
+
+
+ ColorMapShift
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+ -
+
+ CustomColor0
+
+
+ CustomColor0
+
+ 2
+ Color(0.2,0.2,0.2)
+
+
+
+ -
+
+ CustomColor1
+
+
+ CustomColor1
+
+ 2
+ Color(0.8,0.8,0.8)
+
+
+
+ -
+
+ ProgrammableInputPortEnabled
+
+
+ ProgrammableInputPortEnabled
+
+ 3
+ 0
+
+
+
+
+
+
+
+ -
+ RescaleColorMap:1
+
+
+ SCIRun
+ Visualization
+ RescaleColorMap
+
+
+
+ 5
+ 0
+
-
+
+ AutoScale
+
+
+ AutoScale
+
+ 0
+ 0
+
+
+
+ -
+
+ FixedMax
+
+
+ FixedMax
+
+ 1
+ 1.00000000000000000e+00
+
+
+
+ -
+
+ FixedMin
+
+
+ FixedMin
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+ -
+
+ ProgrammableInputPortEnabled
+
+
+ ProgrammableInputPortEnabled
+
+ 3
+ 0
+
+
+
+ -
+
+ Symmetric
+
+
+ Symmetric
+
+ 3
+ 0
+
+
+
+
+
+
+
+ -
+ ShowFieldGlyphs:8
+
+
+ SCIRun
+ Visualization
+ ShowFieldGlyphs
+
+
+
+ 54
+ 0
+
-
+
+ ArrowHeadRatio
+
+
+ ArrowHeadRatio
+
+ 1
+ 5.00000000000000000e-01
+
+
+
+ -
+
+ DefaultMeshColor
+
+
+ DefaultMeshColor
+
+ 2
+ Color(0.5,0.5,0.5)
+
+
+
+ -
+
+ FieldName
+
+
+ FieldName
+
+ 2
+
+
+
+
+ -
+
+ NormalizeGlyphs
+
+
+ NormalizeGlyphs
+
+ 3
+ 0
+
+
+
+ -
+
+ NormalizeTensors
+
+
+ NormalizeTensors
+
+ 3
+ 0
+
+
+
+ -
+
+ NormalizeVectors
+
+
+ NormalizeVectors
+
+ 3
+ 0
+
+
+
+ -
+
+ ProgrammableInputPortEnabled
+
+
+ ProgrammableInputPortEnabled
+
+ 3
+ 0
+
+
+
+ -
+
+ RenderBases
+
+
+ RenderBases
+
+ 3
+ 0
+
+
+
+ -
+
+ RenderBidirectionaly
+
+
+ RenderBidirectionaly
+
+ 3
+ 0
+
+
+
+ -
+
+ RenderGlyphsBellowThreshold
+
+
+ RenderGlyphsBellowThreshold
+
+ 3
+ 1
+
+
+
+ -
+
+ RenderTensorsBelowThreshold
+
+
+ RenderTensorsBelowThreshold
+
+ 3
+ 1
+
+
+
+ -
+
+ RenderVectorsBelowThreshold
+
+
+ RenderVectorsBelowThreshold
+
+ 3
+ 1
+
+
+
+ -
+
+ ScalarsColoring
+
+
+ ScalarsColoring
+
+ 0
+ 0
+
+
+
+ -
+
+ ScalarsColoringDataInput
+
+
+ ScalarsColoringDataInput
+
+ 2
+ Primary
+
+
+
+ -
+
+ ScalarsDisplayType
+
+
+ ScalarsDisplayType
+
+ 0
+ 0
+
+
+
+ -
+
+ ScalarsResolution
+
+
+ ScalarsResolution
+
+ 0
+ 10
+
+
+
+ -
+
+ ScalarsScale
+
+
+ ScalarsScale
+
+ 1
+ 1.00000000000000000e+00
+
+
+
+ -
+
+ ScalarsThreshold
+
+
+ ScalarsThreshold
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+ -
+
+ ScalarsTransparency
+
+
+ ScalarsTransparency
+
+ 3
+ 0
+
+
+
+ -
+
+ ScalarsTransparencyValue
+
+
+ ScalarsTransparencyValue
+
+ 1
+ 6.50000000000000022e-01
+
+
+
+ -
+
+ ScalarsUniformTransparencyValue
+
+
+ ScalarsUniformTransparencyValue
+
+ 1
+ 6.50000000000000022e-01
+
+
+
+ -
+
+ SecondaryVectorParameterDataInput
+
+
+ SecondaryVectorParameterDataInput
+
+ 2
+ Primary
+
+
+
+ -
+
+ SecondaryVectorParameterScale
+
+
+ SecondaryVectorParameterScale
+
+ 1
+ 2.50000000000000000e-01
+
+
+
+ -
+
+ SecondaryVectorParameterScalingType
+
+
+ SecondaryVectorParameterScalingType
+
+ 0
+ 1
+
+
+
+ -
+
+ ShowNormals
+
+
+ ShowNormals
+
+ 3
+ 1
+
+
+
+ -
+
+ ShowNormalsScale
+
+
+ ShowNormalsScale
+
+ 1
+ 1.00000000000000006e-01
+
+
+
+ -
+
+ ShowScalarTab
+
+
+ ShowScalarTab
+
+ 3
+ 0
+
+
+
+ -
+
+ ShowScalars
+
+
+ ShowScalars
+
+ 3
+ 0
+
+
+
+ -
+
+ ShowSecondaryTab
+
+
+ ShowSecondaryTab
+
+ 3
+ 0
+
+
+
+ -
+
+ ShowTensorTab
+
+
+ ShowTensorTab
+
+ 3
+ 1
+
+
+
+ -
+
+ ShowTensors
+
+
+ ShowTensors
+
+ 3
+ 1
+
+
+
+ -
+
+ ShowTertiaryTab
+
+
+ ShowTertiaryTab
+
+ 3
+ 0
+
+
+
+ -
+
+ ShowVectorTab
+
+
+ ShowVectorTab
+
+ 3
+ 0
+
+
+
+ -
+
+ ShowVectors
+
+
+ ShowVectors
+
+ 3
+ 0
+
+
+
+ -
+
+ SuperquadricEmphasis
+
+
+ SuperquadricEmphasis
+
+ 1
+ 8.49999999999999978e-01
+
+
+
+ -
+
+ TensorsColoring
+
+
+ TensorsColoring
+
+ 2
+ Conversion to RGB
+
+
+
+ -
+
+ TensorsColoringDataInput
+
+
+ TensorsColoringDataInput
+
+ 2
+ Primary
+
+
+
+ -
+
+ TensorsDisplayType
+
+
+ TensorsDisplayType
+
+ 2
+ Ellipsoids
+
+
+
+ -
+
+ TensorsResolution
+
+
+ TensorsResolution
+
+ 0
+ 20
+
+
+
+ -
+
+ TensorsScale
+
+
+ TensorsScale
+
+ 1
+ 1.00000000000000006e-01
+
+
+
+ -
+
+ TensorsThreshold
+
+
+ TensorsThreshold
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+ -
+
+ TensorsTransparency
+
+
+ TensorsTransparency
+
+ 3
+ 0
+
+
+
+ -
+
+ TensorsTransparencyValue
+
+
+ TensorsTransparencyValue
+
+ 1
+ 6.50000000000000022e-01
+
+
+
+ -
+
+ TensorsUniformTransparencyValue
+
+
+ TensorsUniformTransparencyValue
+
+ 1
+ 6.50000000000000022e-01
+
+
+
+ -
+
+ Threshold
+
+
+ Threshold
+
+ 1
+ 1.50000000000000000e+00
+
+
+
+ -
+
+ VectorsColoring
+
+
+ VectorsColoring
+
+ 0
+ 2
+
+
+
+ -
+
+ VectorsColoringDataInput
+
+
+ VectorsColoringDataInput
+
+ 2
+ Primary
+
+
+
+ -
+
+ VectorsDisplayType
+
+
+ VectorsDisplayType
+
+ 0
+ 0
+
+
+
+ -
+
+ VectorsResolution
+
+
+ VectorsResolution
+
+ 0
+ 5
+
+
+
+ -
+
+ VectorsScale
+
+
+ VectorsScale
+
+ 1
+ 1.00000000000000000e+00
+
+
+
+ -
+
+ VectorsThreshold
+
+
+ VectorsThreshold
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+ -
+
+ VectorsTransparency
+
+
+ VectorsTransparency
+
+ 3
+ 0
+
+
+
+ -
+
+ VectorsTransparencyValue
+
+
+ VectorsTransparencyValue
+
+ 1
+ 6.50000000000000022e-01
+
+
+
+ -
+
+ VectorsUniformTransparencyValue
+
+
+ VectorsUniformTransparencyValue
+
+ 1
+ 6.50000000000000022e-01
+
+
+
+
+
+
+
+ -
+ ViewScene:10
+
+
+ SCIRun
+ Render
+ ViewScene
+
+
+
+ 60
+ 0
+
-
+
+ Ambient
+
+
+ Ambient
+
+ 1
+ 2.00000000000000011e-01
+
+
+
+ -
+
+ AxesSize
+
+
+ AxesSize
+
+ 0
+ 10
+
+
+
+ -
+
+ AxesVisible
+
+
+ AxesVisible
+
+ 3
+ 1
+
+
+
+ -
+
+ AxesX
+
+
+ AxesX
+
+ 0
+ 100
+
+
+
+ -
+
+ AxesY
+
+
+ AxesY
+
+ 0
+ 100
+
+
+
+ -
+
+ BackgroundColor
+
+
+ BackgroundColor
+
+ 2
+ Color(0,0,0)
+
+
+
+ -
+
+ CameraDistance
+
+
+ CameraDistance
+
+ 1
+ 3.00000000000000000e+00
+
+
+
+ -
+
+ CameraDistanceMinimum
+
+
+ CameraDistanceMinimum
+
+ 1
+ 1.00000000000000004e-10
+
+
+
+ -
+
+ CameraLookAt
+
+
+ CameraLookAt
+
+ 5
+
+ 3
+ 0
+
-
+ listElement
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+ listElement
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+ listElement
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+
+
+
+ -
+
+ CameraRotation
+
+
+ CameraRotation
+
+ 5
+
+ 4
+ 0
+
-
+ listElement
+
+ 1
+ 1.00000000000000000e+00
+
+
+ -
+ listElement
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+ listElement
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+ listElement
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+
+
+
+ -
+
+ ClippingPlaneD
+
+
+ ClippingPlaneD
+
+ 5
+
+ 6
+ 0
+
-
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+
+
+
+ -
+
+ ClippingPlaneEnabled
+
+
+ ClippingPlaneEnabled
+
+ 5
+
+ 6
+ 0
+
-
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+
+
+
+
+ -
+
+ ClippingPlaneNormalReversed
+
+
+ ClippingPlaneNormalReversed
+
+ 5
+
+ 6
+ 0
+
-
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+ -
+
+
+ 3
+ 0
+
+
+
+
+
+
+ -
+
+ ClippingPlaneX
+
+
+ ClippingPlaneX
+
+ 5
+
+ 6
+ 0
+
-
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+
+
+
+ -
+
+ ClippingPlaneY
+
+
+ ClippingPlaneY
+
+ 5
+
+ 6
+ 0
+
-
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+
+
+
+ -
+
+ ClippingPlaneZ
+
+
+ ClippingPlaneZ
+
+ 5
+
+ 6
+ 0
+
-
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+ -
+
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+
+
+
+ -
+
+ Diffuse
+
+
+ Diffuse
+
+ 1
+ 1.00000000000000000e+00
+
+
+
+ -
+
+ Emission
+
+
+ Emission
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+ -
+
+ FogColor
+
+
+ FogColor
+
+ 2
+ Color(0,0,1)
+
+
+
+ -
+
+ FogEnd
+
+
+ FogEnd
+
+ 1
+ 7.09999999999999964e-01
+
+
+
+ -
+
+ FogOn
+
+
+ FogOn
+
+ 3
+ 0
+
+
+
+ -
+
+ FogStart
+
+
+ FogStart
+
+ 1
+ 0.00000000000000000e+00
+
+
+
+ -
+
+ HasNewGeometry
+
+
+ HasNewGeometry
+
+ 3
+ 1
+
+
+
+ -
+
+ HeadLightAzimuth
+
+
+ HeadLightAzimuth
+
+ 0
+ 180
+
+
+
+ -
+
+ HeadLightColor
+
+
+ HeadLightColor
+
+ 2
+ Color(1,1,1)
+
+
+
+ -
+
+ HeadLightInclination
+
+
+ HeadLightInclination
+
+ 0
+ 90
+
+
+
+ -
+
+ HeadLightOn
+
+
+ HeadLightOn
+
+ 3
+ 1
+
+
+
+ -
+
+ IsExecuting
+
+
+ IsExecuting
+
+ 3
+ 0
+
+
+
+ -
+
+ IsFloating
+
+
+ IsFloating
+
+ 3
+ 0
+
+
+
+ -
+
+ Light1Azimuth
+
+
+ Light1Azimuth
+
+ 0
+ 180
+
+
+
+ -
+
+ Light1Color
+
+
+ Light1Color
+
+ 2
+ Color(1,1,1)
+
+
+
+ -
+
+ Light1Inclination
+
+
+ Light1Inclination
+
+ 0
+ 90
+
+
+
+ -
+
+ Light1On
+
+
+ Light1On
+
+ 3
+ 0
+
+
+
+ -
+
+ Light2Azimuth
+
+
+ Light2Azimuth
+
+ 0
+ 180
+
+
+
+ -
+
+ Light2Color
+
+
+ Light2Color
+
+ 2
+ Color(1,1,1)
+
+
+
+ -
+
+ Light2Inclination
+
+
+ Light2Inclination
+
+ 0
+ 90
+
+
+
+ -
+
+ Light2On
+
+
+ Light2On
+
+ 3
+ 0
+
+
+
+ -
+
+ Light3Azimuth
+
+
+ Light3Azimuth
+
+ 0
+ 180
+
+
+
+ -
+
+ Light3Color
+
+
+ Light3Color
+
+ 2
+ Color(1,1,1)
+
+
+
+ -
+
+ Light3Inclination
+
+
+ Light3Inclination
+
+ 0
+ 90
+
+
+
+ -
+
+ Light3On
+
+
+ Light3On
+
+ 3
+ 0
+
+
+
+ -
+
+ ObjectsOnly
+
+
+ ObjectsOnly
+
+ 3
+ 1
+
+
+
+ -
+
+ ProgrammableInputPortEnabled
+
+
+ ProgrammableInputPortEnabled
+
+ 3
+ 0
+
+
+
+ -
+
+ ScaleBarFontSize
+
+
+ ScaleBarFontSize
+
+ 0
+ 8
+
+
+
+ -
+
+ ScaleBarHeight
+
+
+ ScaleBarHeight
+
+ 1
+ 1.00000000000000000e+00
+
+
+
+ -
+
+ ScaleBarLength
+
+
+ ScaleBarLength
+
+ 1
+ 1.00000000000000000e+00
+
+
+
+ -
+
+ ScaleBarLineWidth
+
+
+ ScaleBarLineWidth
+
+ 1
+ 1.00000000000000000e+00
+
+
+
+ -
+
+ ScaleBarMultiplier
+
+
+ ScaleBarMultiplier
+
+ 1
+ 1.00000000000000000e+00
+
+
+
+ -
+
+ ScaleBarNumTicks
+
+
+ ScaleBarNumTicks
+
+ 0
+ 11
+
+
+
+ -
+
+ ScaleBarUnitValue
+
+
+ ScaleBarUnitValue
+
+ 2
+ mm
+
+
+
+ -
+
+ Shine
+
+
+ Shine
+
+ 1
+ 5.00000000000000000e-01
+
+
+
+ -
+
+ ShowScaleBar
+
+
+ ShowScaleBar
+
+ 3
+ 0
+
+
+
+ -
+
+ ShowViewer
+
+
+ ShowViewer
+
+ 3
+ 1
+
+
+
+ -
+
+ Specular
+
+
+ Specular
+
+ 1
+ 2.99999999999999989e-01
+
+
+
+ -
+
+ UseBGColor
+
+
+ UseBGColor
+
+ 3
+ 1
+
+
+
+ -
+
+ VisibleItemListState
+
+
+ VisibleItemListState
+
+ 5
+
+ 1
+ 0
+
-
+ graphicsItem
+
+ 5
+
+ 1
+ 0
+
-
+ ShowFieldGlyphs:8
+
+ 3
+ 1
+
+
+
+
+
+
+
+
+
+ -
+
+ WindowPositionX
+
+
+ WindowPositionX
+
+ 0
+ 882
+
+
+
+ -
+
+ WindowPositionY
+
+
+ WindowPositionY
+
+ 0
+ 565
+
+
+
+ -
+
+ WindowSizeX
+
+
+ WindowSizeX
+
+ 0
+ 1038
+
+
+
+ -
+
+ WindowSizeY
+
+
+ WindowSizeY
+
+ 0
+ 535
+
+
+
+
+
+
+
+
+
+ 6
+ 0
+ -
+ CreateFieldData:9
+
+ OutputField
+ 0
+
+ RescaleColorMap:1
+
+ Field
+ 2
+
+
+ -
+ CreateFieldData:9
+
+ OutputField
+ 0
+
+ ShowFieldGlyphs:8
+
+ PrimaryData
+ 0
+
+
+ -
+ CreateLatVol:3
+
+ OutputField
+ 0
+
+ CreateFieldData:9
+
+ InputField
+ 0
+
+
+ -
+ CreateStandardColorMap:1
+
+ ColorMapObject
+ 0
+
+ RescaleColorMap:1
+
+ ColorMapObject
+ 0
+
+
+ -
+ RescaleColorMap:1
+
+ ColorMapOutput
+ 0
+
+ ShowFieldGlyphs:8
+
+ PrimaryColorMap
+ 0
+
+
+ -
+ ShowFieldGlyphs:8
+
+ SceneGraph
+ 0
+
+ ViewScene:10
+
+ GeneralGeom
+ 0
+
+
+
+
+
+ 6
+ 0
+ -
+ CreateFieldData:9
+
+ -3.80000000000000000e+02
+ -3.04000000000000000e+02
+
+
+ -
+ CreateLatVol:3
+
+ -4.56000000000000000e+02
+ -4.56000000000000000e+02
+
+
+ -
+ CreateStandardColorMap:1
+
+ -6.84000000000000000e+02
+ -6.84000000000000000e+02
+
+
+ -
+ RescaleColorMap:1
+
+ -7.60000000000000000e+02
+ -4.56000000000000000e+02
+
+
+ -
+ ShowFieldGlyphs:8
+
+ -5.32000000000000000e+02
+ -7.60000000000000000e+01
+
+
+ -
+ ViewScene:10
+
+ -5.32000000000000000e+02
+ 3.60000000000000000e+01
+
+
+
+
+ 0
+ 0
+
+
+ 0
+ 0
+
+
+ 6
+ 0
+ -
+ CreateFieldData:9
+ -1
+
+ -
+ CreateLatVol:3
+ -1
+
+ -
+ CreateStandardColorMap:1
+ -1
+
+ -
+ RescaleColorMap:1
+ -1
+
+ -
+ ShowFieldGlyphs:8
+ -1
+
+ -
+ ViewScene:10
+ -1
+
+
+
+ 0
+ 0
+
+
+ 0
+ 0
+
+
+ 0
+ 0
+
+ 0
+
+ 0
+ 0
+
+
+
+
diff --git a/src/Graphics/Glyphs/GlyphConstructor.cc b/src/Graphics/Glyphs/GlyphConstructor.cc
index f54dabdb5b..a20d020492 100644
--- a/src/Graphics/Glyphs/GlyphConstructor.cc
+++ b/src/Graphics/Glyphs/GlyphConstructor.cc
@@ -36,235 +36,275 @@ using namespace Graphics::Datatypes;
GlyphConstructor::GlyphConstructor()
{}
+const GlyphData& GlyphConstructor::getDataConst(SpireIBO::PRIMITIVE prim) const
+{
+ switch(prim)
+ {
+ case Datatypes::SpireIBO::PRIMITIVE::POINTS:
+ return pointData_;
+ break;
+ case Datatypes::SpireIBO::PRIMITIVE::LINES:
+ return lineData_;
+ break;
+ case Datatypes::SpireIBO::PRIMITIVE::TRIANGLES:
+ return meshData_;
+ break;
+ default:
+ return meshData_;
+ break;
+ }
+}
+
+GlyphData& GlyphConstructor::getData(SpireIBO::PRIMITIVE prim)
+{
+ return const_cast(getDataConst(prim));
+}
+
void GlyphConstructor::buildObject(GeometryObjectSpire& geom, const std::string& uniqueNodeID,
const bool isTransparent, const double transparencyValue, const ColorScheme& colorScheme,
- RenderState state, const SpireIBO::PRIMITIVE& primIn, const BBox& bbox, const bool isClippable,
+ RenderState state, const BBox& bbox, const bool isClippable,
const Core::Datatypes::ColorMapHandle colorMap)
{
- bool useColor = colorScheme == ColorScheme::COLOR_IN_SITU || colorScheme == ColorScheme::COLOR_MAP;
- bool useNormals = normals_.size() == points_.size();
- int numAttributes = 3;
+ for (auto prim : {SpireIBO::PRIMITIVE::POINTS, SpireIBO::PRIMITIVE::LINES, SpireIBO::PRIMITIVE::TRIANGLES})
+ {
+ const auto& data = getDataConst(prim);
+ if (data.numVBOElements_ == 0) continue;
+ bool useColor = colorScheme == ColorScheme::COLOR_IN_SITU || colorScheme == ColorScheme::COLOR_MAP;
+ bool useNormals = data.normals_.size() == data.points_.size();
+ int numAttributes = 3;
- RenderType renderType = RenderType::RENDER_VBO_IBO;
- ColorRGB dft = state.defaultColor;
+ RenderType renderType = RenderType::RENDER_VBO_IBO;
+ ColorRGB dft = state.defaultColor;
- std::string shader = (useNormals ? "Shaders/Phong" : "Shaders/Flat");
- std::vector attribs;
- std::vector uniforms;
+ std::string shader = (useNormals ? "Shaders/Phong" : "Shaders/Flat");
+ std::vector attribs;
+ std::vector uniforms;
- attribs.push_back(SpireVBO::AttributeData("aPos", 3 * sizeof(float)));
- uniforms.push_back(SpireSubPass::Uniform("uUseClippingPlanes", isClippable));
- uniforms.push_back(SpireSubPass::Uniform("uUseFog", true));
+ attribs.push_back(SpireVBO::AttributeData("aPos", 3 * sizeof(float)));
+ uniforms.push_back(SpireSubPass::Uniform("uUseClippingPlanes", isClippable));
+ uniforms.push_back(SpireSubPass::Uniform("uUseFog", true));
- if (useNormals)
- {
- numAttributes += 3;
- attribs.push_back(SpireVBO::AttributeData("aNormal", 3 * sizeof(float)));
- uniforms.push_back(SpireSubPass::Uniform("uAmbientColor", glm::vec4(0.1f, 0.1f, 0.1f, 1.0f)));
- uniforms.push_back(SpireSubPass::Uniform("uSpecularColor", glm::vec4(0.1f, 0.1f, 0.1f, 0.1f)));
- uniforms.push_back(SpireSubPass::Uniform("uSpecularPower", 32.0f));
- }
+ if (useNormals)
+ {
+ numAttributes += 3;
+ attribs.push_back(SpireVBO::AttributeData("aNormal", 3 * sizeof(float)));
+ uniforms.push_back(SpireSubPass::Uniform("uAmbientColor", glm::vec4(0.1f, 0.1f, 0.1f, 1.0f)));
+ uniforms.push_back(SpireSubPass::Uniform("uSpecularColor", glm::vec4(0.1f, 0.1f, 0.1f, 0.1f)));
+ uniforms.push_back(SpireSubPass::Uniform("uSpecularPower", 32.0f));
+ }
- SpireText text;
- SpireTexture2D texture;
- if (useColor)
- {
- if(colorMap)
+ SpireText text;
+ SpireTexture2D texture;
+ if (useColor)
{
- numAttributes += 2;
- shader += "_ColorMap";
- attribs.push_back(SpireVBO::AttributeData("aTexCoords", 2 * sizeof(float)));
+ if(colorMap)
+ {
+ numAttributes += 2;
+ shader += "_ColorMap";
+ attribs.push_back(SpireVBO::AttributeData("aTexCoords", 2 * sizeof(float)));
- const static int colorMapResolution = 256;
- for(int i = 0; i < colorMapResolution; ++i)
+ const static int colorMapResolution = 256;
+ for(int i = 0; i < colorMapResolution; ++i)
+ {
+ ColorRGB color = colorMap->valueToColor(static_cast(i)/colorMapResolution * 2.0f - 1.0f);
+ texture.bitmap.push_back(color.r()*255.99f);
+ texture.bitmap.push_back(color.g()*255.99f);
+ texture.bitmap.push_back(color.b()*255.99f);
+ texture.bitmap.push_back(color.a()*255.99f);
+ }
+
+ texture.name = "ColorMap";
+ texture.height = 1;
+ texture.width = colorMapResolution;
+ }
+ else
{
- ColorRGB color = colorMap->valueToColor(static_cast(i)/colorMapResolution * 2.0f - 1.0f);
- texture.bitmap.push_back(color.r()*255.99f);
- texture.bitmap.push_back(color.g()*255.99f);
- texture.bitmap.push_back(color.b()*255.99f);
- texture.bitmap.push_back(color.a()*255.99f);
+ numAttributes += 4;
+ shader += "_Color";
+ attribs.push_back(SpireVBO::AttributeData("aColor", 4 * sizeof(float)));
}
-
- texture.name = "ColorMap";
- texture.height = 1;
- texture.width = colorMapResolution;
}
else
{
- numAttributes += 4;
- shader += "_Color";
- attribs.push_back(SpireVBO::AttributeData("aColor", 4 * sizeof(float)));
+ uniforms.push_back(SpireSubPass::Uniform("uDiffuseColor",
+ glm::vec4(dft.r(), dft.g(), dft.b(), static_cast(transparencyValue))));
}
- }
- else
- {
- uniforms.push_back(SpireSubPass::Uniform("uDiffuseColor",
- glm::vec4(dft.r(), dft.g(), dft.b(), static_cast(transparencyValue))));
- }
- if (isTransparent) uniforms.push_back(SpireSubPass::Uniform("uTransparency", static_cast(transparencyValue)));
+ if (isTransparent) uniforms.push_back(SpireSubPass::Uniform("uTransparency", static_cast(transparencyValue)));
- size_t pointsLeft = points_.size();
- size_t startOfPass = 0;
- int passNumber = 0;
- while(pointsLeft > 0)
- {
- std::string passID = uniqueNodeID + "_" + std::to_string(passNumber++);
- std::string vboName = passID + "VBO";
- std::string iboName = passID + "IBO";
- std::string passName = passID + "Pass";
-
- const static size_t maxPointsPerPass = 3 << 24; //must be a number divisible by 2, 3 and, 4
- uint32_t pointsInThisPass = std::min(pointsLeft, maxPointsPerPass);
- size_t endOfPass = startOfPass + pointsInThisPass;
- pointsLeft -= pointsInThisPass;
-
- size_t vboSize = static_cast(pointsInThisPass) * numAttributes * sizeof(float);
- size_t iboSize = static_cast(pointsInThisPass) * sizeof(uint32_t);
- std::shared_ptr iboBufferSPtr(new spire::VarBuffer(iboSize));
- std::shared_ptr vboBufferSPtr(new spire::VarBuffer(vboSize));
- auto iboBuffer = iboBufferSPtr.get();
- auto vboBuffer = vboBufferSPtr.get();
-
- for (auto a : indices_) if(a >= startOfPass && a < endOfPass)
- iboBuffer->write(static_cast(a - startOfPass));
-
- BBox newBBox;
- for (size_t i = startOfPass; i < endOfPass; ++i)
+ size_t pointsLeft = data.points_.size();
+ size_t startOfPass = 0;
+ int passNumber = 0;
+ while(pointsLeft > 0)
{
- auto point = points_.at(i);
- newBBox.extend(Point(point.x(), point.y(), point.z()));
- vboBuffer->write(static_cast(point.x()));
- vboBuffer->write(static_cast(point.y()));
- vboBuffer->write(static_cast(point.z()));
-
- if (useNormals)
+ std::string passID = uniqueNodeID + "_" + std::to_string(int(prim)) + "_" + std::to_string(passNumber++);
+ std::string vboName = passID + "VBO";
+ std::string iboName = passID + "IBO";
+ std::string passName = passID + "Pass";
+
+ const static size_t maxPointsPerPass = 3 << 24; //must be a number divisible by 2, 3 and, 4
+ uint32_t pointsInThisPass = std::min(pointsLeft, maxPointsPerPass);
+ size_t endOfPass = startOfPass + pointsInThisPass;
+ pointsLeft -= pointsInThisPass;
+
+ size_t vboSize = static_cast(pointsInThisPass) * numAttributes * sizeof(float);
+ size_t iboSize = static_cast(pointsInThisPass) * sizeof(uint32_t);
+ std::shared_ptr iboBufferSPtr(new spire::VarBuffer(iboSize));
+ std::shared_ptr vboBufferSPtr(new spire::VarBuffer(vboSize));
+ auto iboBuffer = iboBufferSPtr.get();
+ auto vboBuffer = vboBufferSPtr.get();
+
+ for (auto a : data.indices_) if(a >= startOfPass && a < endOfPass)
+ iboBuffer->write(static_cast(a - startOfPass));
+
+ BBox newBBox;
+ for (size_t i = startOfPass; i < endOfPass; ++i)
{
- auto normal = normals_.at(i);
- vboBuffer->write(static_cast(normal.x()));
- vboBuffer->write(static_cast(normal.y()));
- vboBuffer->write(static_cast(normal.z()));
- }
+ auto point = data.points_.at(i);
+ newBBox.extend(Point(point.x(), point.y(), point.z()));
+ vboBuffer->write(static_cast(point.x()));
+ vboBuffer->write(static_cast(point.y()));
+ vboBuffer->write(static_cast(point.z()));
- if (useColor)
- {
- auto color = colors_.at(i);
- if(!colorMap)
+ if (useNormals)
{
- vboBuffer->write(static_cast(color.r()));
- vboBuffer->write(static_cast(color.g()));
- vboBuffer->write(static_cast(color.b()));
- vboBuffer->write(static_cast(color.a()));
+ auto normal = data.normals_.at(i);
+ vboBuffer->write(static_cast(normal.x()));
+ vboBuffer->write(static_cast(normal.y()));
+ vboBuffer->write(static_cast(normal.z()));
}
- else
+
+ if (useColor)
{
- vboBuffer->write(static_cast(color.r()));
- vboBuffer->write(static_cast(color.r()));
+ auto color = data.colors_.at(i);
+ if(!colorMap)
+ {
+ vboBuffer->write(static_cast(color.r()));
+ vboBuffer->write(static_cast(color.g()));
+ vboBuffer->write(static_cast(color.b()));
+ vboBuffer->write(static_cast(color.a()));
+ }
+ else
+ {
+ vboBuffer->write(static_cast(color.r()));
+ vboBuffer->write(static_cast(color.r()));
+ }
}
}
- }
- if(!bbox.valid()) newBBox.reset();
+ if(!bbox.valid()) newBBox.reset();
- startOfPass = endOfPass;
+ startOfPass = endOfPass;
- SpireVBO geomVBO(vboName, attribs, vboBufferSPtr, numVBOElements_, newBBox, true);
- SpireIBO geomIBO(iboName, primIn, sizeof(uint32_t), iboBufferSPtr);
+ SpireVBO geomVBO(vboName, attribs, vboBufferSPtr, data.numVBOElements_, newBBox, true);
+ SpireIBO geomIBO(iboName, prim, sizeof(uint32_t), iboBufferSPtr);
- state.set(RenderState::ActionFlags::IS_ON, true);
- state.set(RenderState::ActionFlags::HAS_DATA, true);
- SpireSubPass pass(passName, vboName, iboName, shader, colorScheme, state, renderType, geomVBO, geomIBO, text, texture);
+ state.set(RenderState::ActionFlags::IS_ON, true);
+ state.set(RenderState::ActionFlags::HAS_DATA, true);
+ SpireSubPass pass(passName, vboName, iboName, shader, colorScheme, state, renderType, geomVBO, geomIBO, text, texture);
- for (const auto& uniform : uniforms) pass.addUniform(uniform);
+ for (const auto& uniform : uniforms) pass.addUniform(uniform);
- geom.vbos().push_back(geomVBO);
- geom.ibos().push_back(geomIBO);
- geom.passes().push_back(pass);
+ geom.vbos().push_back(geomVBO);
+ geom.ibos().push_back(geomIBO);
+ geom.passes().push_back(pass);
+ }
}
}
-uint32_t GlyphConstructor::setOffset()
+uint32_t GlyphConstructor::setOffset(SpireIBO::PRIMITIVE prim)
{
- offset_ = numVBOElements_;
- return offset_;
+ auto& data = getData(prim);
+ data.offset_ = data.numVBOElements_;
+ return data.offset_;
}
-bool GlyphConstructor::normalsValid() const
+bool GlyphConstructor::normalsValid(SpireIBO::PRIMITIVE prim) const
{
- return normals_.size() == points_.size();
+ const auto& data = getDataConst(prim);
+ return data.normals_.size() == data.points_.size();
}
-void GlyphConstructor::addVertex(const Vector& point, const Vector& normal, const ColorRGB& color)
+void GlyphConstructor::addVertex(SpireIBO::PRIMITIVE prim, const Vector& point, const Vector& normal, const ColorRGB& color)
{
- points_.push_back(point);
- normals_.push_back(normal);
- colors_.push_back(color);
- ++numVBOElements_;
+ auto& data = getData(prim);
+ data.points_.push_back(point);
+ data.normals_.push_back(normal);
+ data.colors_.push_back(color);
+ ++data.numVBOElements_;
}
-void GlyphConstructor::addVertex(const Vector& point, const ColorRGB& color)
+void GlyphConstructor::addVertex(SpireIBO::PRIMITIVE prim, const Vector& point, const ColorRGB& color)
{
- points_.push_back(point);
- colors_.push_back(color);
- ++numVBOElements_;
+ auto& data = getData(prim);
+ data.points_.push_back(point);
+ data.colors_.push_back(color);
+ ++data.numVBOElements_;
}
void GlyphConstructor::addLine(const Vector& point1, const Vector& point2, const ColorRGB& color1,
const ColorRGB& color2)
{
- points_.push_back(point1);
- colors_.push_back(color1);
- addLineIndex();
+ const auto prim = SpireIBO::PRIMITIVE::LINES;
+ lineData_.points_.push_back(point1);
+ lineData_.colors_.push_back(color1);
+ addLineIndex(prim);
- points_.push_back(point2);
- colors_.push_back(color2);
- addLineIndex();
+ lineData_.points_.push_back(point2);
+ lineData_.colors_.push_back(color2);
+ addLineIndex(prim);
- ++numVBOElements_;
+ ++lineData_.numVBOElements_;
}
void GlyphConstructor::addPoint(const Vector& point, const ColorRGB& color)
{
- addVertex(point, color);
- addLineIndex();
+ const auto prim = SpireIBO::PRIMITIVE::POINTS;
+ addVertex(prim, point, color);
+ addLineIndex(prim);
}
-void GlyphConstructor::addLineIndex()
+void GlyphConstructor::addLineIndex(SpireIBO::PRIMITIVE prim)
{
- indices_.push_back(lineIndex_);
- ++lineIndex_;
+ auto& data = getData(prim);
+ data.indices_.push_back(data.lineIndex_);
+ ++data.lineIndex_;
}
-void GlyphConstructor::addIndex(size_t i)
+void GlyphConstructor::addIndex(SpireIBO::PRIMITIVE prim, size_t i)
{
- indices_.push_back(i);
+ auto& data = getData(prim);
+ data.indices_.push_back(i);
}
-void GlyphConstructor::addIndexToOffset(size_t i)
+void GlyphConstructor::addIndexToOffset(SpireIBO::PRIMITIVE prim, size_t i)
{
- addIndex(i + offset_);
+ auto& data = getData(prim);
+ addIndex(prim, i + data.offset_);
}
-void GlyphConstructor::addIndices(size_t i1, size_t i2, size_t i3)
+void GlyphConstructor::addIndices(SpireIBO::PRIMITIVE prim, size_t i1, size_t i2, size_t i3)
{
- addIndex(i1);
- addIndex(i2);
- addIndex(i3);
+ addIndex(prim, i1);
+ addIndex(prim, i2);
+ addIndex(prim, i3);
}
-void GlyphConstructor::addIndicesToOffset(size_t i1, size_t i2, size_t i3)
+void GlyphConstructor::addIndicesToOffset(SpireIBO::PRIMITIVE prim, size_t i1, size_t i2, size_t i3)
{
- addIndexToOffset(i1);
- addIndexToOffset(i2);
- addIndexToOffset(i3);
+ addIndexToOffset(prim, i1);
+ addIndexToOffset(prim, i2);
+ addIndexToOffset(prim, i3);
}
-size_t GlyphConstructor::getCurrentIndex() const
+size_t GlyphConstructor::getCurrentIndex(SpireIBO::PRIMITIVE prim) const
{
- return numVBOElements_;
+ const auto& data = getDataConst(prim);
+ return data.numVBOElements_;
}
-void GlyphConstructor::popIndicesNTimes(int n)
+void GlyphConstructor::popIndicesNTimes(SpireIBO::PRIMITIVE prim, int n)
{
+ auto& data = getData(prim);
for (int i = 0; i < n; ++i)
- indices_.pop_back();
+ data.indices_.pop_back();
}
diff --git a/src/Graphics/Glyphs/GlyphConstructor.h b/src/Graphics/Glyphs/GlyphConstructor.h
index 7a22d8e4ef..c86def2688 100644
--- a/src/Graphics/Glyphs/GlyphConstructor.h
+++ b/src/Graphics/Glyphs/GlyphConstructor.h
@@ -39,6 +39,17 @@
namespace SCIRun {
namespace Graphics {
+struct SCISHARE GlyphData
+{
+ std::vector points_;
+ std::vector normals_;
+ std::vector colors_;
+ std::vector indices_;
+ size_t numVBOElements_ = 0;
+ size_t lineIndex_ = 0;
+ uint32_t offset_ = 0;
+};
+
class SCISHARE GlyphConstructor
{
public:
@@ -46,36 +57,33 @@ class SCISHARE GlyphConstructor
void buildObject(Graphics::Datatypes::GeometryObjectSpire& geom, const std::string& uniqueNodeID,
const bool isTransparent, const double transparencyValue,
const Graphics::Datatypes::ColorScheme& colorScheme, RenderState state,
- const Graphics::Datatypes::SpireIBO::PRIMITIVE& primIn,
const Core::Geometry::BBox& bbox,
const bool isClippable = true,
const Core::Datatypes::ColorMapHandle colorMap = nullptr);
- uint32_t setOffset();
- bool normalsValid() const;
- void addVertex(const Core::Geometry::Vector& point, const Core::Geometry::Vector& normal,
+ uint32_t setOffset(Datatypes::SpireIBO::PRIMITIVE prim);
+ bool normalsValid(Datatypes::SpireIBO::PRIMITIVE prim) const;
+ void addVertex(Datatypes::SpireIBO::PRIMITIVE prim, const Core::Geometry::Vector& point, const Core::Geometry::Vector& normal,
const Core::Datatypes::ColorRGB& color);
- void addVertex(const Core::Geometry::Vector& point, const Core::Datatypes::ColorRGB& color);
+ void addVertex(Datatypes::SpireIBO::PRIMITIVE prim, const Core::Geometry::Vector& point, const Core::Datatypes::ColorRGB& color);
void addLine(const Core::Geometry::Vector& point1, const Core::Geometry::Vector& point2,
const Core::Datatypes::ColorRGB& color1, const Core::Datatypes::ColorRGB& color2);
void addPoint(const Core::Geometry::Vector& point, const Core::Datatypes::ColorRGB& color);
- void addLineIndex();
- void addIndex(size_t i);
- void addIndices(size_t i1, size_t i2, size_t i3);
- void addIndicesToOffset(size_t i1, size_t i2, size_t i3);
- void addIndexToOffset(size_t i);
- size_t getCurrentIndex() const;
- void popIndicesNTimes(int n);
+ void addLineIndex(Datatypes::SpireIBO::PRIMITIVE prim);
+ void addIndex(Datatypes::SpireIBO::PRIMITIVE prim, size_t i);
+ void addIndices(Datatypes::SpireIBO::PRIMITIVE prim, size_t i1, size_t i2, size_t i3);
+ void addIndicesToOffset(Datatypes::SpireIBO::PRIMITIVE prim, size_t i1, size_t i2, size_t i3);
+ void addIndexToOffset(Datatypes::SpireIBO::PRIMITIVE prim, size_t i);
+ size_t getCurrentIndex(Datatypes::SpireIBO::PRIMITIVE prim) const;
+ void popIndicesNTimes(Datatypes::SpireIBO::PRIMITIVE prim, int n);
private:
+ const GlyphData& getDataConst(Datatypes::SpireIBO::PRIMITIVE prim) const;
+ GlyphData& getData(Datatypes::SpireIBO::PRIMITIVE prim);
+ GlyphData pointData_;
+ GlyphData lineData_;
+ GlyphData meshData_;
std::vector tables_;
- std::vector points_;
- std::vector normals_;
- std::vector colors_;
- std::vector indices_;
- size_t numVBOElements_ = 0;
- size_t lineIndex_ = 0;
- uint32_t offset_ = 0;
};
}}
diff --git a/src/Graphics/Glyphs/GlyphGeom.cc b/src/Graphics/Glyphs/GlyphGeom.cc
index b11c6e27b3..23d4199bce 100644
--- a/src/Graphics/Glyphs/GlyphGeom.cc
+++ b/src/Graphics/Glyphs/GlyphGeom.cc
@@ -45,41 +45,47 @@ GlyphGeom::GlyphGeom()
}
void GlyphGeom::buildObject(GeometryObjectSpire& geom, const std::string& uniqueNodeID,
const bool isTransparent, const double transparencyValue,
- const ColorScheme& colorScheme, RenderState state,
- const SpireIBO::PRIMITIVE& primIn, const BBox& bbox,
+ const ColorScheme& colorScheme, RenderState state, const BBox& bbox,
const bool isClippable, const Core::Datatypes::ColorMapHandle colorMap)
{
constructor_.buildObject(geom, uniqueNodeID, isTransparent, transparencyValue, colorScheme, state,
- primIn, bbox, isClippable, colorMap);
+ bbox, isClippable, colorMap);
}
void GlyphGeom::addArrow(const Point& p1, const Point& p2, double radius, double ratio, int resolution,
- const ColorRGB& color1, const ColorRGB& color2, bool render_cylinder_base, bool render_cone_base)
+ const ColorRGB& color1, const ColorRGB& color2, bool render_cylinder_base,
+ bool render_cone_base, bool showNormals, double showNormalsScale)
{
VectorGlyphBuilder builder(p1, p2);
builder.setResolution(resolution);
builder.setColor1(color1);
builder.setColor2(color2);
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateArrow(constructor_, radius, ratio, render_cylinder_base, render_cone_base);
}
-void GlyphGeom::addSphere(const Point& p, double radius, int resolution, const ColorRGB& color)
+void GlyphGeom::addSphere(const Point& p, double radius, int resolution, const ColorRGB& color,
+ bool showNormals, double showNormalsScale)
{
- generateSphere(p, radius, resolution, color);
+ generateSphere(p, radius, resolution, color, showNormals, showNormalsScale);
}
void GlyphGeom::addComet(const Point& p1, const Point& p2, double radius, int resolution,
- const ColorRGB& color1, const ColorRGB& color2, double sphere_extrusion)
+ const ColorRGB& color1, const ColorRGB& color2, double sphere_extrusion,
+ bool showNormals, double showNormalsScale)
{
VectorGlyphBuilder builder(p1, p2);
builder.setResolution(resolution);
builder.setColor1(color1);
builder.setColor2(color2);
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateComet(constructor_, radius, sphere_extrusion);
}
-void GlyphGeom::addBox(const Point& center, Dyadic3DTensor& t, double scale, ColorRGB& color, bool normalize)
+void GlyphGeom::addBox(const Point& center, Dyadic3DTensor& t, double scale, ColorRGB& color, bool normalize, bool showNormals, double showNormalsScale)
{
TensorGlyphBuilder builder(t, center);
builder.setColor(color);
@@ -87,10 +93,12 @@ void GlyphGeom::addBox(const Point& center, Dyadic3DTensor& t, double scale, Col
builder.normalizeTensor();
builder.scaleTensor(scale);
builder.makeTensorPositive();
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateBox(constructor_);
}
-void GlyphGeom::addEllipsoid(const Point& center, Dyadic3DTensor& t, double scale, int resolution, const ColorRGB& color, bool normalize)
+void GlyphGeom::addEllipsoid(const Point& center, Dyadic3DTensor& t, double scale, int resolution, const ColorRGB& color, bool normalize, bool showNormals, double showNormalsScale)
{
TensorGlyphBuilder builder(t, center);
builder.setResolution(resolution);
@@ -99,11 +107,13 @@ void GlyphGeom::addEllipsoid(const Point& center, Dyadic3DTensor& t, double scal
builder.normalizeTensor();
builder.scaleTensor(scale);
builder.makeTensorPositive();
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateEllipsoid(constructor_, false);
}
void GlyphGeom::addSuperquadricTensor(const Point& center, Dyadic3DTensor& t, double scale, int resolution,
- const ColorRGB& color, bool normalize, double emphasis)
+ const ColorRGB& color, bool normalize, double emphasis, bool showNormals, double showNormalsScale)
{
TensorGlyphBuilder builder(t, center);
builder.setResolution(resolution);
@@ -111,67 +121,81 @@ void GlyphGeom::addSuperquadricTensor(const Point& center, Dyadic3DTensor& t, do
if (normalize)
builder.normalizeTensor();
builder.scaleTensor(scale);
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateSuperquadricTensor(constructor_, emphasis);
}
void GlyphGeom::addSuperquadricSurface(const Point& center, Dyadic3DTensor& t, double scale, int resolution,
- const ColorRGB& color, double A, double B)
+ const ColorRGB& color, double A, double B, bool showNormals, double showNormalsScale)
{
TensorGlyphBuilder builder(t, center);
builder.setResolution(resolution);
builder.setColor(color);
builder.scaleTensor(scale);
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateSuperquadricSurface(constructor_, A, B);
}
void GlyphGeom::addCylinder(const Point& p1, const Point& p2, double radius, int resolution,
const ColorRGB& color1, const ColorRGB& color2,
- bool renderBase1, bool renderBase2)
+ bool showNormals, double showNormalsScale, bool renderBase1, bool renderBase2)
{
VectorGlyphBuilder builder(p1, p2);
builder.setResolution(resolution);
builder.setColor1(color1);
builder.setColor2(color2);
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateCylinder(constructor_, radius, radius, renderBase1, renderBase2);
}
void GlyphGeom::addCylinder(const Point& p1, const Point& p2, double radius1, double radius2,
int resolution, const ColorRGB& color1, const ColorRGB& color2,
- bool renderBase1, bool renderBase2)
+ bool showNormals, double showNormalsScale, bool renderBase1, bool renderBase2)
{
VectorGlyphBuilder builder(p1, p2);
builder.setResolution(resolution);
builder.setColor1(color1);
builder.setColor2(color2);
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateCylinder(constructor_, radius1, radius2, renderBase1, renderBase2);
}
void GlyphGeom::addDisk(const Point& p1, const Point& p2, double radius, int resolution,
- const ColorRGB& color1, const ColorRGB& color2)
+ const ColorRGB& color1, const ColorRGB& color2, bool showNormals, double showNormalsScale)
{
VectorGlyphBuilder builder(p1, p2);
builder.setResolution(resolution);
builder.setColor1(color1);
builder.setColor2(color2);
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateCylinder(constructor_, radius, radius, true, true);
}
void GlyphGeom::addTorus(const Point& p1, const Point& p2, double major_radius, double minor_radius, int resolution,
- const ColorRGB& color1, const ColorRGB&)
+ const ColorRGB& color1, const ColorRGB&, bool showNormals, double showNormalsScale)
{
VectorGlyphBuilder builder(p1, p2);
builder.setResolution(resolution);
builder.setColor1(color1);
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateTorus(constructor_, major_radius, minor_radius);
}
void GlyphGeom::addCone(const Point& p1, const Point& p2, double radius, int resolution,
- bool render_base, const ColorRGB& color1, const ColorRGB& color2)
+ bool render_base, const ColorRGB& color1, const ColorRGB& color2, bool showNormals, double showNormalsScale)
{
VectorGlyphBuilder builder(p1, p2);
builder.setResolution(resolution);
builder.setColor1(color1);
builder.setColor2(color2);
+ builder.setShowNormals(showNormals);
+ builder.setShowNormalsScale(showNormalsScale);
builder.generateCone(constructor_, radius, render_base);
}
@@ -179,14 +203,16 @@ void GlyphGeom::addClippingPlane(const Point& p1, const Point& p2,
const Point& p3, const Point& p4, double radius, int resolution,
const ColorRGB& color1, const ColorRGB& color2)
{
- addSphere(p1, radius, resolution, color1);
- addSphere(p2, radius, resolution, color1);
- addSphere(p3, radius, resolution, color1);
- addSphere(p4, radius, resolution, color1);
- addCylinder(p1, p2, radius, resolution, color1, color2);
- addCylinder(p2, p3, radius, resolution, color1, color2);
- addCylinder(p3, p4, radius, resolution, color1, color2);
- addCylinder(p4, p1, radius, resolution, color1, color2);
+ const bool showNormals = false;
+ const double showNormalsScale = 0.0;
+ addSphere(p1, radius, resolution, color1, showNormals, showNormalsScale);
+ addSphere(p2, radius, resolution, color1, showNormals, showNormalsScale);
+ addSphere(p3, radius, resolution, color1, showNormals, showNormalsScale);
+ addSphere(p4, radius, resolution, color1, showNormals, showNormalsScale);
+ addCylinder(p1, p2, radius, resolution, color1, color2, showNormals, showNormalsScale);
+ addCylinder(p2, p3, radius, resolution, color1, color2, showNormals, showNormalsScale);
+ addCylinder(p3, p4, radius, resolution, color1, color2, showNormals, showNormalsScale);
+ addCylinder(p4, p1, radius, resolution, color1, color2, showNormals, showNormalsScale);
}
void GlyphGeom::addPlane(const Point& p1, const Point& p2,
@@ -214,8 +240,9 @@ void GlyphGeom::addPoint(const Point& p, const ColorRGB& color)
constructor_.addPoint(Vector(p), color);
}
-void GlyphGeom::generateSphere(const Point& center, double radius, int resolution, const ColorRGB& color)
+void GlyphGeom::generateSphere(const Point& center, double radius, int resolution, const ColorRGB& color, bool showNormals, double showNormalsScale)
{
+ const auto prim = SpireIBO::PRIMITIVE::TRIANGLES;
if (resolution < 3) resolution = 3;
if (radius < 0) radius = 1.0;
double theta_inc = M_PI / resolution;
@@ -228,39 +255,47 @@ void GlyphGeom::generateSphere(const Point& center, double radius, int resolutio
for(int u = 0; u <= 2*resolution; ++u)
{
double theta = u * theta_inc;
- Vector p1 = Vector(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
- Vector p2 = Vector(sin(theta) * cos(phi + phi_inc), sin(theta) * sin(phi + phi_inc), cos(theta));
-
- constructor_.setOffset();
- constructor_.addVertex(radius * p1 + Vector(center), p1, color);
- constructor_.addVertex(radius * p2 + Vector(center), p2, color);
+ Vector n1 = Vector(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
+ Vector n2 = Vector(sin(theta) * cos(phi + phi_inc), sin(theta) * sin(phi + phi_inc), cos(theta));
+ Vector p1 = radius * n1 + Vector(center);
+ Vector p2 = radius * n2 + Vector(center);
+
+ constructor_.setOffset(prim);
+ constructor_.addVertex(prim, p1, n1, color);
+ constructor_.addVertex(prim, p2, n2, color);
+ if (showNormals)
+ {
+ constructor_.addLine(p1, showNormalsScale * n1 + p1, color, color);
+ constructor_.addLine(p2, showNormalsScale * n2 + p2, color, color);
+ }
int v1 = 1, v2 = 2;
if(u < resolution)
std::swap(v1, v2);
- constructor_.addIndicesToOffset(0, v1, v2);
- constructor_.addIndicesToOffset(v2, v1, 3);
+ constructor_.addIndicesToOffset(prim, 0, v1, v2);
+ constructor_.addIndicesToOffset(prim, v2, v1, 3);
}
- constructor_.popIndicesNTimes(6);
+ constructor_.popIndicesNTimes(prim, 6);
}
}
void GlyphGeom::generatePlane(const Point& p1, const Point& p2,
const Point& p3, const Point& p4, const ColorRGB& color)
{
+ const auto prim = SpireIBO::PRIMITIVE::TRIANGLES;
Vector n1 = Cross(p2 - p1, p4 - p1).normal();
Vector n2 = Cross(p3 - p2, p1 - p2).normal();
Vector n3 = Cross(p4 - p3, p2 - p3).normal();
Vector n4 = Cross(p1 - p4, p3 - p4).normal();
- constructor_.setOffset();
+ constructor_.setOffset(prim);
- constructor_.addVertex(Vector(p1), n1, color);
- constructor_.addVertex(Vector(p2), n2, color);
- constructor_.addVertex(Vector(p3), n3, color);
- constructor_.addVertex(Vector(p4), n4, color);
+ constructor_.addVertex(prim, Vector(p1), n1, color);
+ constructor_.addVertex(prim, Vector(p2), n2, color);
+ constructor_.addVertex(prim, Vector(p3), n3, color);
+ constructor_.addVertex(prim, Vector(p4), n4, color);
- constructor_.addIndicesToOffset(0, 1, 2);
- constructor_.addIndicesToOffset(2, 3, 0);
+ constructor_.addIndicesToOffset(prim, 0, 1, 2);
+ constructor_.addIndicesToOffset(prim, 2, 3, 0);
}
diff --git a/src/Graphics/Glyphs/GlyphGeom.h b/src/Graphics/Glyphs/GlyphGeom.h
index 242c917977..21f96bb410 100644
--- a/src/Graphics/Glyphs/GlyphGeom.h
+++ b/src/Graphics/Glyphs/GlyphGeom.h
@@ -51,43 +51,44 @@ class SCISHARE GlyphGeom
void buildObject(Datatypes::GeometryObjectSpire& geom, const std::string& uniqueNodeID,
const bool isTransparent, const double transparencyValue,
- const Datatypes::ColorScheme& colorScheme, RenderState state,
- const Datatypes::SpireIBO::PRIMITIVE& primIn, const Core::Geometry::BBox& bbox,
- const bool isClippable = true,
+ const Datatypes::ColorScheme& colorScheme, RenderState state,
+ const Core::Geometry::BBox& bbox, const bool isClippable = true,
const Core::Datatypes::ColorMapHandle colorMap = nullptr);
void addArrow(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2, double radius,
double ratio, int resolution, const Core::Datatypes::ColorRGB& color1,
const Core::Datatypes::ColorRGB& color2, bool render_cylinder_base,
- bool render_cone_base);
+ bool render_cone_base, bool showNormals, double showNormalsScale);
void addSphere(const Core::Geometry::Point& p, double radius, int resolution,
- const Core::Datatypes::ColorRGB& color);
+ const Core::Datatypes::ColorRGB& color, bool showNormals, double showNormalsScale);
void addBox(const Core::Geometry::Point& center, Core::Datatypes::Dyadic3DTensor& t, double scale,
- Core::Datatypes::ColorRGB& color, bool normalize);
+ Core::Datatypes::ColorRGB& color, bool normalize, bool showNormals, double showNormalsScale);
void addEllipsoid(const Core::Geometry::Point& center, Core::Datatypes::Dyadic3DTensor& t, double scale,
- int resolution, const Core::Datatypes::ColorRGB& color, bool normalize);
+ int resolution, const Core::Datatypes::ColorRGB& color, bool normalize, bool showNormals, double showNormalsScale);
void addSuperquadricTensor(const Core::Geometry::Point& center, Core::Datatypes::Dyadic3DTensor& t,
double scale, int resolution, const Core::Datatypes::ColorRGB& color,
- bool normalize, double emphasis);
+ bool normalize, double emphasis, bool showNormals, double showNormalsScale);
void addCylinder(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2, double radius,
int resolution, const Core::Datatypes::ColorRGB& color1,
const Core::Datatypes::ColorRGB& color2,
+ bool showNormals, double showNormalsScale,
bool renderBase1 = false, bool renderBase2 = false);
void addCylinder(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2, double radius1,
double radius2, int resolution, const Core::Datatypes::ColorRGB& color1,
const Core::Datatypes::ColorRGB& color2,
+ bool showNormals, double showNormalsScale,
bool renderBase1 = false, bool renderBase2 = false);
void addCone(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2, double radius,
int resolution, bool renderBase, const Core::Datatypes::ColorRGB& color1,
- const Core::Datatypes::ColorRGB& color2);
+ const Core::Datatypes::ColorRGB& color2, bool showNormals, double showNormalsScale);
void addDisk(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2, double radius,
int resolution, const Core::Datatypes::ColorRGB& color1,
- const Core::Datatypes::ColorRGB& color2);
+ const Core::Datatypes::ColorRGB& color2, bool showNormals, double showNormalsScale);
void addComet(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2, double radius,
int resolution, const Core::Datatypes::ColorRGB& color1,
- const Core::Datatypes::ColorRGB& color2, double sphere_extrusion);
+ const Core::Datatypes::ColorRGB& color2, double sphere_extrusion, bool showNormals, double showNormalsScale);
void addTorus(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2,
double major_radius, double minor_radius, int resolution,
- const Core::Datatypes::ColorRGB& color1, const Core::Datatypes::ColorRGB& color2);
+ const Core::Datatypes::ColorRGB& color1, const Core::Datatypes::ColorRGB& color2, bool showNormals, double showNormalsScale);
void addClippingPlane(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2,
const Core::Geometry::Point& p3, const Core::Geometry::Point& p4,
double radius, int resolution, const Core::Datatypes::ColorRGB& color1,
@@ -103,9 +104,9 @@ class SCISHARE GlyphGeom
void addPoint(const Core::Geometry::Point& p, const Core::Datatypes::ColorRGB& color);
void addSuperquadricSurface(const Core::Geometry::Point& center, Core::Datatypes::Dyadic3DTensor& t,
double scale, int resolution, const Core::Datatypes::ColorRGB& color,
- double A, double B);
+ double A, double B, bool showNormals, double showNormalsScale);
void generateSphere(const Core::Geometry::Point& center, double radius, int resolution,
- const Core::Datatypes::ColorRGB& color);
+ const Core::Datatypes::ColorRGB& color, bool showNormals, double showNormalsScale);
void generatePlane(const Core::Geometry::Point& p1, const Core::Geometry::Point& p2,
const Core::Geometry::Point& p3, const Core::Geometry::Point& p4,
const Core::Datatypes::ColorRGB& color);
diff --git a/src/Graphics/Glyphs/GlyphGeomUtility.h b/src/Graphics/Glyphs/GlyphGeomUtility.h
index 9270f7786b..11b19c7a51 100644
--- a/src/Graphics/Glyphs/GlyphGeomUtility.h
+++ b/src/Graphics/Glyphs/GlyphGeomUtility.h
@@ -56,6 +56,8 @@ class SCISHARE GlyphGeomUtility
inline double GlyphGeomUtility::spow(double e, double x)
{
+ if (std::abs(e) < 1.0e-14)
+ return 0.0;
if (e < 0.0)
return -std::pow(-e, x);
else
diff --git a/src/Graphics/Glyphs/TensorGlyphBuilder.cc b/src/Graphics/Glyphs/TensorGlyphBuilder.cc
index 658aa3ecf9..85f1a7406f 100644
--- a/src/Graphics/Glyphs/TensorGlyphBuilder.cc
+++ b/src/Graphics/Glyphs/TensorGlyphBuilder.cc
@@ -48,6 +48,16 @@ void TensorGlyphBuilder::scaleTensor(double scale)
t_ = t_ * scale;
}
+void TensorGlyphBuilder::setShowNormals(bool showNormals)
+{
+ showNormals_ = showNormals;
+}
+
+void TensorGlyphBuilder::setShowNormalsScale(double scale)
+{
+ normalDebugScale_ = scale * t_.frobeniusNorm();
+}
+
void TensorGlyphBuilder::normalizeTensor()
{
t_.normalize();
@@ -130,6 +140,7 @@ void TensorGlyphBuilder::postScaleTransorms()
void TensorGlyphBuilder::generateEllipsoid(GlyphConstructor& constructor, bool half)
{
+ const auto prim = Datatypes::SpireIBO::PRIMITIVE::TRIANGLES;
computeTransforms();
postScaleTransorms();
computeSinCosTable(half);
@@ -152,7 +163,7 @@ void TensorGlyphBuilder::generateEllipsoid(GlyphConstructor& constructor, bool h
double cosTheta = tab1_.cos(u);
// Transorm points and add to points list
- constructor.setOffset();
+ constructor.setOffset(prim);
for (int i = 0; i < 2; ++i)
{
Point point = evaluateEllipsoidPoint(sinPhi[i], cosPhi[i], sinTheta, cosTheta);
@@ -171,13 +182,15 @@ void TensorGlyphBuilder::generateEllipsoid(GlyphConstructor& constructor, bool h
normal.safe_normalize();
}
- constructor.addVertex(pVector, normal, color_);
+ constructor.addVertex(prim, pVector, normal, color_);
+ if (showNormals_)
+ constructor.addLine(pVector, pVector + normalDebugScale_ * normal, color_, color_);
}
- constructor.addIndicesToOffset(0, 1, 2);
- constructor.addIndicesToOffset(2, 1, 3);
+ constructor.addIndicesToOffset(prim, 0, 1, 2);
+ constructor.addIndicesToOffset(prim, 2, 1, 3);
}
- constructor.popIndicesNTimes(6);
+ constructor.popIndicesNTimes(prim, 6);
}
}
@@ -220,6 +233,7 @@ void TensorGlyphBuilder::generateSuperquadricSurface(GlyphConstructor& construct
void TensorGlyphBuilder::generateSuperquadricSurfacePrivate(GlyphConstructor& constructor, double A, double B)
{
+ const auto prim = Datatypes::SpireIBO::PRIMITIVE::TRIANGLES;
double cl = t_.linearCertainty();
double cp = t_.planarCertainty();
bool linear = cl >= cp;
@@ -236,7 +250,7 @@ void TensorGlyphBuilder::generateSuperquadricSurfacePrivate(GlyphConstructor& co
for (int u = 0; u < nu_; ++u)
{
- constructor.setOffset();
+ constructor.setOffset(prim);
double sinTheta = tab1_.sin(u);
double cosTheta = tab1_.cos(u);
@@ -261,14 +275,16 @@ void TensorGlyphBuilder::generateSuperquadricSurfacePrivate(GlyphConstructor& co
normal.safe_normalize();
}
- constructor.addVertex(pVector, normal, color_);
+ constructor.addVertex(prim, pVector, normal, color_);
+ if (showNormals_)
+ constructor.addLine(pVector, pVector + normalDebugScale_ * normal, color_, color_);
}
- constructor.addIndicesToOffset(0, 1, 2);
- constructor.addIndicesToOffset(2, 1, 3);
+ constructor.addIndicesToOffset(prim, 0, 1, 2);
+ constructor.addIndicesToOffset(prim, 2, 1, 3);
}
}
- constructor.popIndicesNTimes(6);
+ constructor.popIndicesNTimes(prim, 6);
}
Point TensorGlyphBuilder::evaluateSuperquadricNormal(bool linear, double sinPhi, double cosPhi,
@@ -360,13 +376,17 @@ void TensorGlyphBuilder::generateBox(GlyphConstructor& constructor)
void TensorGlyphBuilder::generateBoxSide(GlyphConstructor& constructor, const Vector& p1, const Vector& p2, const Vector& p3,
const Vector& p4, const Vector& normal)
{
- constructor.setOffset();
- constructor.addVertex(p1, normal, color_);
- constructor.addVertex(p2, normal, color_);
- constructor.addVertex(p3, normal, color_);
- constructor.addVertex(p4, normal, color_);
- constructor.addIndicesToOffset(2, 0, 3);
- constructor.addIndicesToOffset(1, 3, 0);
+ const auto prim = Datatypes::SpireIBO::PRIMITIVE::TRIANGLES;
+ constructor.setOffset(prim);
+ constructor.addVertex(prim, p1, normal, color_);
+ constructor.addVertex(prim, p2, normal, color_);
+ constructor.addVertex(prim, p3, normal, color_);
+ constructor.addVertex(prim, p4, normal, color_);
+ constructor.addIndicesToOffset(prim, 2, 0, 3);
+ constructor.addIndicesToOffset(prim, 1, 3, 0);
+ if (showNormals_)
+ for (auto& p : {p1, p2, p3, p4})
+ constructor.addLine(p, p + normalDebugScale_ * normal, color_, color_);
}
std::vector TensorGlyphBuilder::generateBoxPoints()
diff --git a/src/Graphics/Glyphs/TensorGlyphBuilder.h b/src/Graphics/Glyphs/TensorGlyphBuilder.h
index 8731632271..701d36b8f8 100644
--- a/src/Graphics/Glyphs/TensorGlyphBuilder.h
+++ b/src/Graphics/Glyphs/TensorGlyphBuilder.h
@@ -48,6 +48,8 @@ class SCISHARE TensorGlyphBuilder
void reorderTensorValues(std::vector& eigvecs, std::vector& eigvals);
void makeTensorPositive();
void normalizeTensor();
+ void setShowNormals(bool showNormals);
+ void setShowNormalsScale(double scale);
void setColor(const Core::Datatypes::ColorRGB& color);
void setResolution(double resolution);
void generateSuperquadricTensor(GlyphConstructor& constructor, double emphasis);
@@ -80,6 +82,8 @@ class SCISHARE TensorGlyphBuilder
void postScaleTransorms();
void computeSinCosTable(bool half);
+ bool showNormals_ = false;
+ double normalDebugScale_ = 0.1;
const static int DIMENSIONS_ = 3;
const static int BOX_FACE_POINTS_ = 4;
Core::Datatypes::Dyadic3DTensor t_;
diff --git a/src/Graphics/Glyphs/VectorGlyphBuilder.cc b/src/Graphics/Glyphs/VectorGlyphBuilder.cc
index 92f72fc020..7c6b44d015 100644
--- a/src/Graphics/Glyphs/VectorGlyphBuilder.cc
+++ b/src/Graphics/Glyphs/VectorGlyphBuilder.cc
@@ -67,11 +67,22 @@ void VectorGlyphBuilder::setP2(const Point& p)
p2_ = p;
}
+void VectorGlyphBuilder::setShowNormals(bool showNormals)
+{
+ showNormals_ = showNormals;
+}
+
+void VectorGlyphBuilder::setShowNormalsScale(double showNormalsScale)
+{
+ showNormalsScale_ = showNormalsScale * (p2_ - p1_).length();
+}
+
void VectorGlyphBuilder::generateCylinder(GlyphConstructor& constructor, double radius1, double radius2, bool renderBase1, bool renderBase2)
{
if (radius1 < 0) radius1 = 1.0;
if (radius2 < 0) radius2 = 1.0;
+ auto prim = Datatypes::SpireIBO::PRIMITIVE::TRIANGLES;
//generate triangles for the cylinders.
Vector n((p1_ - p2_).normal());
Vector crx = n.getArbitraryTangent();
@@ -83,13 +94,13 @@ void VectorGlyphBuilder::generateCylinder(GlyphConstructor& constructor, double
int p1_index, p2_index;
if(renderBase1)
{
- p1_index = constructor.getCurrentIndex();
- constructor.addVertex(Vector(p1_), n, color1_);
+ p1_index = constructor.getCurrentIndex(prim);
+ constructor.addVertex(prim, Vector(p1_), n, color1_);
}
if(renderBase2)
{
- p2_index = constructor.getCurrentIndex();
- constructor.addVertex(Vector(p2_), -n, color2_);
+ p2_index = constructor.getCurrentIndex(prim);
+ constructor.addVertex(prim, Vector(p2_), -n, color2_);
}
// Precalculate
@@ -97,34 +108,50 @@ void VectorGlyphBuilder::generateCylinder(GlyphConstructor& constructor, double
double strip_angle = 2. * M_PI / resolution_;
Vector p;
- auto startOffset = constructor.getCurrentIndex();
+ auto startOffset = constructor.getCurrentIndex(prim);
for (int strip = 0; strip <= resolution_; ++strip)
{
p = std::cos(strip_angle * strip) * u +
std::sin(strip_angle * strip) * crx;
p.normalize();
Vector normals((length * p + (radius2-radius1)*n).normal());
+ auto vert1 = radius1 * p + Vector(p1_);
+ auto vert2 = radius2 * p + Vector(p2_);
- constructor.setOffset();
- constructor.addVertex(radius1 * p + Vector(p1_), normals, color1_);
- constructor.addVertex(radius2 * p + Vector(p2_), normals, color2_);
- constructor.addIndicesToOffset(0, 1, points_per_loop);
- constructor.addIndicesToOffset(points_per_loop, 1, points_per_loop + 1);
+ constructor.setOffset(prim);
+ constructor.addVertex(prim, vert1, normals, color1_);
+ constructor.addVertex(prim, vert2, normals, color2_);
+ constructor.addIndicesToOffset(prim, 0, 1, points_per_loop);
+ constructor.addIndicesToOffset(prim, points_per_loop, 1, points_per_loop + 1);
if(renderBase1)
- constructor.addVertex(radius1 * p + Vector(p1_), n, color1_);
+ {
+ constructor.addVertex(prim, vert1, n, color1_);
+ if (showNormals_)
+ constructor.addLine(vert1, vert1 + showNormalsScale_ * n, color1_, color1_);
+ }
if(renderBase2)
- constructor.addVertex(radius2 * p + Vector(p2_), -n, color2_);
+ {
+ constructor.addVertex(prim, vert2, -n, color2_);
+ if (showNormals_)
+ constructor.addLine(vert2, vert2 - showNormalsScale_ * n, color2_, color2_);
+ }
+ if (showNormals_)
+ {
+ auto normScaled = showNormalsScale_ * normals;
+ constructor.addLine(vert1, vert1 + normScaled, color1_, color1_);
+ constructor.addLine(vert2, vert2 + normScaled, color2_, color2_);
+ }
}
- constructor.popIndicesNTimes(6);
+ constructor.popIndicesNTimes(prim, 6);
for (int strip = 0; strip < resolution_; ++strip)
{
int offset = strip * points_per_loop + startOffset;
if(renderBase1)
- constructor.addIndices(p1_index, offset + 2, offset + points_per_loop + 2);
+ constructor.addIndices(prim, p1_index, offset + 2, offset + points_per_loop + 2);
if(renderBase2)
- constructor.addIndices(offset + renderBase1 + 2, p2_index,
+ constructor.addIndices(prim, offset + renderBase1 + 2, p2_index,
offset + points_per_loop + renderBase1 + 2);
}
}
@@ -134,6 +161,7 @@ void VectorGlyphBuilder::generateComet(GlyphConstructor& constructor, double rad
if (radius < 0) radius = 1;
Vector dir = (p2_-p1_).normal();
+ auto prim = Datatypes::SpireIBO::PRIMITIVE::TRIANGLES;
//Generate triangles for the cone.
Vector n((p1_ - p2_).normal());
Vector crx = n.getArbitraryTangent();
@@ -161,10 +189,17 @@ void VectorGlyphBuilder::generateComet(GlyphConstructor& constructor, double rad
Vector new_point = cone_radius * p + Vector(cone_p2);
cone_rim_points.push_back(new_point);
- constructor.setOffset();
- constructor.addVertex(new_point, normals, color1_);
- constructor.addVertex(Vector(p1_), normals, color2_);
- constructor.addIndicesToOffset(0, points_per_loop, 1);
+ constructor.setOffset(prim);
+ constructor.addVertex(prim, new_point, normals, color1_);
+ constructor.addVertex(prim, Vector(p1_), normals, color2_);
+ constructor.addIndicesToOffset(prim, 0, points_per_loop, 1);
+
+ if (showNormals_)
+ {
+ auto normScaled = showNormalsScale_ * normals;
+ constructor.addLine(new_point, normScaled + new_point, color1_, color1_);
+ constructor.addLine(Vector(p1_), normScaled + Vector(p1_), color2_, color2_);
+ }
}
// Generate ellipsoid
@@ -217,24 +252,29 @@ void VectorGlyphBuilder::generateComet(GlyphConstructor& constructor, double rad
Vector norm1 = (rotate * Vector(modelVert1)).normal();
Vector norm2 = (rotate * Vector(modelVert2)).normal();
- constructor.setOffset();
+ constructor.setOffset(prim);
// Use cone points around rim of ellipsoid
if(v == nv - 2)
- constructor.addVertex(cone_rim_points[cone_rim_index++], norm1, color1_);
- else
- constructor.addVertex(vert1, norm1, color1_);
-
- constructor.addVertex(vert2, norm2, color1_);
- constructor.addIndicesToOffset(0, 1, 2);
- constructor.addIndicesToOffset(2, 1, 3);
+ vert1 = cone_rim_points[cone_rim_index++];
+
+ constructor.addVertex(prim, vert1, norm1, color1_);
+ constructor.addVertex(prim, vert2, norm2, color1_);
+ constructor.addIndicesToOffset(prim, 0, 1, 2);
+ constructor.addIndicesToOffset(prim, 2, 1, 3);
+ if (showNormals_)
+ {
+ constructor.addLine(vert1, vert1 + showNormalsScale_ * norm1, color1_, color1_);
+ constructor.addLine(vert2, vert2 + showNormalsScale_ * norm2, color2_, color2_);
+ }
}
- constructor.popIndicesNTimes(6);
+ constructor.popIndicesNTimes(prim, 6);
}
}
void VectorGlyphBuilder::generateCone(GlyphConstructor& constructor, double radius, bool renderBase)
{
+ const auto prim = Datatypes::SpireIBO::PRIMITIVE::TRIANGLES;
if (radius < 0) radius = 1;
//generate triangles for the cylinders.
@@ -244,10 +284,10 @@ void VectorGlyphBuilder::generateCone(GlyphConstructor& constructor, double radi
// Center of base
int points_per_loop = 2;
- size_t base_index = constructor.getCurrentIndex();
+ size_t base_index = constructor.getCurrentIndex(prim);
if(renderBase)
{
- constructor.addVertex(Vector(p1_), n, color1_);
+ constructor.addVertex(prim, Vector(p1_), n, color1_);
points_per_loop = 3;
}
@@ -262,22 +302,33 @@ void VectorGlyphBuilder::generateCone(GlyphConstructor& constructor, double radi
p.normalize();
Vector normals((length * p - radius * n).normal());
- auto offset = constructor.setOffset();
- constructor.addVertex(radius * p + Vector(p1_), normals, color1_);
- constructor.addVertex(Vector(p2_), normals, color2_);
- constructor.addIndicesToOffset(0, 1, points_per_loop);
+ auto offset = constructor.setOffset(prim);
+ auto vert1 = radius * p + Vector(p1_);
+ constructor.addVertex(prim, vert1, normals, color1_);
+ constructor.addVertex(prim, Vector(p2_), normals, color2_);
+ constructor.addIndicesToOffset(prim, 0, 1, points_per_loop);
if(renderBase)
{
- constructor.addVertex(radius * p + Vector(p1_), n, color1_);
- constructor.addIndices(base_index, offset + 2, offset + points_per_loop + 2);
+ auto point = radius * p + Vector(p1_);
+ constructor.addVertex(prim, point, n, color1_);
+ constructor.addIndices(prim, base_index, offset + 2, offset + points_per_loop + 2);
+ if (showNormals_)
+ constructor.addLine(Vector(point), Vector(point) + showNormalsScale_ * n, color2_, color2_);
+ }
+ if (showNormals_)
+ {
+ auto normScaled = showNormalsScale_ * normals;
+ constructor.addLine(vert1, vert1 + normScaled, color1_, color1_);
+ constructor.addLine(Vector(p2_), Vector(p2_) + normScaled, color2_, color2_);
}
}
- constructor.popIndicesNTimes(3 * (1 + renderBase));
+ constructor.popIndicesNTimes(prim, 3 * (1 + renderBase));
}
void VectorGlyphBuilder::generateTorus(GlyphConstructor& constructor, double major_radius, double minor_radius)
{
+ const auto prim = Datatypes::SpireIBO::PRIMITIVE::TRIANGLES;
int nv = resolution_;
int nu = nv + 1;
@@ -316,14 +367,19 @@ void VectorGlyphBuilder::generateTorus(GlyphConstructor& constructor, double maj
Vector norm1 = (rotate * Vector(nr1*nx, nr1*ny, z1)).normal();
Vector norm2 = (rotate * Vector(nr2*nx, nr2*ny, z2)).normal();
- constructor.setOffset();
- constructor.addVertex(vert1, norm1, color1_);
- constructor.addVertex(vert2, norm2, color1_);
- constructor.addIndicesToOffset(0, 1, 2);
- constructor.addIndicesToOffset(2, 1, 3);
+ constructor.setOffset(prim);
+ constructor.addVertex(prim, vert1, norm1, color1_);
+ constructor.addVertex(prim, vert2, norm2, color1_);
+ constructor.addIndicesToOffset(prim, 0, 1, 2);
+ constructor.addIndicesToOffset(prim, 2, 1, 3);
+ if (showNormals_)
+ {
+ constructor.addLine(Vector(vert1), Vector(vert1) + showNormalsScale_ * norm1, color1_, color1_);
+ constructor.addLine(Vector(vert2), Vector(vert2) + showNormalsScale_ * norm2, color2_, color2_);
+ }
}
}
- constructor.popIndicesNTimes(6);
+ constructor.popIndicesNTimes(prim, 6);
}
void VectorGlyphBuilder::generateArrow(GlyphConstructor& constructor, double radius, double ratio, bool render_cylinder_base, bool render_cone_base)
diff --git a/src/Graphics/Glyphs/VectorGlyphBuilder.h b/src/Graphics/Glyphs/VectorGlyphBuilder.h
index 936abf7bc2..5eb2599329 100644
--- a/src/Graphics/Glyphs/VectorGlyphBuilder.h
+++ b/src/Graphics/Glyphs/VectorGlyphBuilder.h
@@ -47,6 +47,8 @@ class SCISHARE VectorGlyphBuilder
void setColor2(const Core::Datatypes::ColorRGB& color);
void setP1(const Core::Geometry::Point& p);
void setP2(const Core::Geometry::Point& p);
+ void setShowNormals(bool showNormals);
+ void setShowNormalsScale(double showNormalsScale);
void generateCylinder(GlyphConstructor& constructor, double radius1, double radius2, bool renderBase1, bool renderBase2);
void generateComet(GlyphConstructor& constructor, double radius, double sphere_extrusion);
void generateCone(GlyphConstructor& constructor, double radius, bool renderBase);
@@ -59,6 +61,8 @@ class SCISHARE VectorGlyphBuilder
int resolution_ = 3;
Core::Datatypes::ColorRGB color1_ = {1.0, 1.0, 1.0};
Core::Datatypes::ColorRGB color2_ = {1.0, 1.0, 1.0};
+ bool showNormals_ = false;
+ double showNormalsScale_ = 0.1;
};
}}
diff --git a/src/Graphics/Widgets/GlyphFactory.cc b/src/Graphics/Widgets/GlyphFactory.cc
index bd6427b3f8..1705882c6a 100644
--- a/src/Graphics/Widgets/GlyphFactory.cc
+++ b/src/Graphics/Widgets/GlyphFactory.cc
@@ -48,12 +48,12 @@ std::string RealGlyphFactory::sphere(SphereParameters params, WidgetBase& widget
GlyphGeom glyphs;
ColorRGB node_color;
- glyphs.addSphere(params.point, params.common.scale, params.common.resolution, node_color);
+ glyphs.addSphere(params.point, params.common.scale, params.common.resolution, node_color, false, 0.0);
auto renState = getSphereRenderState(params.common.defaultColor);
glyphs.buildObject(widget, name, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY), 1.0,
- colorScheme, renState, SpireIBO::PRIMITIVE::TRIANGLES, params.common.bbox);
+ colorScheme, renState, params.common.bbox);
return name;
}
@@ -72,12 +72,12 @@ std::string RealGlyphFactory::superquadric(SuperquadricParameters params, Widget
GlyphGeom glyphs;
ColorRGB node_color;
glyphs.addSuperquadricSurface(params.point, params.tensor, params.common.scale,
- params.common.resolution, node_color, params.A, params.B);
+ params.common.resolution, node_color, params.A, params.B, false, 0.0);
auto renState = getSphereRenderState(params.common.defaultColor);
glyphs.buildObject(widget, name, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY), 1.0,
- colorScheme, renState, SpireIBO::PRIMITIVE::TRIANGLES, params.common.bbox);
+ colorScheme, renState, params.common.bbox);
return name;
}
@@ -119,12 +119,13 @@ std::string RealGlyphFactory::disk(DiskParameters params, WidgetBase& widget) co
GlyphGeom glyphs;
ColorRGB node_color;
- glyphs.addDisk(params.p1, params.p2, params.common.scale, params.common.resolution, node_color, node_color);
+ glyphs.addDisk(params.p1, params.p2, params.common.scale, params.common.resolution,
+ node_color, node_color, false, 0.0);
auto renState = getSphereRenderState(params.common.defaultColor);
glyphs.buildObject(widget, name, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY), 1.0,
- colorScheme, renState, SpireIBO::PRIMITIVE::TRIANGLES, params.common.bbox);
+ colorScheme, renState, params.common.bbox);
return name;
}
@@ -141,12 +142,13 @@ std::string RealGlyphFactory::cylinder(CylinderParameters params, WidgetBase& wi
GlyphGeom glyphs;
ColorRGB node_color;
- glyphs.addCylinder(params.p1, params.p2, params.common.scale, params.common.resolution, node_color, node_color);
+ glyphs.addCylinder(params.p1, params.p2, params.common.scale, params.common.resolution,
+ node_color, node_color, false, 0.0);
auto renState = getSphereRenderState(params.common.defaultColor);
glyphs.buildObject(widget, name, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY), 1.0,
- colorScheme, renState, SpireIBO::PRIMITIVE::TRIANGLES, params.common.bbox);
+ colorScheme, renState, params.common.bbox);
return name;
}
@@ -164,12 +166,13 @@ std::string RealGlyphFactory::cone(ConeParameters params, WidgetBase& widget) co
GlyphGeom glyphs;
ColorRGB node_color;
- glyphs.addCone(params.cylinder.p1, params.cylinder.p2, params.cylinder.common.scale, params.cylinder.common.resolution, params.renderBase, node_color, node_color);
+ glyphs.addCone(params.cylinder.p1, params.cylinder.p2, params.cylinder.common.scale,
+ params.cylinder.common.resolution, params.renderBase, node_color, node_color, false, 0.0);
auto renState = getSphereRenderState(params.cylinder.common.defaultColor);
glyphs.buildObject(widget, name, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY), 1.0,
- colorScheme, renState, SpireIBO::PRIMITIVE::TRIANGLES, params.cylinder.common.bbox);
+ colorScheme, renState, params.cylinder.common.bbox);
return name;
}
@@ -206,12 +209,13 @@ std::string RealGlyphFactory::basicBox(BasicBoundingBoxParameters params, Widget
//generate triangles for the cylinders.
for (auto edge = 0; edge < 24; edge += 2)
{
- glyphs.addCylinder(points[point_indicies[edge]], points[point_indicies[edge + 1]], params.common.scale, num_strips, ColorRGB(), ColorRGB());
+ glyphs.addCylinder(points[point_indicies[edge]], points[point_indicies[edge + 1]],
+ params.common.scale, num_strips, ColorRGB(), ColorRGB(), false, 0.0);
}
//generate triangles for the spheres
for (const auto& a : points)
{
- glyphs.addSphere(a, params.common.scale, num_strips, ColorRGB(1, 0, 0));
+ glyphs.addSphere(a, params.common.scale, num_strips, ColorRGB(1, 0, 0), false, 0.0);
}
std::stringstream ss;
@@ -231,7 +235,7 @@ std::string RealGlyphFactory::basicBox(BasicBoundingBoxParameters params, Widget
renState.set(RenderState::ActionFlags::IS_WIDGET, true);
glyphs.buildObject(widget, name, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY), 1.0,
- colorScheme, renState, SpireIBO::PRIMITIVE::TRIANGLES, params.common.bbox);
+ colorScheme, renState, params.common.bbox);
return name;
}
@@ -266,12 +270,13 @@ std::string RealGlyphFactory::box(BoundingBoxParameters params, WidgetBase& widg
//generate triangles for the cylinders.
for (auto edge = 0; edge < 24; edge += 2)
{
- glyphs.addCylinder(points[point_indicies[edge]], points[point_indicies[edge + 1]], params.common.scale, num_strips, ColorRGB(), ColorRGB());
+ glyphs.addCylinder(points[point_indicies[edge]], points[point_indicies[edge + 1]],
+ params.common.scale, num_strips, ColorRGB(), ColorRGB(), false, 0.0);
}
//generate triangles for the spheres
for (const auto& a : points)
{
- glyphs.addSphere(a, params.common.scale, num_strips, ColorRGB(1, 0, 0));
+ glyphs.addSphere(a, params.common.scale, num_strips, ColorRGB(1, 0, 0), false, 0.0);
}
std::stringstream ss;
@@ -291,7 +296,7 @@ std::string RealGlyphFactory::box(BoundingBoxParameters params, WidgetBase& widg
renState.set(RenderState::ActionFlags::IS_WIDGET, true);
glyphs.buildObject(widget, name, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY), 1.0,
- colorScheme, renState, SpireIBO::PRIMITIVE::TRIANGLES, params.common.bbox);
+ colorScheme, renState, params.common.bbox);
return name;
}
diff --git a/src/Interface/Modules/Render/ViewScene.cc b/src/Interface/Modules/Render/ViewScene.cc
index 150ed0e9ee..ff19d4a532 100644
--- a/src/Interface/Modules/Render/ViewScene.cc
+++ b/src/Interface/Modules/Render/ViewScene.cc
@@ -2145,7 +2145,7 @@ void ViewSceneDialog::buildGeometryClippingPlane(int index, bool reverseNormal,
renState.set(RenderState::ActionFlags::IS_WIDGET, true);
auto geom(makeShared(*impl_->gid_, uniqueNodeID, false));
glyphs.buildObject(*geom, uniqueNodeID, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY), 1.0,
- colorScheme, renState, SpireIBO::PRIMITIVE::TRIANGLES, BBox(Point{}, Point{}), false, nullptr);
+ colorScheme, renState, BBox(Point{}, Point{}), false, nullptr);
Graphics::GlyphGeom glyphs2;
glyphs2.addPlane(p1, p2, p3, p4, ColorRGB());
@@ -2160,7 +2160,7 @@ void ViewSceneDialog::buildGeometryClippingPlane(int index, bool reverseNormal,
renState.defaultColor = ColorRGB(1, 1, 1, 0.2);
auto geom2(makeShared(*impl_->gid_, ss.str(), false));
glyphs2.buildObject(*geom2, uniqueNodeID, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY), 0.2,
- colorScheme, renState, SpireIBO::PRIMITIVE::TRIANGLES, BBox(Point{}, Point{}), false, nullptr);
+ colorScheme, renState, BBox(Point{}, Point{}), false, nullptr);
impl_->clippingPlaneGeoms_.push_back(geom);
impl_->clippingPlaneGeoms_.push_back(geom2);
diff --git a/src/Modules/Legacy/Visualization/ShowAndEditDipoles.cc b/src/Modules/Legacy/Visualization/ShowAndEditDipoles.cc
index bd2aa54021..bcbac6c5fa 100644
--- a/src/Modules/Legacy/Visualization/ShowAndEditDipoles.cc
+++ b/src/Modules/Legacy/Visualization/ShowAndEditDipoles.cc
@@ -572,7 +572,6 @@ GeometryHandle ShowAndEditDipolesImpl::addLines()
{
auto bbox = fieldInput_->vmesh()->get_bounding_box();
- SpireIBO::PRIMITIVE primIn = SpireIBO::PRIMITIVE::LINES;
std::string idName = std::string("SAEDField") +
GeometryObject::delimiter +
state_()->getValue(Parameters::FieldName).toString()
@@ -599,7 +598,7 @@ GeometryHandle ShowAndEditDipolesImpl::addLines()
}
}
- glyphs.buildObject(*geom, idName, false, 0.5, ColorScheme::COLOR_UNIFORM, renState, primIn, bbox);
+ glyphs.buildObject(*geom, idName, false, 0.5, ColorScheme::COLOR_UNIFORM, renState, bbox);
return geom;
}
diff --git a/src/Modules/Visualization/ShowField.cc b/src/Modules/Visualization/ShowField.cc
index 87e9f89650..10cd78df3b 100644
--- a/src/Modules/Visualization/ShowField.cc
+++ b/src/Modules/Visualization/ShowField.cc
@@ -867,11 +867,6 @@ void GeometryBuilder::renderNodes(
nodeTransparencyValue_ = static_cast(state_->getValue(NodeTransparencyValue).toDouble());
- SpireIBO::PRIMITIVE primIn = SpireIBO::PRIMITIVE::POINTS;
- // Use spheres...
- if (state.get(RenderState::ActionFlags::USE_SPHERE))
- primIn = SpireIBO::PRIMITIVE::TRIANGLES;
-
GlyphGeom glyphs;
while (eiter != eiter_end)
{
@@ -900,7 +895,7 @@ void GeometryBuilder::renderNodes(
//accumulate VBO or IBO data
if (state.get(RenderState::ActionFlags::USE_SPHERE))
{
- glyphs.addSphere(p, radius, num_strips, node_color);
+ glyphs.addSphere(p, radius, num_strips, node_color, false, 0.0);
}
else
{
@@ -911,7 +906,7 @@ void GeometryBuilder::renderNodes(
}
glyphs.buildObject(*geom, uniqueNodeID, state.get(RenderState::ActionFlags::USE_TRANSPARENT_NODES), nodeTransparencyValue_,
- colorScheme, state, primIn, mesh->get_bounding_box(), true, textureMap);
+ colorScheme, state, mesh->get_bounding_box(), true, textureMap);
}
@@ -961,11 +956,6 @@ void GeometryBuilder::renderEdges(
std::string uniqueNodeID = id + "edge" + ss.str();
- SpireIBO::PRIMITIVE primIn = SpireIBO::PRIMITIVE::LINES;
- // Use cylinders...
- if (state.get(RenderState::ActionFlags::USE_CYLINDER))
- primIn = SpireIBO::PRIMITIVE::TRIANGLES;
-
GlyphGeom glyphs;
while (eiter != eiter_end)
{
@@ -1034,9 +1024,9 @@ void GeometryBuilder::renderEdges(
{
if (state.get(RenderState::ActionFlags::USE_CYLINDER))
{
- glyphs.addCylinder(p0, p1, radius, num_strips, edge_colors[0], edge_colors[1]);
- glyphs.addSphere(p0, radius, num_strips, edge_colors[0]);
- glyphs.addSphere(p1, radius, num_strips, edge_colors[1]);
+ glyphs.addCylinder(p0, p1, radius, num_strips, edge_colors[0], edge_colors[1], false, 0.0);
+ glyphs.addSphere(p0, radius, num_strips, edge_colors[0], false, 0.0);
+ glyphs.addSphere(p1, radius, num_strips, edge_colors[1], false, 0.0);
}
else
{
@@ -1048,7 +1038,7 @@ void GeometryBuilder::renderEdges(
}
glyphs.buildObject(*geom, uniqueNodeID, state.get(RenderState::ActionFlags::USE_TRANSPARENT_EDGES), edgeTransparencyValue_,
- colorScheme, state, primIn, mesh->get_bounding_box(), true, textureMap);
+ colorScheme, state, mesh->get_bounding_box(), true, textureMap);
}
void ShowField::updateAvailableRenderOptions(FieldHandle field)
diff --git a/src/Modules/Visualization/ShowFieldGlyphs.cc b/src/Modules/Visualization/ShowFieldGlyphs.cc
index 9d2a886a7e..bd5cb8828d 100644
--- a/src/Modules/Visualization/ShowFieldGlyphs.cc
+++ b/src/Modules/Visualization/ShowFieldGlyphs.cc
@@ -124,6 +124,8 @@ namespace SCIRun {
int resolution,
ColorRGB& node_color,
bool use_lines,
+ bool show_normals,
+ double show_normals_scale,
bool render_base1,
bool render_base2);
@@ -173,6 +175,8 @@ void GlyphBuilder::addGlyph(
int resolution,
ColorRGB& node_color,
bool use_lines,
+ bool show_normals,
+ double show_normals_scale,
bool render_base1 = false,
bool render_base2 = false)
{
@@ -189,26 +193,31 @@ void GlyphBuilder::addGlyph(
case RenderState::GlyphType::COMET_GLYPH:
{
static const double sphere_extrusion = 0.0625f;
- glyphs.addComet(p1-(dir*scale), p1, scaled_radius, resolution, node_color, node_color, sphere_extrusion);
+ glyphs.addComet(p1-(dir*scale), p1, scaled_radius, resolution, node_color, node_color,
+ sphere_extrusion, show_normals, show_normals_scale);
break;
}
case RenderState::GlyphType::CONE_GLYPH:
- glyphs.addCone(p1, p2, scaled_radius, resolution, render_base1, node_color, node_color);
+ glyphs.addCone(p1, p2, scaled_radius, resolution, render_base1, node_color, node_color,
+ show_normals, show_normals_scale);
break;
case RenderState::GlyphType::ARROW_GLYPH:
- glyphs.addArrow(p1, p2, scaled_radius, ratio, resolution, node_color, node_color, render_base1, render_base2);
+ glyphs.addArrow(p1, p2, scaled_radius, ratio, resolution, node_color, node_color,
+ render_base1, render_base2, show_normals, show_normals_scale);
break;
case RenderState::GlyphType::DISK_GLYPH:
{
Point new_p2 = p1 + dir.normal() * scaled_radius * 2.0;
double new_radius = dir.length() * scale * 0.5;
- glyphs.addDisk(p1, new_p2, new_radius, resolution, node_color, node_color);
+ glyphs.addDisk(p1, new_p2, new_radius, resolution, node_color, node_color,
+ show_normals, show_normals_scale);
break;
}
case RenderState::GlyphType::RING_GLYPH:
{
double major_radius = dir.length() * scale * 0.5;
- glyphs.addTorus(p1, p2, major_radius, scaled_radius, resolution, node_color, node_color);
+ glyphs.addTorus(p1, p2, major_radius, scaled_radius, resolution, node_color, node_color,
+ show_normals, show_normals_scale);
break;
}
case RenderState::GlyphType::SPRING_GLYPH:
@@ -217,7 +226,8 @@ void GlyphBuilder::addGlyph(
if (use_lines)
glyphs.addLine(p1, p2, node_color, node_color);
else
- glyphs.addArrow(p1, p2, scaled_radius, ratio, resolution, node_color, node_color, render_base1, render_base2);
+ glyphs.addArrow(p1, p2, scaled_radius, ratio, resolution, node_color, node_color,
+ render_base1, render_base2, show_normals, show_normals_scale);
}
}
@@ -240,6 +250,8 @@ void ShowFieldGlyphs::setStateDefaults()
// General Options
state->setValue(DefaultMeshColor, ColorRGB(0.5, 0.5, 0.5).toString());
state->setValue(FieldName, std::string());
+ state->setValue(ShowNormals, false);
+ state->setValue(ShowNormalsScale, 0.1);
// Vectors
state->setValue(ShowVectorTab, false);
@@ -509,13 +521,6 @@ void GlyphBuilder::renderVectors(
bool useLines = renState.mGlyphType == RenderState::GlyphType::LINE_GLYPH || renState.mGlyphType == RenderState::GlyphType::NEEDLE_GLYPH;
- SpireIBO::PRIMITIVE primIn = SpireIBO::PRIMITIVE::TRIANGLES;
- // Use Lines
- if (useLines)
- {
- primIn = SpireIBO::PRIMITIVE::LINES;
- }
-
// Gets user set data
ColorScheme colorScheme = portHandler_->getColorScheme();
double scale = state->getValue(ShowFieldGlyphs::VectorsScale).toDouble();
@@ -528,6 +533,8 @@ void GlyphBuilder::renderVectors(
bool renderBases = state->getValue(ShowFieldGlyphs::RenderBases).toBool();
bool renderGlphysBelowThreshold = state->getValue(ShowFieldGlyphs::RenderVectorsBelowThreshold).toBool();
float threshold = state->getValue(ShowFieldGlyphs::VectorsThreshold).toDouble();
+ auto showNormals = state->getValue(ShowFieldGlyphs::ShowNormals).toBool();
+ auto showNormalsScale = state->getValue(ShowFieldGlyphs::ShowNormalsScale).toDouble();
// Make sure scale and resolution are not below minimum values
if (scale < 0) scale = 1.0;
@@ -572,13 +579,13 @@ void GlyphBuilder::renderVectors(
// No need to render cylinder base if arrow is bidirectional
bool render_cylinder_base = renderBases && !renderBidirectionaly;
addGlyph(glyphs, renState.mGlyphType, points[i], dir, radius, scale, arrowHeadRatio,
- resolution, node_color, useLines, render_cylinder_base, renderBases);
+ resolution, node_color, useLines, showNormals, showNormalsScale, render_cylinder_base, renderBases);
if(renderBidirectionaly)
{
Vector neg_dir = -dir;
addGlyph(glyphs, renState.mGlyphType, points[i], neg_dir, radius, scale, arrowHeadRatio,
- resolution, node_color, useLines, render_cylinder_base, renderBases);
+ resolution, node_color, useLines, showNormals, showNormalsScale, render_cylinder_base, renderBases);
}
}
}
@@ -590,7 +597,7 @@ void GlyphBuilder::renderVectors(
glyphs.buildObject(*geom, uniqueNodeID, renState.get(RenderState::ActionFlags::USE_TRANSPARENT_EDGES),
state->getValue(ShowFieldGlyphs::VectorsUniformTransparencyValue).toDouble(),
- colorScheme, renState, primIn, mesh->get_bounding_box(), true, portHandler_->getTextureMap());
+ colorScheme, renState, mesh->get_bounding_box(), true, portHandler_->getTextureMap());
}
void GlyphBuilder::renderScalars(
@@ -606,18 +613,13 @@ void GlyphBuilder::renderScalars(
ColorScheme colorScheme = portHandler_->getColorScheme();
double scale = state->getValue(ShowFieldGlyphs::ScalarsScale).toDouble();
int resolution = state->getValue(ShowFieldGlyphs::ScalarsResolution).toInt();
+ auto showNormals = state->getValue(ShowFieldGlyphs::ShowNormals).toBool();
+ auto showNormalsScale = state->getValue(ShowFieldGlyphs::ShowNormalsScale).toDouble();
if (scale < 0) scale = 1.0;
if (resolution < 3) resolution = 5;
bool usePoints = renState.mGlyphType == RenderState::GlyphType::POINT_GLYPH;
- SpireIBO::PRIMITIVE primIn = SpireIBO::PRIMITIVE::TRIANGLES;;
- // Use Points
- if (usePoints)
- {
- primIn = SpireIBO::PRIMITIVE::POINTS;
- }
-
auto indices = std::vector();
auto points = std::vector();
getPoints(mesh, indices, points);
@@ -637,7 +639,7 @@ void GlyphBuilder::renderScalars(
glyphs.addPoint(points[i], node_color);
break;
case RenderState::GlyphType::SPHERE_GLYPH:
- glyphs.addSphere(points[i], radius, resolution, node_color);
+ glyphs.addSphere(points[i], radius, resolution, node_color, showNormals, showNormalsScale);
break;
case RenderState::GlyphType::BOX_GLYPH:
BOOST_THROW_EXCEPTION(AlgorithmInputException() << ErrorMessage("Box Geom is not supported yet."));
@@ -647,7 +649,7 @@ void GlyphBuilder::renderScalars(
if (usePoints)
glyphs.addPoint(points[i], node_color);
else
- glyphs.addSphere(points[i], radius, resolution, node_color);
+ glyphs.addSphere(points[i], radius, resolution, node_color, showNormals, showNormalsScale);
break;
}
}
@@ -659,7 +661,7 @@ void GlyphBuilder::renderScalars(
glyphs.buildObject(*geom, uniqueNodeID, renState.get(RenderState::ActionFlags::USE_TRANSPARENT_NODES),
state->getValue(ShowFieldGlyphs::ScalarsUniformTransparencyValue).toDouble(),
- colorScheme, renState, primIn, mesh->get_bounding_box(), true,
+ colorScheme, renState, mesh->get_bounding_box(), true,
portHandler_->getTextureMap());
}
@@ -705,17 +707,14 @@ void GlyphBuilder::renderTensors(
std::string uniqueLineID = id + "tensor_line_glyphs" + ss.str();
std::string uniquePointID = id + "tensor_point_glyphs" + ss.str();
- SpireIBO::PRIMITIVE primIn = SpireIBO::PRIMITIVE::TRIANGLES;
-
- GlyphGeom tensor_line_glyphs;
- GlyphGeom point_glyphs;
-
int neg_eigval_count = 0;
int tensorcount = 0;
static const double vectorThreshold = 0.001;
static const double pointThreshold = 0.01;
static const double epsilon = pow(2, -52);
+ auto showNormals = state->getValue(ShowFieldGlyphs::ShowNormals).toBool();
+ auto showNormalsScale = state->getValue(ShowFieldGlyphs::ShowNormalsScale).toDouble();
GlyphGeom glyphs;
// Render every item from facade
for (int i = 0; i < indices.size(); i++)
@@ -751,7 +750,7 @@ void GlyphBuilder::renderTensors(
if (order0Tensor)
{
- point_glyphs.addPoint(points[i], node_color);
+ glyphs.addPoint(points[i], node_color);
}
else if (order1Tensor)
{
@@ -764,7 +763,7 @@ void GlyphBuilder::renderTensors(
dir = eigvec2 * eigvals[1];
// Point p1 = points[i];
// Point p2 = points[i] + dir;
- addGlyph(tensor_line_glyphs, RenderState::GlyphType::LINE_GLYPH, points[i], dir, scale, scale, scale, resolution, node_color, true);
+ addGlyph(glyphs, RenderState::GlyphType::LINE_GLYPH, points[i], dir, scale, scale, scale, resolution, node_color, true, showNormals, showNormalsScale);
}
// Render as order 2 or 3 tensor
else
@@ -773,18 +772,18 @@ void GlyphBuilder::renderTensors(
switch (renState.mGlyphType)
{
case RenderState::GlyphType::BOX_GLYPH:
- glyphs.addBox(points[i], newT, scale, node_color, normalizeGlyphs);
+ glyphs.addBox(points[i], newT, scale, node_color, normalizeGlyphs, showNormals, showNormalsScale);
break;
case RenderState::GlyphType::ELLIPSOID_GLYPH:
- glyphs.addEllipsoid(points[i], newT, scale, resolution, node_color, normalizeGlyphs);
+ glyphs.addEllipsoid(points[i], newT, scale, resolution, node_color, normalizeGlyphs, showNormals, showNormalsScale);
break;
case RenderState::GlyphType::SUPERQUADRIC_TENSOR_GLYPH:
{
double emphasis = state->getValue(ShowFieldGlyphs::SuperquadricEmphasis).toDouble();
if(emphasis > 0.0)
- glyphs.addSuperquadricTensor(points[i], newT, scale, resolution, node_color, normalizeGlyphs, emphasis);
+ glyphs.addSuperquadricTensor(points[i], newT, scale, resolution, node_color, normalizeGlyphs, emphasis, showNormals, showNormalsScale);
else
- glyphs.addEllipsoid(points[i], newT, scale, resolution, node_color, normalizeGlyphs);
+ glyphs.addEllipsoid(points[i], newT, scale, resolution, node_color, normalizeGlyphs, showNormals, showNormalsScale);
}
default:
break;
@@ -801,22 +800,8 @@ void GlyphBuilder::renderTensors(
glyphs.buildObject(*geom, uniqueNodeID, renState.get(RenderState::ActionFlags::USE_TRANSPARENCY),
state->getValue(ShowFieldGlyphs::TensorsUniformTransparencyValue).toDouble(),
- colorScheme, renState, primIn, mesh->get_bounding_box(), true,
+ colorScheme, renState, mesh->get_bounding_box(), true,
portHandler_->getTextureMap());
-
- // Render lines(2 eigenvalues equaling 0)
- RenderState lineRenState = getVectorsRenderState(state);
- tensor_line_glyphs.buildObject(*geom, uniqueLineID, lineRenState.get(RenderState::ActionFlags::USE_TRANSPARENT_EDGES),
- state->getValue(ShowFieldGlyphs::TensorsUniformTransparencyValue).toDouble(),
- colorScheme, lineRenState, SpireIBO::PRIMITIVE::LINES, mesh->get_bounding_box(),
- true, portHandler_->getTextureMap());
-
- // Render scalars(3 eigenvalues equaling 0)
- RenderState pointRenState = getScalarsRenderState(state);
- point_glyphs.buildObject(*geom, uniquePointID, pointRenState.get(RenderState::ActionFlags::USE_TRANSPARENT_NODES),
- state->getValue(ShowFieldGlyphs::TensorsUniformTransparencyValue).toDouble(),
- colorScheme, pointRenState, SpireIBO::PRIMITIVE::POINTS, mesh->get_bounding_box(),
- true, portHandler_->getTextureMap());
}
void ShowFieldGlyphs::setSuperquadricEmphasis(int emphasis)
@@ -1010,6 +995,8 @@ RenderState GlyphBuilder::getTensorsRenderState(ModuleStateHandle state)
}
const AlgorithmParameterName ShowFieldGlyphs::FieldName("FieldName");
+const AlgorithmParameterName ShowFieldGlyphs::ShowNormals("ShowNormals");
+const AlgorithmParameterName ShowFieldGlyphs::ShowNormalsScale("ShowNormalsScale");
// Mesh Color
const AlgorithmParameterName ShowFieldGlyphs::DefaultMeshColor("DefaultMeshColor");
// Vector Controls
diff --git a/src/Modules/Visualization/ShowFieldGlyphs.h b/src/Modules/Visualization/ShowFieldGlyphs.h
index 90a7e15bc3..79979649e2 100644
--- a/src/Modules/Visualization/ShowFieldGlyphs.h
+++ b/src/Modules/Visualization/ShowFieldGlyphs.h
@@ -52,6 +52,8 @@ namespace SCIRun {
static const Core::Algorithms::AlgorithmParameterName FieldName;
// Mesh Color
static const Core::Algorithms::AlgorithmParameterName DefaultMeshColor;
+ static const Core::Algorithms::AlgorithmParameterName ShowNormals;
+ static const Core::Algorithms::AlgorithmParameterName ShowNormalsScale;
// Vector Controls
static const Core::Algorithms::AlgorithmParameterName ShowVectorTab;
static const Core::Algorithms::AlgorithmParameterName ShowVectors;
diff --git a/src/Modules/Visualization/ShowMeshBoundingBox.cc b/src/Modules/Visualization/ShowMeshBoundingBox.cc
index 376194e338..e90588a92f 100644
--- a/src/Modules/Visualization/ShowMeshBoundingBox.cc
+++ b/src/Modules/Visualization/ShowMeshBoundingBox.cc
@@ -154,7 +154,7 @@ GeometryHandle ShowMeshBoundingBoxImpl::makeGeometry(const GeometryIDGenerator&
auto geom(makeShared(idGen, "ShowMeshBoundingBox", true));
glyphs.buildObject(*geom, geom->uniqueID(), false, 1.0, ColorScheme::COLOR_IN_SITU,
- getRenderState(), SpireIBO::PRIMITIVE::LINES, bbox_, true, nullptr);
+ getRenderState(), bbox_, true, nullptr);
return geom;
}
diff --git a/src/Modules/Visualization/ShowOrientationAxes.cc b/src/Modules/Visualization/ShowOrientationAxes.cc
index 774a86fcd6..3d3434aed3 100644
--- a/src/Modules/Visualization/ShowOrientationAxes.cc
+++ b/src/Modules/Visualization/ShowOrientationAxes.cc
@@ -134,19 +134,19 @@ void ShowOrientationAxesImpl::addOrientationArrows(GlyphGeom& glyphs, const Poin
// Positive
glyphs.addArrow(pos, pos + Vector(vectorLength, 0, 0), radius, ARROW_RATIO_, RESOLUTION_,
- RED_, RED_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_);
+ RED_, RED_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_, false, 0.0);
glyphs.addArrow(pos, pos + Vector(0, vectorLength, 0), radius, ARROW_RATIO_, RESOLUTION_,
- GREEN_, GREEN_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_);
+ GREEN_, GREEN_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_, false, 0.0);
glyphs.addArrow(pos, pos + Vector(0, 0, vectorLength), radius, ARROW_RATIO_, RESOLUTION_,
- BLUE_, BLUE_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_);
+ BLUE_, BLUE_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_, false, 0.0);
// Negative
glyphs.addArrow(pos, pos - Vector(vectorLength, 0, 0), radius, ARROW_RATIO_, RESOLUTION_,
- RED_NEGATIVE_, RED_NEGATIVE_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_);
+ RED_NEGATIVE_, RED_NEGATIVE_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_, false, 0.0);
glyphs.addArrow(pos, pos - Vector(0, vectorLength, 0), radius, ARROW_RATIO_, RESOLUTION_,
- GREEN_NEGATIVE_, GREEN_NEGATIVE_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_);
+ GREEN_NEGATIVE_, GREEN_NEGATIVE_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_, false, 0.0);
glyphs.addArrow(pos, pos - Vector(0, 0, vectorLength), radius, ARROW_RATIO_, RESOLUTION_,
- BLUE_NEGATIVE_, BLUE_NEGATIVE_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_);
+ BLUE_NEGATIVE_, BLUE_NEGATIVE_, RENDER_CYLINDER_BASE_, RENDER_CONE_BASE_, false, 0.0);
}
BBox ShowOrientationAxesImpl::getBBox(const Point& pos) const
@@ -172,7 +172,7 @@ GeometryHandle ShowOrientationAxesImpl::makeGeometry(const GeometryIDGenerator&
auto geom(makeShared(idGen, "ShowOrientationAxes", true));
glyphs.buildObject(*geom, geom->uniqueID(), false, 1.0, ColorScheme::COLOR_IN_SITU,
- getRenderState(), SpireIBO::PRIMITIVE::TRIANGLES, bbox, true, nullptr);
+ getRenderState(), bbox, true, nullptr);
return geom;
}