ArcGIS Pro 3.4 API Reference Guide
ArcGIS.Desktop.Mapping.Voxel Namespace / SectionDefinition Class / Normal Property
Example Version

Normal Property (SectionDefinition)
Gets and sets the section normal.
Syntax
public Coordinate3D Normal {get; set;}
Remarks
The Normal is a unit vector (x, y, z)
Example
Create a Section at the Voxel MidPoint
//var voxelLayer = ... ;
//Must be on the QueuedTask.Run()

if (voxelLayer.Visualization != VoxelVisualization.Surface)
    voxelLayer.SetVisualization(VoxelVisualization.Surface);
voxelLayer.SetSectionContainerExpanded(true);
voxelLayer.SetSectionContainerVisibility(true);

//To stop the Voxel Exploration Dockpane activating use:
voxelLayer.AutoShowExploreDockPane = false;
//This is useful if u have your own dockpane currently activated...
//Normally, it would be set in your dockpane

//Create a section that cuts the volume in two on the vertical plane

//At 2.x - var volume = voxelLayer.GetVolumeSize();

//Use the SelectedVariableProfile to get the sections
//via its associated volume
var volume = voxelLayer.SelectedVariableProfile.Volume;
var volumeSize = volume.GetVolumeSize();

//Orientation 90 degrees (due West), Tilt 0 degrees
var normal = voxelLayer.GetNormal(90, 0.0);

//Position must be specified in voxel space

//At 2.x -
//voxelLayer.CreateSection(new SectionDefinition()
//{
//    Name = "Middle Section",
//    VoxelPosition = new Coordinate3D(volume.Item1 / 2, volume.Item2 / 2, volume.Item3 / 2),
//    Normal = normal,
//    IsVisible = true
//});
volume.CreateSection(new SectionDefinition()
{
    Name = "Middle Section",
    VoxelPosition = new Coordinate3D(volumeSize.X / 2, volumeSize.Y / 2, volumeSize.Z / 2),
    Normal = normal,
    IsVisible = true
});

//reset if needed...Normally this might be when your dockpane
//was de-activated (ie "closed")
voxelLayer.AutoShowExploreDockPane = true;
Create a Horizontal Section
//var voxelLayer = ... ;
//Must be on the QueuedTask.Run()

if (voxelLayer.Visualization != VoxelVisualization.Surface)
    voxelLayer.SetVisualization(VoxelVisualization.Surface);
voxelLayer.SetSectionContainerExpanded(true);
voxelLayer.SetSectionContainerVisibility(true);

//Create a section that cuts the volume in two on the horizontal plane
            
//At 2.x - var volumeSize = voxelLayer.GetVolumeSize();

//Use the SelectedVariableProfile to get the sections
//via its associated volume
var volume = voxelLayer.SelectedVariableProfile.Volume;
var volumeSize = volume.GetVolumeSize();

//Or use normal (0, 0, 1) or (0, 0, -1)...
var horz_section = SectionDefinition.CreateHorizontalSectionDefinition();

horz_section.Name = "Horizontal Section";
horz_section.IsVisible = true;
horz_section.VoxelPosition = new Coordinate3D(volumeSize.X / 2, volumeSize.Y / 2, volumeSize.Z / 2);

//At 2.x - voxelLayer.CreateSection(horz_section);
volume.CreateSection(horz_section);
Create Sections in a Circle Pattern
//var voxelLayer = ... ;
//Must be on the QueuedTask.Run()

if (voxelLayer.Visualization != VoxelVisualization.Surface)
    voxelLayer.SetVisualization(VoxelVisualization.Surface);
voxelLayer.SetSectionContainerExpanded(true);
voxelLayer.SetSectionContainerVisibility(true);

//At 2.x - var volumeSize = voxelLayer.GetVolumeSize();

//Use the SelectedVariableProfile to get the sections
//via its associated volume
var volume = voxelLayer.SelectedVariableProfile.Volume;
var volumeSize = volume.GetVolumeSize();

//180 degrees orientation is due South. 90 degrees orientation is due west.
var south = 180.0;
var num_sections = 12;
var spacing = 1 / (double)num_sections;

//Create a section every nth degree of orientation. Each section
//bisects the middle of the voxel
for (int s = 0; s < num_sections; s++)
{
    var orientation = south * (s * spacing);
    //At 2.x -
    //voxelLayer.CreateSection(new SectionDefinition()
    //{
    //    Name = $"Circle {s + 1}",
    //    VoxelPosition = new Coordinate3D(volumeSize.Item1 / 2, volumeSize.Item2 / 2, volumeSize.Item3 / 2),
    //    Normal = voxelLayer.GetNormal(orientation, 0.0),
    //    IsVisible = true
    //});

    volume.CreateSection(new SectionDefinition()
    {
        Name = $"Circle {s + 1}",
        VoxelPosition = new Coordinate3D(volumeSize.X / 2, volumeSize.Y / 2, volumeSize.Z / 2),
        Normal = voxelLayer.GetNormal(orientation, 0.0),
        IsVisible = true
    });
}
Create Sections that Bisect the Voxel
//var voxelLayer = ... ;
//Must be on the QueuedTask.Run()

if (voxelLayer.Visualization != VoxelVisualization.Surface)
    voxelLayer.SetVisualization(VoxelVisualization.Surface);
voxelLayer.SetSectionContainerExpanded(true);
voxelLayer.SetSectionContainerVisibility(true);

//At 2.x - var volumeSize = voxelLayer.GetVolumeSize();

//Use the SelectedVariableProfile to get the sections
//via its associated volume
var volume = voxelLayer.SelectedVariableProfile.Volume;
var volumeSize = volume.GetVolumeSize();

//Make three Normals - each is a Unit Vector (x, y, z)
var north_south = new Coordinate3D(1, 0, 0);
var east_west = new Coordinate3D(0, 1, 0);
var horizontal = new Coordinate3D(0, 0, 1);

int n = 0;
//The two verticals bisect the x,y plane. The horizontal normal bisects
//the Z plane.
foreach (var normal in new List<Coordinate3D> { north_south, east_west, horizontal })
{
    //At 2.x -
    //voxelLayer.CreateSection(new SectionDefinition()
    //{
    //    Name = $"Cross {++n}",
    //    VoxelPosition = new Coordinate3D(volumeSize.Item1 / 2, volumeSize.Item2 / 2, volumeSize.Item3 / 2),
    //    Normal = normal,
    //    IsVisible = true
    //});

    volume.CreateSection(new SectionDefinition()
    {
        Name = $"Cross {++n}",
        VoxelPosition = new Coordinate3D(volumeSize.X / 2, volumeSize.Y / 2, volumeSize.Z / 2),
        Normal = normal,
        IsVisible = true
    });
}
Create Sections Diagonally across the Voxel
//var voxelLayer = ... ;
//Must be on the QueuedTask.Run()

if (voxelLayer.Visualization != VoxelVisualization.Surface)
    voxelLayer.SetVisualization(VoxelVisualization.Surface);
voxelLayer.SetSectionContainerExpanded(true);
voxelLayer.SetSectionContainerVisibility(true);

//At 2.x - var volumeSize = voxelLayer.GetVolumeSize();

//Use the SelectedVariableProfile to get the sections
//via its associated volume
var volume = voxelLayer.SelectedVariableProfile.Volume;
var volumeSize = volume.GetVolumeSize();

//make a diagonal across the voxel
var voxel_pos = new Coordinate3D(0, 0, volumeSize.Z);
var voxel_pos_ur = new Coordinate3D(volumeSize.X, volumeSize.Y, volumeSize.Z);

var lineBuilder = new LineBuilderEx(voxel_pos, voxel_pos_ur, null);
var diagonal = PolylineBuilderEx.CreatePolyline(lineBuilder.ToSegment());

var num_sections = 12;
var spacing = 1 / (double)num_sections;

//change as needed
var orientation = 20.0; //(approx NNW)
var tilt = -15.0;

var normal = voxelLayer.GetNormal(orientation, tilt);

for (int s = 0; s < num_sections; s++)
{
    Coordinate2D end_pt = new Coordinate2D(0, 0);
    if (s > 0)
    {
        //position each section evenly spaced along the diagonal
        var segments = new List<Segment>() as ICollection<Segment>;
        var part = GeometryEngine.Instance.GetSubCurve3D(
                diagonal, 0.0, s * spacing, AsRatioOrLength.AsRatio);
        part.GetAllSegments(ref segments);
        end_pt = segments.First().EndCoordinate;
    }

    //At 2.x -
    //voxelLayer.CreateSection(new SectionDefinition()
    //{
    //    Name = $"Diagonal {s + 1}",
    //    VoxelPosition = new Coordinate3D(end_pt.X, end_pt.Y, volumeSize.Item3),
    //    Normal = normal,
    //    IsVisible = true
    //});

    volume.CreateSection(new SectionDefinition()
    {
        Name = $"Diagonal {s + 1}",
        VoxelPosition = new Coordinate3D(end_pt.X, end_pt.Y, volumeSize.Z),
        Normal = normal,
        IsVisible = true
    });
}
Update Section Orientation and Tilt
//var voxelLayer = ... ;
//Must be on the QueuedTask.Run()

if (voxelLayer.Visualization != VoxelVisualization.Surface)
    voxelLayer.SetVisualization(VoxelVisualization.Surface);
voxelLayer.SetSectionContainerExpanded(true);
voxelLayer.SetSectionContainerVisibility(true);

//Use the SelectedVariableProfile to get the sections
//via its associated volume
var volume = voxelLayer.SelectedVariableProfile.Volume;

//At 2.x - foreach (var section in voxelLayer.GetSections())
foreach (var section in volume.GetSections())
{
    //set each normal to 45.0 orientation and tilt
    section.Normal = voxelLayer.GetNormal(45.0, 45.0);
    //apply the change
    //At 2.x - voxelLayer.UpdateSection(section);
    volume.UpdateSection(section);
}
Requirements

Target Platforms: Windows 11, Windows 10

ArcGIS Pro version: 3 or higher.
See Also