logo

Writing C# Functions

How to create Hypar functions in C#

By uploading a function to Hypar you can produce multiple options for a building problem in just a few seconds, and combine them with other people's functions to create rich, realistic designs. In this introduction to Hypar, we'll work with a much simpler function that generates masses of variable dimensions.
Anyone can create a Hypar Function using C#. Keep reading or watch the tutorial video to learn how.

Tutorial Video

Prerequisites

Pre-flight check

C# and Revit Prerequisites

Things to keep in mind

  • We’re here to help with C# - Basic familiarity with the C# programming language will help, but if you're not familiar with C# we'll do our best to walk you through making changes to the initial code you'll get by following the steps in this guide.
  • Hypar is no strings attached - None of the Hypar libraries you'll use in this guide bind your code to Hypar web services. For example, if you'd like to use the Elements library for a desktop application, it's an open source project on GitHub and will always be free for anyone to use or extend. You don't even have to tell us you're using it.

How to create a Function

  • Sign in to Hypar. Scroll down to Your Functions. Click New Function then New C# Function.
Image without caption
  • Now you can start srtting up your function through the Hypar interface. For consistency, give your function the name Starter Function and a description (if you’d like!). Click Next.
    • Image without caption
  • Click or drag three Range inputs and name them Width, Length, and Height, and set their minimum values to 1:
Image without caption
  • You can also select "Preview" to visualize how the inputs will look in the function.
  • Note: We’ll save the Connections section for another tutorial.
  • Click Next again so that 4: Outputs is highlighted at the top. Click + Output to add a new output to report the box’s volume, and configure it like the image below:
Image without caption
  • Move on to the final step, Logic. Click Create Function, and then click the copy icon to copy the terminal command.
Image without caption
  • Your Function has now been privately published to Hypar!
  • Next, we'll write some code to define the logic for the Function.
  • Return to your command prompt. Decide where you want Hypar to save the code for your Function on your computer, and use the cd command to set that location as the current working directory:
    • bash
      cd C:/users/yourUserName/repos
  • Then paste the command you copied from the Hypar web interface, and run it using the Hypar CLI:
    • plain text
      hypar new --function-id={YOUR_FUNCTION_ID]
  • A bunch of messages will go by as Hypar sets up your local project.
Image without caption
  • Next, open VS Code and open the project folder we just created. It should be in the location you picked earlier, with the folder name "StarterFunction."
  • The Hypar CLI just created a bunch of files for you. Here's what that looks like in VS Code:
Image without caption
  • It may seem like a lot, but the good news is you rarely have to edit most of these files — Hypar takes care of all of that for you. Any file you see that ends with .g.cs is not meant to be edited by you.
    • Open the StarterFunction.cs in the /src directory (this contains the logic for your function.)
      The Execute method is the entry point into our function; Upon Function creation it creates an "Outputs" object, and returns it.
      Image without caption
      Note that the method has a few arguments. The one called input contains the inputs we defined earlier, Width, Length, and Height. Let's use some of those inputs to create a rectangle. Add this line to your function, in between the two existing lines of the method:
      c#
      var rectangle = Polygon.Rectangle(input.Width, input.Length);
      Image without caption
  • Next we'll make a Mass Element to pass to the Hypar 3D environment.
  • Note: If you want something to show up in the 3D view, it has to be an Element of some kind.
  • Add this line after the rectangle:
    • c#
      var mass = new Mass(rectangle, input.Height);
      Image without caption
  • We also have to put the mass we created in the output model, like so:
    • c#
      output.Model.AddElement(mass);
      Image without caption
  • Finally, we created an output called Volume to report the box's volume. These data outputs are provided to the constructor for the Outputs object — so let's edit the first line of our method to look like this:
    • c#
      var output = new StarterFunctionOutputs(input.Width * input.Length * input.Height);
  • The Execute method within your function should look something like this:
    • c#
      public static StarterFunctionOutputs Execute(Dictionary<string, Model> inputModels, StarterFunctionInputs input) { // create an outputs object and populate any output values var output = new StarterFunctionOutputs(input.Width * input.Length * input.Height); // create a rectangle var rectangle = Polygon.Rectangle(input.Width, input.Length); // create a mass from the rectangle var mass = new Mass(rectangle, input.Height); // add the mass to the output model output.Model.AddElement(mass); return output; }
      Be sure to save the file!

Publish your Function

  • To publish our changes to the web, open up your command prompt again (or open VS Code's integrated terminal).
  • Make sure your working directory is the one Hypar created for you — you might need to cd StarterFunction first.
  • Then publish your function logic using the publish command like this:
    • bash
      hypar publish
      💡
      Note: No one at Hypar can see your source code — Hypar only receives the compiled binary file. The only way we can access your code is if you send it to us directly.
      Image without caption
  • Your Function logic has now been added to your Function on Hypar. Return to hypar.io and sign in so we can test it out!
  • Create a new workflow by clicking New Workflow and selecting New Blank Workflow. Give your Workflow a name by clicking it. You'll then see this screen:
Image without caption
  • In the Function Library panel, search for "Starter Function".
  • Click + Add on Starter Function and hide the Function Library by clicking the x to close it. Your function will run automatically and you should see something like this:
Image without caption
You've just run a web application that you created!
  • Click in the 3D view to zoom, pan, and rotate the result. Now click on Starter Function to open up its inputs. Try adjusting the sliders to see how the mass changes shape.
Image without caption
  • This diagram summarizes the process we just went through to create, define, and publish our function:
    • Image without caption

How to edit your Function

Access your Function details by clicking About/Edit from within the menu.
As the owner of the Function, this is where you can make changes.
Image without caption
Image without caption
Switch to the Inputs tab and click Edit Function Details at the bottom of the window. This brings us to the same interface we used to create the inputs originally.
Image without caption
Let's add a new Color input by dragging "Color" to the top. Call it "Mass Color" and click the color swatch to set a different color as the default.
Any value you set in this window will be the default value that shows up when your function is added to a workflow.
Image without caption
Switch to the Outputs tab so we can add an output for the base area of our mass. Click + to add and configure it like the image below:
Image without caption
Click Save Changes to register your changes to the function's configuration.
Next, we'll need to pull those changes into our local code files, so that we can use the new input and output. Switch to the Logic tab and copy the second command:
bash
hypar pull && hypar init
hypar pull pulls the changes we made in the web interface to our hypar.json configuration file, and hypar init generates new code files from that configuration. You are also welcome to run these commands independently — you don't need to copy them from the web every time.
Return to VS Code and select the hypar.json file from the explorer. This is where you can view the configuration that describes this Function.
Image without caption
Scroll down to see our new Color input and Area output reflected:
Image without caption
💡
Advanced users may find it easier to edit hypar.json manually rather than editing the function in the web UI and running hypar pull. Just remember to use hypar init after any changes to hypar.json to make sure the corresponding C# code gets regenerated.
Returning to StarterFunction.cs, we can take advantage of our new inputs and outputs. We'll edit the first line to add the base area output:
c#
var output = new StarterFunctionOutputs(input.Width * input.Length * input.Height, input.Width * input.Length);
And create a new material before we create our mass:
c#
var material = new Material("Box Color", input.MassColor);
And finally add the material to the mass.
c#
var mass = new Mass(rectangle, input.Height, material);
Here's how the updated Execute method code should look now:
c#
public static StarterFunctionOutputs Execute(Dictionary<string, Model> inputModels, StarterFunctionInputs input) { // create an output object var output = new StarterFunctionOutputs(input.Width * input.Length * input.Height, input.Width * input.Length); // create a rectangle var rectangle = Polygon.Rectangle(input.Width, input.Length); // create a new material var material = new Material("Box Color", input.MassColor); // create a mass from the rectangle var mass = new Mass(rectangle, input.Height, material); // add the mass to the output model output.Model.AddElement(mass); return output; }
Be sure to save the file, and then publish these changes by running
plain text
hypar publish
again. Then we'll return to our workflow on Hypar, and reload the page to update the Function. You may have to adjust a slider value to cause the function to recompute.
Image without caption
This diagram summarizes the steps we've taken to edit and update our function:
Image without caption

How to share your Function

Functions are private to you by default — only you can see and use them in a Workflow.
If you’d like to share your Function, go to Function details by clicking About/Edit from within the menu then click Permissions.
Image without caption
To make your Function public, uncheck the Private checkbox.
You can also share Functions with specific email addresses or domains (like myfirm.com).

How to add a thumbnail to your Function

You may also want to add a thumbnail to your function so others can get a sense of what it does. To do this, go to the Details tab, click Edit Function Details, and drag-and-drop an image on the drop zone. Then click Save Changes to save the thumbnail.
Image without caption

Testing your Function

There are two ways to test a Function:
  • hypar run is a live, highly interactive method, that lets you see the results of your code changes instantly. View the below page to learn more:
Here is a video that demonstrates both methods:

What's next?

Congratulations on creating your first Hypar function! Now it’s time to create your own.
Here are a few tips for deciding what to make:
  • Solve one small problem. Hypar Functions are easy to compose — no single function needs to do too much on its own.
  • Repetition is your friend — build something that can tackle tasks that you hate doing manually, or take something you’ve built before and build it again on Hypar.
  • Reach out to the community — our Discord channel has tons of community members ready to answer questions or share ideas.
  • Have fun with it! What do you think would look cool? What would look silly? Build that!
Here are some other good resources:
  • Hypar's Building Blocks repo has the source code for many Hypar functions. Read those to see how they work, and feel free to branch or improve any of them.

Advanced topics

  • Use Function Staging to safely test out new updates to your function without breaking anything for existing users:
  • Learn about Overrides, to create richer, more intelligent interactions with your functions, in way that can balance automation with human design intervention:
  • Learn about Element Instances, to efficiently create multiple copies of a piece of geometry as output from your function:
  • Use Queries to select elements and get data:
  • Create custom model exporters to download different file types from a Hypar workflow: