Friday, February 19, 2016

Dynamo to C# Revit Macros #1 : QR Code Generator

I am gradually learning to code learning C#, and by that I mean windows console applications. Where everyone else starts... As in the hello world and what door would you like to open and win a car sorts of applications. The Bob Tabor videos are helping a lot and I even picked up a Microsoft Step by Step book which is helping out a lot. I intend to post some of my own successes later, but this blog post is directly focused on a collaborative effort towards "Where ideas come from" and how to make these said ideas better.

   
Video share credit to Fausto Mendez and, of course, Steven Johnson 


The story begins back in 2014 where I met my friend and colleague Fausto Mendez, at Autodesk University. As I stood in line anxiously, the morning of my first A.U, I met Fausto at the front board. He was standing there prior to me which surprised me because I was so damn early, due to excitement, that I thought I would be the first one there. Through networking and communicating with Fausto. I found out that he was an experienced coder, and he was all about hacking things. I was impressed with everything he was saying, but was very naive to the full scope of what he was actually coding or what he actually did with all this coding knowledge. I found out things of similarity about his job compared to mine and how he was essentially applying everything I wanted to apply to plumbing and heating, but towards the electrical profession. As the past two A.U.'s have gone by we've stayed in touch and I've seen how his successes have continued, and seen his applications immensely improve. He has been supportive along the way of my desire to learn, and is patiently awaiting my successes, even though it's taking far longer than it should :). Since then I've become a huge user of Dynamo. I've created several modules, and have collaborated in the community with others to implement new nodes that could overall lead to the success of some ideas I've had in our office that could streamline our workflows. This led to me thinking about a new innovation of things, but an innovation of ideas with Fausto. I proposed the idea of collaboratively converting the dynamo modules into C# Code. Through his amazing coding skills and the use of dynamo as a visual flow of the code. Fausto was able to compile the code quicker and it was easier for me to effectively communicate my ideas

Below is the QR Code Generator dynamo module to C# conversion:

I simply made an Autodesk Screencast. Shared the video with him along with the Dynamo module and he was able to quickly respond back with the success of the Revit Macro and shared the modules code in a text file.

Dynamo Module #1: QR Code Generator


Dynamo Module #1 QR Code Generator

This module allows for the creation of QR codes by simply clicking the family and/or Assembly Instance to a folder location, thanks to Jostein Olsen's QR Module.

Fausto's Response:

Autodesk Screencast of Revit Macro in action

Fausto's walkthrough of how to compile and write the C# code illustrated through his website.

http://www.faustomendez.com/2016/02/revit-qrcode-generator/

QrCodeGenerator();

 public void QrCodeGenerator()
        {
            UIDocument uidoc = this.ActiveUIDocument;
            Document doc = uidoc.Document;
            
            List<ElementId> ids = new List<ElementId>();
            Selection sel = uidoc.Selection;

            ICollection<ElementId> selIds = sel.GetElementIds();

            if (0 < selIds.Count)
            {
                foreach (ElementId id in selIds)
                {
                    ids.Add(id);
                }
            }

            if (0 == selIds.Count)
            {
                IList<Reference> refs = null;

                try
                {
                    refs = sel.PickObjects(ObjectType.Element,
                    "Please Element(s) to Generate QrCode.");
                }
                catch (Autodesk.Revit.Exceptions
                .OperationCanceledException)
                {
                    //  return Result.Cancelled;
                }
                ids = new List<ElementId>(
                refs.Select<Reference, ElementId>(
                r => r.ElementId));
            }

            foreach (ElementId id in ids)
            {
                Element el = doc.GetElement(id);
                FamilyInstance elsym = el as FamilyInstance;
                FamilySymbol famsym = elsym.Symbol as FamilySymbol;
                string data = Uri.EscapeUriString(famsym.get_Parameter(BuiltInParameter.ALL_MODEL_URL).AsString());
                string folderpath = @"C:\{Your Folder Path Here}\";
                string Filename = el.Name;

                GenerateQRCode(data, folderpath, Filename);
            }


        }

        private static void GenerateQRCode(string Data, string folderpath, string fileName)
        {
            try
            {
                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("https://api.qrserver.com/v1/create-qr-code/?size=900x900&data=" + Data);
                System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
                if ((response.StatusCode == System.Net.HttpStatusCode.OK ||
                    response.StatusCode == System.Net.HttpStatusCode.Moved ||
                    response.StatusCode == System.Net.HttpStatusCode.Redirect) &&
                    response.ContentType.StartsWith("image", StringComparison.OrdinalIgnoreCase))
                {
                    using (System.IO.Stream inputStream = response.GetResponseStream())
                    using (System.IO.Stream outputStream = System.IO.File.OpenWrite(folderpath + fileName + ".png"))
                    {
                        byte[] buffer = new byte[4096];
                        int bytesRead;
                        do
                        {
                            bytesRead = inputStream.Read(buffer, 0, buffer.Length);
                            outputStream.Write(buffer, 0, bytesRead);
                        } while (bytesRead != 0);
                    }
                }
            }
            catch (Exception ex)
            {
                TaskDialog.Show("Error", ex.Message);
            }

        }
Photo credit to Fausto Mendez

This truly shows the power of the Revit community, and that if you set your mind to collaborating with other design professionals your "collision of smaller hunches" will lead to a potentially better idea!