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

In This Topic
    Normal Property (SectionDefinition)
    In This Topic
    Gets and sets the section normal.
    Syntax
    public Coordinate3D Normal {get; set;}
    Public Property Normal As Coordinate3D
    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