Skip to content

Commit

Permalink
initial setup
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewheumann committed Nov 27, 2023
1 parent a5bef60 commit a976ea4
Show file tree
Hide file tree
Showing 7 changed files with 537 additions and 1 deletion.
15 changes: 15 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"image":"mcr.microsoft.com/devcontainers/universal:2",
"customizations": {
"vscode": {
"extensions": [
"ms-dotnettools.dotnet-interactive-vscode",
"ms-dotnettools.csdevkit"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "zsh",
"terminal.integrated.profiles.linux": { "zsh": { "path": "/bin/zsh" } }
}
}
}
}
59 changes: 59 additions & 0 deletions 00 Elements Notebooks.dib
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!meta

{"kernelInfo":{"defaultKernelName":"csharp","items":[{"aliases":[],"name":"csharp"}]}}

#!markdown

# Introducing Hypar.Elements

#!markdown

In order to get you familiarized with the Elements library, we've set up a series of .NET interactive notebooks. Elements is designed to work seamlessly with notebooks, to make it easy to prototype and explore the code.

If you haven't used code notebooks like jupyter before, this might take a little getting used to — here's a brief overview.

#!markdown

Some cells are Markdown cells, like this one. You can double-click on them to edit them. When you're done editing, you can run the cell by pressing `Ctrl+Enter` or `Shift+Enter`.

#!markdown

Edit this cell by double-clicking and writing your name:

Hello, my name is _________

#!markdown

Cells can also contain code that can execute. In these notebooks, C# code is supported. Return a value from a cell to display it. Try running the following cell:

#!csharp

var sum = 10 + 20;
return sum;

#!markdown

You can import packages from nuget with a special syntax, like the cell below. Try running this cell. It will import the Hypar.Elements package, with the latest alpha version. The Hypar.Elements package is also configured with some special extra features just for notebooks, so you'll see a message at the end.

#!csharp

#r "nuget: Hypar.Elements, *-*"

#!markdown

Just like you can return a value from a cell, you can also return and display 3d geometry built with elements. Try running the following cell (don't worry about the code too much yet, we'll explain in the following notebooks).

#!csharp

var mass = new Mass(Polygon.Star(5, 3, 5),4, new Material("Red", Colors.Red));
return mass;

#!markdown

You should be able to zoom in and out and orbit the model. Try it!

#!markdown

# Exercise

Create a new code cell. Write some code and execute it! Print "Hello world," or do some basic math. (Don't worry, we'll get to more interesting exercises in the next notebooks.)
98 changes: 98 additions & 0 deletions 01 Geometry Basics.dib
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!meta

{"kernelInfo":{"defaultKernelName":"csharp","items":[{"aliases":[],"name":"csharp"}]}}

#!markdown

# Import Hypar Library

#!csharp

#r "nuget: Hypar.Elements, *-*"

#!markdown

# Points, Lines, and Polylines
Hypar is a 3d world. X and Y form the ground, and Z is up, like most architectural modeling applications.

Hypar uses the `Vector3` type for both points (positions) and vectors (directions).

Create a new `Vector3` with the `Vector3` constructor:

#!csharp

var myVector = new Vector3(2,4,5);

#!markdown

Create a `Line` with the `Line` constructor, and pass it two `Vector3`s:

#!csharp

var a = new Vector3(0,0,0);
var b = new Vector3(10, 5, 7);
var line = new Line(a, b);
return line;

#!markdown

Create a `Polyline` with the `Polyline` constructor. You can pass it a `List` of `Vector3`, or directly pass it any number of `Vector3`s in the arguments.

#!csharp

// A slightly more verbose way...
var points = new List<Vector3>();
points.Add(new Vector3(0, 0, 0));
points.Add(new Vector3(2, 0, 0));
points.Add(new Vector3(2, 2, 0));
points.Add(new Vector3(0, 2, 0));
var polyline1 = new Polyline(points);
return polyline1;

#!markdown

You can skip the `new Vector3` part in many cases.

(Polyline takes a `params[]` argument, and we auto-convert Tuples with 2 and 3 elements to `Vector3`, if you're curious how this works.)

#!csharp

// A slightly shorter way to do the same thing:
var polyline2 = new Polyline((0,0), (2,0), (2,2), (0,2), (0,2,5));
return polyline2;

#!markdown

# Polygons
A `Polygon` is just like a `Polyline`, except it represents a closed shape, and it must be planar.

#!csharp

var polygon = new Polygon((0,0), (2,2), (4,0), (4,4), (0,4));
return polygon;

#!markdown

There are also convenience shapes for common cases:
- Rectangle
- Star
- L
- U
- Ngon

Also note how we can display multiple polylines at once in a notebook by returning a list or array:

#!csharp

var rectangle = Polygon.Rectangle(10,10);
var star = Polygon.Star(5,3,5);
var l = Polygon.L(2, 2, 0.5);
var u = Polygon.U(5, 3, 0.75);
var hexagon = Polygon.Ngon(6, 10);
return new [] { rectangle, star, l, u, hexagon };

#!markdown

# Exercise

Use a for loop to create 20 concentric rectangles, each 1 unit larger than the previous one. Return them in a list so we can see them all.
132 changes: 132 additions & 0 deletions 02 Profiles + Operations.dib
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#!meta

{"kernelInfo":{"defaultKernelName":"csharp","items":[{"aliases":[],"name":"csharp"}]}}

#!markdown

### Setup

#!csharp

#r "nuget: Hypar.Elements, *-*"

#!markdown

# Profiles and Solid Operations

#!markdown

## Profiles

Profiles are basically "Polygons with holes" — and they're a major geometry workhorse on Hypar. They're used to represent everything from the outlines of spaces, to building footprints, to the cross-sections of structural members.

#!csharp

var outerBoundary = Polygon.Rectangle((0,0), (10, 10));
var hole = Polygon.Rectangle((4,4), (8, 8));
var profile = new Profile(outerBoundary, hole);
return profile;

#!markdown

Profiles can have multiple holes, too:

#!csharp

var outerBoundary = Polygon.Rectangle((0,0), (10, 10));
var hole1 = Polygon.Rectangle((2,2), (4, 4));
var hole2 = Polygon.Rectangle((6,6), (8, 8));
var profile = new Profile(outerBoundary, new List<Polygon> { hole1, hole2 });
return profile;

#!markdown

## Solid Operations

We can also create solid geometry, not just curves. The two most common are the `Lamina`, which is basically a flat surface, and the `Extrude`, which is a straight extrusion along a vector. Both can be created from `Profile`s.

#!csharp

var lamina = new Lamina(profile);
return lamina;

#!csharp

var extrude = new Extrude(profile, 2, Vector3.ZAxis);
return extrude;

#!markdown

`Sweep`s are also supported:

#!csharp

using Elements.Geometry.Profiles;
var rail = new Polyline((0,0), (10,0), (10, 3), (12, 4));
var crossSection = new WideFlangeProfileFactory().GetProfileByType(WideFlangeProfileType.W24x94);
var sweep = new Sweep(crossSection, rail, 0, 0, 0, false);
return sweep;

#!markdown

## Representations

You can create a `Representation` out of multiple solid operations, for more complex geometry. Solid operations may be solid and void, so a representation can be a complex boolean:

#!csharp

var baseExtrude = new Extrude(Polygon.Ngon(6, 5), 6, new Vector3(0,0,1));
var void1 = new Extrude(Polygon.Ngon(4, 2), 7, Vector3.ZAxis, true);
var void2 = new Sweep(Polygon.Star(3, 2, 5), new Line((-5,0,3), (5, 0, 3)),0,0,0, true);
var representation = new Representation(new List<SolidOperation> { baseExtrude, void1, void2 });
return representation;

#!markdown

# Profile Operations
You can also perform useful 2D operations on profiles to create new Profiles. These include:
- `Profile.Offset`
- `Profile.Intersection`
- `Profile.UnionAll`
- `Profile.Split`

among others.

#!csharp

// Offset
var baseProfile = new Profile(Polygon.Star(10,6, 5));
var offsets = Profile.Offset(new [] {baseProfile}, 5);
return new List<Profile> { baseProfile }.Concat(offsets);

#!csharp

// Intersect
var p1 = new Profile(Polygon.Star(8,3, 5));
var p2 = new Profile(Polygon.Rectangle(2, 10));
var intersection = Profile.Intersection(new[] {p1}, new[] {p2});
// Use model curves to display with different colors
var curves = new List<ModelCurve>();
curves.AddRange(p1.ToModelCurves(null, BuiltInMaterials.XAxis));
curves.AddRange(p2.ToModelCurves(null, BuiltInMaterials.YAxis));
curves.AddRange(intersection.SelectMany((p) => p.ToModelCurves(null, BuiltInMaterials.ZAxis)));
return curves;

#!csharp

return Profile.UnionAll(new [] {p1, p2});

#!csharp

var splitLine1 = new Polyline((-10, 0), (0, 1), (10, 0));
var splitLine2 = new Polyline((0,-10), (3, 10));

var splits = Profile.Split(new [] {p1}, new Polyline[] {splitLine1, splitLine2});
var random = new Random(3);
return splits.Select(s => new Extrude(s, random.NextDouble() * 10, Vector3.ZAxis));

#!markdown

# Exercise

Create a profile with a hole, and create an extrude from it. Then, create a representation from the extrude. Consider adding an additional void operation to the represenation to subtract from the extrude. Finally, return the representation.
Loading

0 comments on commit a976ea4

Please sign in to comment.