Edges from Toposurface Boundaries

The boundaries of Revit toposurfaces are not edges. Among other things, this means that topo boundaries can’t be used to create model lines, don’t work with linework, and can’t be selected to define the path of a sweep.

A reader asked if there is a good way to use the API to generate 3D reference lines from a toposurface that could be used as the path for sweeps to represent curbs and gutters for roads, parking lots and driveways. I wrote this bit of code to create model lines from the boundary points of a selected toposurface, but the result is not great, because many small lines are created where a single arc or spline would be preferable and these model lines will not automatically update when the toposurface changes.

Do any of the Revit Site experts out there have ideas about what a more complete solution might be?

public void topoBoundaryLine()
{
    Document doc = this.ActiveUIDocument.Document;
    UIDocument uidoc = this.ActiveUIDocument;
    Application app = this.Application;
    TopographySurface ts1 = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as TopographySurface;
    IEnumerable<XYZ> points = ts1.GetPoints().Where(q => ts1.IsBoundaryPoint(q));

    using (Transaction t = new Transaction(doc,"Create Topo Boundary Lines"))
    {
        t.Start();
        XYZ prev = null;
        foreach (XYZ point in points)
        {
            XYZ pt1 = null;
            XYZ pt2 = null;

            if (prev == null)
            {
                pt1 = points.First();
                pt2 = points.Last();
            }
            else
            {
                pt1 = prev;
                pt2 = point;
            }

            Line line = app.Create.NewLineBound(pt1, pt2);                        
            XYZ v = pt1 - pt2;
            double dxy = Math.Abs(v.X) + Math.Abs(v.Y);
            XYZ w = (dxy > 0.0001) ? XYZ.BasisZ : XYZ.BasisY;
            XYZ norm = v.CrossProduct(w).Normalize();
            SketchPlane skplane = doc.Create.NewSketchPlane(app.Create.NewPlane(norm, pt2));
            ModelCurve mc = doc.Create.NewModelCurve(line, skplane);

            prev = point;
        }
        t.Commit();
    }
}
Advertisements

10 thoughts on “Edges from Toposurface Boundaries

  1. Hey Harry,
    I’m curious if you could make a python node for Dynamo that does this same or similar action: receives a TopographySurface element and outputs XYZs. If you made something like this, I could see about some optimizing routines to get more efficient curves out of it.

    It seems like what you really want though is to get access to the underlying sketch that generated the subregions and project this onto a smooth approximation of the surface. This would get straight line and 3d hermite splines of all the edges (probably not a whole lot of arcs, at least not without a some optimization routines).
    Another approach would be to get the sketch, then for each sketch curve, extract start, middle and end points, and project these onto the surface of the topo. For each group of three points, create an arc (or maybe a hermite curve). Curious what this would look like, would likely have some area where there are funny kinks, but would be a whole lot simpler.

    All of this hinges on if the subregion curve loops are accessible through the API.

    • Hi Zach,

      I think there are (at least) two problems:

      1) The underlying sketch that generated the subregions does not exist after splitting the surface. The toposurface is not like a sketch-based element such as a floor. After you split the surface the “sketch” is gone and only lives on as the new boundary points of the toposurfaces.

      2) There is nothing in the Revit API for projecting a curve onto a mesh (which is the GeometryObject of the toposurface)

      Harry

  2. Hi Harry

    I am still stuck with the following:

    SketchPlane skplane = SketchPlane.Create(app.Create.NewPlane(norm, pt2));

    says
    No overload for method ‘Create’ takes 1 arguments (CS1501) – C:\ProgramData\Autodesk\Revit\Macros\2016\Revit\AppHookup\Tools\Source\Tools\ThisApplication.cs:204,35

  3. There are 3 ways to use SketchPlane.Create. If you want to use a plane to create the sketch plane that is the 2nd option and the document needs to be provided.

    SketchPlane.Create(Document, ElementId) Creates a sketch plane from a grid, reference plane, or level.
    SketchPlane.Create(Document, Plane) Creates a new sketch plane from a geometric plane.
    SketchPlane.Create(Document, Reference) Creates a new sketch plane from a reference to a planar face.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s