Friday, March 16, 2012

Vasari SDK Sample 2 - DividedSurfacePanelRandomizer


Sample #2 of the new Vasari SDK samples is DividedSurfacePanelRandomizer. The SDK sample contains code in  both VB.NET and C#.

This is another short and sweet sample demonstrating how to randomize panels instantiated within a Divided Surface pattern. This sample needs to be run from within a family (rfa) file for an element who's face(s) have a Divided Surface and are populated with a panel based pattern family. A family file named "DividedSurfacePanelRandomizer.rfa" has been provided with the SDK to use for this sample.


This sample is provided with a modeless user form that prompts you to select a panel element from within a Divided Surface. Once you've selected a panel, the form loads all pattern families within the family that are of the same form pattern shape. These types are what will be randomized across the Divided Surface.

The code that handles the randomization is fairly straightforward. The .NET class "Random" used to generate a random number between 1 and the total qualifying panel families based on your original selection and uses that integer to identify the corresponding panel family symbol to apply in that instance.


        ' New Transaction
        Dim m_t As New Transaction(_doc, "Vasari SDK - Panel Randomization")
        m_t.Start()

        Try

            ' Get all Panels of Matching Type
            Dim m_filter As New FilteredElementCollector(_doc)
            m_filter.WhereElementIsNotElementType()
            m_filter.OfCategory(BuiltInCategory.OST_CurtainWallPanels)
            Dim m_panels As New List(Of Element)
            m_panels = m_filter.ToElements

            ' Random Object
            Dim m_r As New Random

            ' Prime Progressbar
            With Me.ProgressBar1
                .Minimum = 0
                .Maximum = m_panels.Count
                .Value = 0
            End With

            ' Randomize their types
            For Each x As Element In m_panels

                ' Step the progressbar
                Me.ProgressBar1.Increment(1)

                ' Ignore non Panel Elements
                If Not TypeOf x Is Panel Then Continue For

                Try

                    ' Only Work with Panes of Qualifying Type
                    If _Panels.ContainsValue(x.GetTypeId) Then

                        ' Randomize Instance
                        Try

                            ' Random Number between 1 and Quantity of Qualifying Panel Types
                            Dim m_i As Integer = m_r.Next(1, _Panels.Count)

                            ' Change the Type to the Matching Dictionary Entry for the Random Number Key
                            Dim m_eid As ElementId = Nothing
                            _Panels.TryGetValue(m_i, m_eid)

                            ' Was the Type Value Found?
                            If Not m_eid Is Nothing Then

                                ' Change the Type ID
                                x.ChangeTypeId(m_eid)

                            End If

                        Catch ex2 As Exception

                        End Try

                    End If

                Catch ex1 As Exception

                End Try

            Next

            ' Finalize the Transaction
            m_t.Commit()

        Catch ex As Exception

            ' Rollback on failure
            m_t.RollBack()

        End Try

You can click randomize as many times as you want until you get the desired randomization.