How could I continue after Postcommand call to "Material Browser"?

How could I continue after Postcommand call to "Material Browser"?

BinghuiLi
Participant Participant
446 Views
5 Replies
Message 1 of 6

How could I continue after Postcommand call to "Material Browser"?

BinghuiLi
Participant
Participant

Hello,

 

After opening the material browser using postcommand, is there any way I can get the element(Material) selected in the material browser?

BinghuiLi_0-1712743158526.png

 

Thanks!

 

Best Regards,

Binghui

0 Likes
Accepted solutions (1)
447 Views
5 Replies
Replies (5)
Message 2 of 6

jeremy_tammik
Alumni
Alumni

No. Sorry. Well, yes, of course there is, because you can do anything you like, but there is no support or other functionality provided by the Revit API to help you. You would have to take recourse to the underlying Windows API or .NET libraries to programmatically "scrape" the information from the UI somehow. That is pretty hard-core hacking. I am sorry to say I have no further advice to offer on that... What do you actually want to achieve? Why are you trying to mix the UI and API?

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 6

BinghuiLi
Participant
Participant

Hi Jeremy,

 

The idea is to have a button on one of my own add-ins to set the parameter value for the parameter by opening the material browser. Previously I simply listed all the material names in the combobox for my colleagues to choose from, but the feedback was that they still preferred to be able to select them directly in the material browser, where they can see the parameter and the picture more visually. 

 

There is similar functionality in revit's material parameter settings, and I thought maybe this could be done through the API.

0 Likes
Message 4 of 6

jeremy_tammik
Alumni
Alumni
Accepted solution

Sounds perfectly sensible to me. Unfortunately, no idea how to programmatically extract the selected item. The Building Coder shares some hacking solutions in the Automation category...

  

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 5 of 6

BinghuiLi
Participant
Participant

I solved this problem in a stupid way, reading the Journal file and reading the last determined material name...

 

 

 

internal class MaterialBrowserEventHandler : IExternalEventHandler
{
    public void Execute(UIApplication app)
    {
        GetMaterialText(GetJournalFilePath(app));
    }

    public string GetName()
    {
        return "MaterialBrowserEventHandler";
    }


    private string GetJournalFilePath(UIApplication application)
    {


        string filePath = application.Application.RecordingJournalFilename;
        TaskDialog.Show("test", filePath);
        return filePath;
    }

    private void GetMaterialText(string journalFilePath)
    {
        using (FileStream fileStream = new FileStream(journalFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            byte[] buffer = new byte[4096]; // Buffer to read file content
            string prevLine = null;

            // Start reading from the end of the file
            long position = fileStream.Length;

            while (position > 0)
            {
                // Calculate the position to start reading from
                position = Math.Max(0, position - buffer.Length);
                fileStream.Seek(position, SeekOrigin.Begin);

                // Read data into the buffer
                int bytesRead = fileStream.Read(buffer, 0, (int)Math.Min(buffer.Length, fileStream.Length - position));

                // Convert the read bytes to string
                string fileContent = Encoding.UTF8.GetString(buffer, 0, bytesRead);

                // Split the content into lines
                string[] lines = fileContent.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);

                // Iterate over lines in reverse order
                for (int i = lines.Length - 1; i > 0; i--)
                {
                    string line = lines[i];

                    // Use regular expression to match the part containing "OK, IDOK"
                    Match match = Regex.Match(line, @"OK, IDOK");
                    prevLine = lines[i - 1];
                    if (match.Success && prevLine != null)
                    {
                        // Match the field content in the previous line
                        Match fieldNameMatch = Regex.Match(prevLine, @"(?<=- )(\S+)(?= , Dialog)");
                        if (fieldNameMatch.Success)
                        {
                            string fieldName = fieldNameMatch.Value;
                            TaskDialog.Show("MaterialBrowser", fieldName);
                            Console.WriteLine("Found line containing 'OK, IDOK', field content is: " + fieldName);
                            return;
                        }
                    }
                }
            }
        }
    }
}

 

0 Likes
Message 6 of 6

jeremy_tammik
Alumni
Alumni

Wow. Congratulations! I call that a creative solution! Thank you for sharing it.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes