ArcGIS Pro 3.7 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 Property Normal As Coordinate3D
    public Coordinate3D Normal {get; set;}
    Remarks
    The Normal is a unit vector (x, y, z)
    Example
    Create a Section at the Voxel MidPoint
    {
      // Note: call within 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
    
        //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
    
        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
    {
      // Note: call within 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
    
        //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);
    
        volume.CreateSection(horz_section);
      }
    }
    Create Sections in a Circle Pattern
    {
      // Note: call within 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;
        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);
          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
    {
      // Note: call within 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;
        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 })
        {
          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
    {
      // Note: call within 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;
        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;
          }
    
          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
    {
      // Note: call within 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;
    
        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
          volume.UpdateSection(section);
        }
      }
    }
    Requirements

    Target Platforms: Windows 11 Home, Pro, Enterprise (64 bit)

    ArcGIS Pro version: 3.0 or higher.
    See Also