//Voxels requires an Advanced license levelvarcanUseVoxels=(ArcGIS.Core.Licensing.LicenseInformation.Level==ArcGIS.Core.Licensing.LicenseLevels.Advanced);
Check if a Voxel Layer can be created
//Map must be a local sceneboolcanCreateVoxel=false;if(MapView.Active.ViewingMode==MapViewingMode.SceneLocal){//license level must be advancedcanCreateVoxel=(ArcGIS.Core.Licensing.LicenseInformation.Level==ArcGIS.Core.Licensing.LicenseLevels.Advanced);}if(canCreateVoxel){//TODO - use the voxel api methods}
Create Voxel Layer
//Must be on the QueuedTask.Run()//Must be a .NetCDF file for voxelsvarurl=@"C:\MyData\AirQuality_Redlands.nc";varcim_connection=newCIMVoxelDataConnection(){URI=url};//Create a VoxelLayerCreationParamsvarcreateParams=VoxelLayerCreationParams.Create(cim_connection);createParams.IsVisible=true;//Can also just use the path directly...//var createParams = VoxelLayerCreationParams.Create(url);//Use VoxelLayerCreationParams to enumerate the variables within//the voxelvarvariables=createParams.Variables;foreach(varvariableinvariables){varline=$"{variable.Variable}: {variable.DataType}, "+$"{variable.Description}, {variable.IsDefault}, {variable.IsSelected}";System.Diagnostics.Debug.WriteLine(line);}//Optional: set the default variablecreateParams.SetDefaultVariable(variables.Last());//Create the layer - map must be a local sceneLayerFactory.Instance.CreateLayer<VoxelLayer>(createParams,map);
Voxel Layer settings and properties
Get a Voxel Layer from the TOC
//Get selected layer if a voxel layer is selectedvarvoxelLayer=MapView.Active.GetSelectedLayers().OfType<VoxelLayer>().FirstOrDefault();if(voxelLayer==null){//just get the first voxel layer in the TOCvoxelLayer=MapView.Active.Map.GetLayersAsFlattenedList().OfType<VoxelLayer>().FirstOrDefault();if(voxelLayer==null)return;}
Manipulate the Voxel Layer TOC Group
//var voxelLayer = ...//Must be on the QueuedTask.Run()//Toggle containers and visibility in the TOCvoxelLayer.SetExpanded(!voxelLayer.IsExpanded);voxelLayer.SetVisibility(!voxelLayer.IsVisible);voxelLayer.SetIsosurfaceContainerExpanded(!voxelLayer.IsIsosurfaceContainerExpanded);voxelLayer.SetIsosurfaceContainerVisibility(!voxelLayer.IsIsosurfaceContainerVisible);voxelLayer.SetSliceContainerExpanded(voxelLayer.IsSliceContainerExpanded);voxelLayer.SetSliceContainerVisibility(!voxelLayer.IsSliceContainerVisible);voxelLayer.SetSectionContainerExpanded(!voxelLayer.IsSectionContainerExpanded);voxelLayer.SetSectionContainerVisibility(!voxelLayer.IsSectionContainerVisible);voxelLayer.SetLockedSectionContainerExpanded(!voxelLayer.IsLockedSectionContainerExpanded);voxelLayer.SetLockedSectionContainerVisibility(!voxelLayer.IsLockedSectionContainerVisible);
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()//Change the visualization to Volume//e.g. for creating slicesvoxelLayer.SetVisualization(VoxelVisualization.Volume);//Change the visualization to Surface//e.g. to create isosurfaces and sectionsvoxelLayer.SetVisualization(VoxelVisualization.Surface);
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()//Offsetvaroffset=voxelLayer.CartographicOffset;//apply an offsetvoxelLayer.SetCartographicOffset(offset+100.0);//VerticalExaggerationvarexaggeration=voxelLayer.VerticalExaggeration;//apply an exaggerationvoxelLayer.SetVerticalExaggeration(exaggeration+100.0);//Change the exaggeration mode to "ScaleZ" - corresponds to 'Z-coordinates' //on the Layer properties UI - must use the CIMvardef=voxelLayer.GetDefinition()asCIMVoxelLayer;def.Layer3DProperties.ExaggerationMode=ExaggerationMode.ScaleZ;//can set vertical exaggeration via the CIM also//def.Layer3DProperties.VerticalExaggeration = exaggeration + 100.0;//apply the changevoxelLayer.SetDefinition(def);//Diffuse Lightingif(!voxelLayer.IsDiffuseLightingEnabled)voxelLayer.SetDiffuseLightingEnabled(true);vardiffuse=voxelLayer.DiffuseLighting;//set Diffuse lighting to a value between 0 and 1voxelLayer.SetDiffuseLighting(0.5);//50%//Specular Lightingif(!voxelLayer.IsSpecularLightingEnabled)voxelLayer.SetSpecularLightingEnabled(true);varspecular=voxelLayer.SpecularLighting;//set Diffuse lighting to a value between 0 and 1voxelLayer.SetSpecularLighting(0.5);//50%
ArcGIS.Desktop.Mapping.Events.MapMemberPropertiesChangedEvent.Subscribe((args)=>{varvoxel=args.MapMembers.OfType<VoxelLayer>().FirstOrDefault();if(voxel==null)return;//Anything changed on a voxel layer?if(args.EventHints.Any(hint =>hint==MapMemberEventHint.VoxelSelectedVariableProfileIndex)){//Voxel variable profile selection changedvarchanged_variable_name=voxel.SelectedVariableProfile.Variable;//TODO respond to change, use QueuedTask if needed}elseif(args.EventHints.Any(hint =>hint==MapMemberEventHint.Renderer)){//This can fire when a renderer becomes ready on a new layer; the selected variable profile//is changed; visualization is changed, etc.varrenderer=voxel.SelectedVariableProfile.Renderer;//TODO respond to change, use QueuedTask if needed}});ArcGIS.Desktop.Mapping.Voxel.Events.VoxelAssetChangedEvent.Subscribe((args)=>{//An asset changed on a voxel layerSystem.Diagnostics.Debug.WriteLine("");System.Diagnostics.Debug.WriteLine("VoxelAssetChangedEvent");System.Diagnostics.Debug.WriteLine($" AssetType: {args.AssetType}, ChangeType: {args.ChangeType}");if(args.ChangeType==VoxelAssetEventArgs.VoxelAssetChangeType.Remove)return;//Get "what"changed - add or update//eg IsoSurfaceVoxelLayervoxelLayer=null;if(args.AssetType==VoxelAssetEventArgs.VoxelAssetType.Isosurface){varsurface=MapView.Active.GetSelectedIsosurfaces().FirstOrDefault();//there will only be one selected...if(surface!=null){voxelLayer=surface.Layer;//TODO respond to change, use QueuedTask if needed}}//Repeat for Slices, Sections, LockedSections...//GetSelectedSlices(), GetSelectedSections(), GetSelectedLockedSections();});
Variable Profiles + Renderer
Get the Selected Variable Profile
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varsel_profile=voxelLayer.SelectedVariableProfile;//Get the variable profile namevarprofile_name=sel_profile.Variable;
Change the Selected Variable Profile
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varprofiles=voxelLayer.GetVariableProfiles();//Select any profile as long as it is not the current selected variablevarnot_selected=profiles.Where(p =>p.Variable!=sel_profile.Variable).ToList();if(not_selected.Count()>0){voxelLayer.SetSelectedVariableProfile(not_selected.First());}
Get the Variable Profiles
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varvariable_profiles=voxelLayer.GetVariableProfiles();
Get the Variable Renderer
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varvariable=voxelLayer.GetVariableProfiles().First();varrenderer=variable.Renderer;if(variable.DataType==VoxelVariableDataType.Continuous){//Renderer will be stretchvarstretchRenderer=rendererasCIMVoxelStretchRenderer;//access the renderer}else//VoxelVariableDataType.Discrete{//Renderer will be unique valuevaruvr=rendererasCIMVoxelUniqueValueRenderer;//access the renderer}
Access Stats and Color Range for a Stretch Renderer
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()//Get the variable profile on which to access the datavarvariable=voxelLayer.SelectedVariableProfile;//or use ...voxelLayer.GetVariableProfiles()//Data rangevarmin=variable.GetVariableStatistics().MinimumValue;varmax=variable.GetVariableStatistics().MaximumValue;//Color range (Continuous only)doublecolor_min,color_max;if(variable.DataType==VoxelVariableDataType.Continuous){varrenderer=variable.RendererasCIMVoxelStretchRenderer;color_min=renderer.ColorRangeMin;color_max=renderer.ColorRangeMax;}
Change Stretch Renderer Color Range
//Typically, the default color range covers the most//commonly occuring voxel values. Usually, the data//range is much broader than the color range//Get the variable profile whose renderer will be changedvarvariable=voxelLayer.SelectedVariableProfile;//Check DataTypeif(variable.DataType!=VoxelVariableDataType.Continuous)return;//must be continuous to have a Stretch Renderer...varrenderer=variable.RendererasCIMVoxelStretchRenderer;varcolor_min=renderer.ColorRangeMin;varcolor_max=renderer.ColorRangeMax;//increase range by 10% of the current differencevardif=(color_max-color_min)*0.05;color_min-=dif;color_max+=dif;//make sure we do not exceed data rangeif(color_min<variable.GetVariableStatistics().MinimumValue)color_min=variable.GetVariableStatistics().MinimumValue;if(color_max>variable.GetVariableStatistics().MaximumValue)color_max=variable.GetVariableStatistics().MaximumValue;renderer.ColorRangeMin=color_min;renderer.ColorRangeMax=color_max;//apply changesvariable.SetRenderer(renderer);
Change The Visibility on a CIMVoxelColorUniqueValue class
//Get the variable profile whose renderer will be changedvarvariable=voxelLayer.SelectedVariableProfile;//Check DataTypeif(variable.DataType!=VoxelVariableDataType.Discrete)return;//must be Discrete to have a UV Renderer...varrenderer=variable.RendererasCIMVoxelUniqueValueRenderer;//A CIMVoxelUniqueValueRenderer consists of a collection of//CIMVoxelColorUniqueValue classes - one per discrete value//in the associated variable profile value array//Get the first classvarclasses=renderer.Classes.ToList();varunique_value_class=classes.First();//Set its visibility offunique_value_class.Visible=false;//Apply the change to the rendererrenderer.Classes=classes.ToArray();//apply the changesvariable.SetRenderer(renderer);
IsoSurfaces
Check the MaxNumberofIsoSurfaces for a Variable
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varvariable=voxelLayer.GetVariableProfiles().First();varmax=variable.MaxNumberOfIsosurfaces;if(max>=variable.GetIsosurfaces().Count){//no more surfaces can be created on this variable}
Check a Variable's Datatype
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varvariable=voxelLayer.GetVariableProfiles().First();if(variable.DataType!=VoxelVariableDataType.Continuous){//No iso surfaces//Iso surface can only be created for VoxelVariableDataType.Continuous}
Check CanCreateIsoSurface
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()//Visualization must be surface or CanCreateIsosurface will return//falseif(voxelLayer.Visualization!=VoxelVisualization.Surface)voxelLayer.SetVisualization(VoxelVisualization.Surface);//Get the variable profile on which to create the iso surfacevarvariable=voxelLayer.SelectedVariableProfile;//or use ...voxelLayer.GetVariableProfiles().First(....// o Visualization must be Surface// o Variable profile must be continuous// o Variable MaxNumberofIsoSurfaces must not have been reached...if(variable.CanCreateIsosurface){//Do the create}
Create Isosurface
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()//Visualization must be surfaceif(voxelLayer.Visualization!=VoxelVisualization.Surface)voxelLayer.SetVisualization(VoxelVisualization.Surface);//Get the variable profile on which to create the iso surfacevarvariable=voxelLayer.SelectedVariableProfile;// o Visualization must be Surface// o Variable profile must be continuous// o Variable MaxNumberofIsoSurfaces must not have been reached...if(variable.CanCreateIsosurface){//Note: calling create if variable.CanCreateIsosurface == false//will trigger an InvalidOperationException//Specify a voxel value for the iso surfacevarmin=variable.GetVariableStatistics().MinimumValue;varmax=variable.GetVariableStatistics().MaximumValue;varmid=(max+min)/2;//color range (i.e. values that are being rendered)varrenderer=variable.RendererasCIMVoxelStretchRenderer;varcolor_min=renderer.ColorRangeMin;varcolor_max=renderer.ColorRangeMax;//keep the surface within the current color range (or it//won't render)if(mid<color_min){mid=renderer.ColorRangeMin;}elseif(mid>color_max){mid=renderer.ColorRangeMax;}//Create the iso surfacevarsuffix=Math.Truncate(mid*100)/100;variable.CreateIsosurface(newIsosurfaceDefinition(){Name=$"Surface {suffix}",Value=mid,IsVisible=true});}
How to Change Value and Color on an Isosurface
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varvariable=voxelLayer.SelectedVariableProfile;//Change the color of the first surface for the given profilevarsurface=variable.GetIsosurfaces().FirstOrDefault();if(surface!=null){if(voxelLayer.Visualization!=VoxelVisualization.Surface)voxelLayer.SetVisualization(VoxelVisualization.Surface);//Change the iso surface voxel valuesurface.Value=surface.Value*0.9;//get a random colorvarcount=newRandom().Next(0,100);varcolors=ColorFactory.Instance.GenerateColorsFromColorRamp(((CIMVoxelStretchRenderer)variable.Renderer).ColorRamp,count);varidx=newRandom().Next(0,count-1);surface.Color=colors[idx];//set the custom color flag true to lock the color//locking the color prevents it from being changed if the//renderer color range or color theme is updatedsurface.IsCustomColor=true;//update the surfacevariable.UpdateIsosurface(surface);}
Change Isourface Color Back to Default
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()//var variable = ...;//var surface = ...;if(surface.IsCustomColor){surface.Color=variable.GetIsosurfaceColor((double)surface.Value);surface.IsCustomColor=false;//update the surfacevariable.UpdateIsosurface(surface);}
Delete Isosurface(s)
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varvariable=voxelLayer.SelectedVariableProfile;//delete the last surfacevarlast_surface=variable.GetIsosurfaces().LastOrDefault();if(last_surface!=null){variable.DeleteIsosurface(last_surface);}//delete all the surfacesforeach(varsurfaceinvariable.GetIsosurfaces())variable.DeleteIsosurface(surface);//Optional - set visualization back to Volumeif(variable.GetIsosurfaces().Count()==0){voxelLayer.SetVisualization(VoxelVisualization.Volume);}
Slices
Get the Collection of Slices
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varslices=voxelLayer.GetSlices();//Do something... e.g. make them visibleforeach(varsliceinslices){slice.IsVisible=true;voxelLayer.UpdateSlice(slice);}//expand the slice container and make sure container visibility is truevoxelLayer.SetSliceContainerExpanded(true);voxelLayer.SetSliceContainerVisibility(true);
Get a Slice(s)
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varslice=voxelLayer.GetSlices().FirstOrDefault();varslice2=voxelLayer.GetSlices().First(s =>s.Id==my_slice_id);
Get Selected Slice in TOC
//Must be on the QueuedTask.Run()varslice=MapView.Active?.GetSelectedSlices()?.FirstOrDefault();if(slice!=null){}
Get Voxel Layer for the Selected Slice in TOC
//Must be on the QueuedTask.Run()VoxelLayervoxelLayer=null;varslice=MapView.Active?.GetSelectedSlices()?.FirstOrDefault();if(slice!=null){voxelLayer=slice.Layer;//TODO - use the layer}
Create a Slice
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()if(voxelLayer.Visualization!=VoxelVisualization.Volume)voxelLayer.SetVisualization(VoxelVisualization.Volume);voxelLayer.SetSliceContainerExpanded(true);voxelLayer.SetSliceContainerVisibility(true);//To stop the Voxel Exploration Dockpane activating use:voxelLayer.AutoShowExploreDockPane=false;//This is useful if u have your own dockpane currently activated...varvolume=voxelLayer.GetVolumeSize();//Orientation 90 degrees (West), Tilt 0.0 (vertical)//Convert to a normalvarnormal=voxelLayer.GetNormal(90,0.0);//Create the slice at the voxel mid-point. VoxelPosition//is specified in voxel-space coordinatesvoxelLayer.CreateSlice(newSliceDefinition(){Name="Middle Slice",VoxelPosition=newCoordinate3D(volume.Item1/2,volume.Item2/2,volume.Item3/2),Normal=normal,IsVisible=true});//reset if needed...voxelLayer.AutoShowExploreDockPane=true;
Change Tilt on a Slice
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()//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 dockpaneif(voxelLayer.Visualization!=VoxelVisualization.Volume)voxelLayer.SetVisualization(VoxelVisualization.Volume);voxelLayer.SetSliceContainerVisibility(true);varslice=voxelLayer.GetSlices().First(s =>s.Name=="Change Tilt Slice");(doubleorientation,doubletilt)=voxelLayer.GetOrientationAndTilt(slice.Normal);//Convert orientation and tilt to a normalslice.Normal=voxelLayer.GetNormal(orientation,45.0);voxelLayer.UpdateSlice(slice);//reset if needed...Normally this might be when your dockpane//was de-activated (ie "closed")voxelLayer.AutoShowExploreDockPane=true;
Delete Slice
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varlast_slice=voxelLayer.GetSlices().LastOrDefault();if(last_slice!=null)voxelLayer.DeleteSlice(last_slice);//Delete all slicesvarslices=voxelLayer.GetSlices();foreach(varsliceinslices)voxelLayer.DeleteSlice(slice);
Sections
Get a Section
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varsection=voxelLayer.GetSections().FirstOrDefault();varsection2=voxelLayer.GetSections().First(sec =>sec.Id==my_section_id);
Get the Current Collection of Sections
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()if(voxelLayer.Visualization!=VoxelVisualization.Surface)voxelLayer.SetVisualization(VoxelVisualization.Surface);voxelLayer.SetSectionContainerExpanded(true);voxelLayer.SetSectionContainerVisibility(true);varsections=voxelLayer.GetSections();
Get the Selected Section in TOC
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varsection=MapView.Active?.GetSelectedSections()?.FirstOrDefault();if(section!=null){}
Get Voxel Layer for the Selected Section in TOC
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()VoxelLayervoxelLayer=null;varsection=MapView.Active?.GetSelectedSections()?.FirstOrDefault();if(section!=null){voxelLayer=section.Layer;//TODO - use the layer}
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 planevarvolume=voxelLayer.GetVolumeSize();//Orientation 90 degrees (due West), Tilt 0 degreesvarnormal=voxelLayer.GetNormal(90,0.0);//Position must be specified in voxel spacevoxelLayer.CreateSection(newSectionDefinition(){Name="Middle Section",VoxelPosition=newCoordinate3D(volume.Item1/2,volume.Item2/2,volume.Item3/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 planevarvolume=voxelLayer.GetVolumeSize();//Or use normal (0, 0, 1) or (0, 0, -1)...varhorz_section=SectionDefinition.CreateHorizontalSectionDefinition();horz_section.Name="Horizontal Section";horz_section.VoxelPosition=newCoordinate3D(volume.Item1/2,volume.Item2/2,volume.Item3/2);horz_section.IsVisible=true;voxelLayer.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);varvolume=voxelLayer.GetVolumeSize();//180 degrees orientation is due South. 90 degrees orientation is due west.varsouth=180.0;varnum_sections=12;varspacing=1/(double)num_sections;//Create a section every nth degree of orientation. Each section//bisects the middle of the voxelfor(ints=0;s<num_sections;s++){varorientation=south*(s*spacing);voxelLayer.CreateSection(newSectionDefinition(){Name=$"Circle {s+1}",VoxelPosition=newCoordinate3D(volume.Item1/2,volume.Item2/2,volume.Item3/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);varvolume=voxelLayer.GetVolumeSize();//Make three Normals - each is a Unit Vector (x, y, z)varnorth_south=newCoordinate3D(1,0,0);vareast_west=newCoordinate3D(0,1,0);varhorizontal=newCoordinate3D(0,0,1);intn=0;//The two verticals bisect the x,y plane. The horizontal normal bisects//the Z plane.foreach(varnormalinnewList<Coordinate3D>{north_south,east_west,horizontal}){voxelLayer.CreateSection(newSectionDefinition(){Name=$"Cross {++n}",VoxelPosition=newCoordinate3D(volume.Item1/2,volume.Item2/2,volume.Item3/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);varvolume=voxelLayer.GetVolumeSize();//make a diagonal across the voxelvarvoxel_pos=newCoordinate3D(0,0,volume.Item3);varvoxel_pos_ur=newCoordinate3D(volume.Item1,volume.Item2,volume.Item3);varlineBuilder=newLineBuilder(voxel_pos,voxel_pos_ur,null);vardiagonal=PolylineBuilder.CreatePolyline(lineBuilder.ToSegment());varnum_sections=12;varspacing=1/(double)num_sections;//change as neededvarorientation=20.0;//(approx NNW)vartilt=-15.0;varnormal=voxelLayer.GetNormal(orientation,tilt);for(ints=0;s<num_sections;s++){Coordinate2Dend_pt=newCoordinate2D(0,0);if(s>0){//position each section evenly spaced along the diagonalvarsegments=newList<Segment>()asICollection<Segment>;varpart=GeometryEngine.Instance.GetSubCurve3D(diagonal,0.0,s*spacing,AsRatioOrLength.AsRatio);part.GetAllSegments(refsegments);end_pt=segments.First().EndCoordinate;}voxelLayer.CreateSection(newSectionDefinition(){Name=$"Diagonal {s+1}",VoxelPosition=newCoordinate3D(end_pt.X,end_pt.Y,volume.Item3),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);foreach(varsectioninvoxelLayer.GetSections()){//set each normal to 45.0 orientation and tiltsection.Normal=voxelLayer.GetNormal(45.0,45.0);//apply the changevoxelLayer.UpdateSection(section);}
Update Section Visibility
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()if(voxelLayer.Visualization!=VoxelVisualization.Surface)voxelLayer.SetVisualization(VoxelVisualization.Surface);voxelLayer.SetSectionContainerExpanded(true);voxelLayer.SetSectionContainerVisibility(true);varsections=voxelLayer.GetSections().Where(s =>!s.IsVisible);//Make them all visibleforeach(varsectioninsections){section.IsVisible=true;//apply the changevoxelLayer.UpdateSection(section);}
Delete Sections
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()foreach(varsectioninvoxelLayer.GetSections())voxelLayer.DeleteSection(section);//optional...if(voxelLayer.Visualization!=VoxelVisualization.Volume)voxelLayer.SetVisualization(VoxelVisualization.Volume);
Locked Sections
Get the Current Collection of Locked Sections
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()if(voxelLayer.Visualization!=VoxelVisualization.Surface)voxelLayer.SetVisualization(VoxelVisualization.Surface);voxelLayer.SetLockedSectionContainerExpanded(true);voxelLayer.SetLockedSectionContainerVisibility(true);varlocked_sections=voxelLayer.GetLockedSections();
Get a Locked Section
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varlocked_section=voxelLayer.GetLockedSections().FirstOrDefault();varlocked_section2=voxelLayer.GetLockedSections().First(lsec =>lsec.Id==my_locked_section_id);
Get Selected Locked Section in TOC
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()varlocked_section=MapView.Active?.GetSelectedLockedSections()?.FirstOrDefault();if(locked_section!=null){}
Get Voxel Layer for the Selected Locked Section in TOC
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()VoxelLayervoxelLayer=null;varlocked_section=MapView.Active?.GetSelectedLockedSections()?.FirstOrDefault();if(locked_section!=null){voxelLayer=locked_section.Layer;//TODO - use the layer}
Set the Variable Profile Active for Selected Locked Section
//Must be on the QueuedTask.Run()varlocked_section=MapView.Active?.GetSelectedLockedSections()?.FirstOrDefault();if(locked_section!=null){varvariable=locked_section.Layer.GetVariableProfile(locked_section.VariableName);locked_section.Layer.SetSelectedVariableProfile(variable);}
Lock a Section/"Create" a Locked Section
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()if(voxelLayer.Visualization!=VoxelVisualization.Surface)voxelLayer.SetVisualization(VoxelVisualization.Surface);voxelLayer.SetSectionContainerExpanded(true);voxelLayer.SetLockedSectionContainerExpanded(true);voxelLayer.SetLockedSectionContainerVisibility(true);//get the selected sectionvarsection=MapView.Active.GetSelectedSections().FirstOrDefault();if(section==null)section=voxelLayer.GetSections().FirstOrDefault();if(section==null)return;//Lock the section (Creates a locked section, deletes//the section)if(voxelLayer.CanLockSection(section))voxelLayer.LockSection(section);
Update Locked Section Visibility
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()if(voxelLayer.Visualization!=VoxelVisualization.Surface)voxelLayer.SetVisualization(VoxelVisualization.Surface);voxelLayer.SetLockedSectionContainerExpanded(true);voxelLayer.SetLockedSectionContainerVisibility(true);varlocked_sections=voxelLayer.GetLockedSections().Where(ls =>!ls.IsVisible);//Make them visibleforeach(varlocked_sectioninlocked_sections){locked_section.IsVisible=true;//apply changevoxelLayer.UpdateSection(locked_section);}
Unlock a Locked Section
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()if(voxelLayer.Visualization!=VoxelVisualization.Surface)voxelLayer.SetVisualization(VoxelVisualization.Surface);voxelLayer.SetSectionContainerExpanded(true);voxelLayer.SetSectionContainerVisibility(true);voxelLayer.SetLockedSectionContainerExpanded(true);//get the selected locked sectionvarlocked_section=MapView.Active.GetSelectedLockedSections().FirstOrDefault();if(locked_section==null)locked_section=voxelLayer.GetLockedSections().FirstOrDefault();if(locked_section==null)return;//Unlock the locked section (Deletes the locked section, creates//a section)if(voxelLayer.CanUnlockSection(locked_section))voxelLayer.UnlockSection(locked_section);
Delete a Locked Section
//var voxelLayer = ... ;//Must be on the QueuedTask.Run()if(voxelLayer.GetLockedSections().Count()==0)return;//Delete the last locked section from the collection of//locked sectionsvoxelLayer.DeleteSection(voxelLayer.GetLockedSections().Last());