I am trying to toggle the visibility of point clouds in a view by setting the 'View.ArePointCloudsHidden' property. I have come across three (3) scenarios, and they code below handles the first two correctly, but the third is not working and I am not sure why.
Scenario 1: View has no view template. Below code successfully toggles Point Cloud Visibility on/off.
Scenario 2: View has a view template that controls point cloud visibility. The below code first applies 'temporary view properties' to the view, and then toggles Point Cloud Visibility on/off. This code also works.
Scenario 3: View has a view template that DOES NOT controls point cloud visibility. The below code doesn't work, and the Point Cloud Visibility in the view stays the same.
public override Result Execute(UIApplication uiapp)
{
try
{
Document doc = uiapp.ActiveUIDocument.Document;
View activeView = uiapp.ActiveUIDocument.ActiveView;
using (Transaction formTx = new Transaction(doc))
{
try
{
// determine transaction name (shown to user in undo/redo stack)
string transactionName = activeView.ArePointCloudsHidden
? "Show Point Clouds"
: "Hide Point Clouds";
formTx.Start(transactionName);
// enable temporary view graphics for this view if:
// (1) point cloud visibiliity is controlled by the view's view template, and
// (2) temporary view graphics aren't on already
if (
DoesViewTemplateControlPointCloudVisibility(doc, activeView.ViewTemplateId) &&
!activeView.TemporaryViewModes.IsModeActive(TemporaryViewMode.TemporaryViewProperties)
)
{
// enable temporary view properties only if it's available in the active view
if (activeView.TemporaryViewModes.IsModeAvailable(TemporaryViewMode.TemporaryViewProperties))
{
activeView.EnableTemporaryViewPropertiesMode(activeView.Id);
}
else
{
formTx.RollBack();
return Result.Failed;
}
}
// toggle point cloud visibility
activeView.ArePointCloudsHidden = !activeView.ArePointCloudsHidden;
formTx.Commit();
}
catch (Exception e)
{
if (formTx.HasStarted())
{
formTx.RollBack();
}
return Result.Failed;
}
}
return Result.Succeeded;
}
catch (Exception e)
{
UIUtil.ShowRevitDialogExceptionError(e);
return Result.Failed;
}
}
/// <summary>
/// Returns true if the given view template has control over whether
/// point clouds are visible are not in a given view
/// </summary>
private bool DoesViewTemplateControlPointCloudVisibility(Document doc, ElementId viewTemplateId)
{
View viewTemplate = doc.GetElement(viewTemplateId) as View;
//? throw exception instead?
if (viewTemplate == null || !viewTemplate.IsTemplate) return false; // input validation
// get the parameters that are NOT controlled by this view template
IEnumerable<int> paramsNotControlledByViewTemplate =
viewTemplate.GetNonControlledTemplateParameterIds()
.Select(id => id.IntegerValue);
// return false if the list of parameters NOT controlled by the view template inclused the point cloud parameter
return paramsNotControlledByViewTemplate.Contains((int)BuiltInParameter.VIS_GRAPHICS_POINT_CLOUDS)
? false
: true;
//todo: check view template filters too
}
Is there, perhaps, a different way to set point cloud visibility when a view template is applied, even though the view template doesn't control Point Cloud Visibility, that I should be using?
So, after some more researching, this might be a Revit bug. When I try to reproduce the processing I'm trying to solve using the Revit UI (scenario 3 from above), it does not work.
Below are the steps I'm doing in the UI. I've also attached a .gif showing how it doesn't work.
1) Apply view template to view
2) Edit view template - uncheck 'V/G Overrides Point Clouds'
3) Open up the Visibility Graphics for that view
4) On the Point Cloud tab, uncheck the 'Show point clouds in this view' box.
5) The point clouds in that view are still visible!!!! What?!
In the same .gif, I then demonstrate that if I remove the view template from that view, and then change the point cloud visibility in the same way, the point clouds do disappear, as expected.
Note: I have tested this in Revit 2020 and Revit 2023, and both seem to have this same issue.