This is part 4 of Scott Conover’s AU 2009 class on

analysing building geometry
.

Curve Types

Revit uses a variety of curve types to represent curve geometry in a document.
The curve types and corresponding Revit API classes include:

  • Bounded line – Line
  • Unbound line – Line
  • Arc – Arc
  • Circle – Arc
  • Elliptical arc – Ellipse
  • Ellipse – Ellipse
  • NURBS – NurbSpline
  • Hermite – HermiteSpline

Here are the definitions and some notes on each of these curve types:

  • Bounded line:
    A line segment defined by its endpoints.
    Obtain endpoints from Curve.get_Endpoint().

  • Unbounded line: An infinite line defined by a location and direction.
    Identify these with Curve.IsBound.
    Evaluate point and tangent vector at raw parameter zero to find the input parameters for the equation of the line.

  • Arc:
    A bound circular arc.
    Begin and end at a certain angle.
    These angles can be obtained by the raw parameter values at each end of the arc.

  • Circle:
    An unbound circle.
    Identify with Curve.IsBound.
    Use raw parameter for evaluation (from 0 to 2π).

  • Elliptical arc:
    A bound elliptical segment.

  • Ellipse:
    An unbound ellipse.
    Identify with Curve.IsBound.
    Use raw parameter for evaluation (from 0 to 2π).

  • Nurbs spline:
    A non-uniform rational B-spline.
    Used for splines sketched in various Revit tools, plus imported geometry.

  • Hermite spline:
    A spline interpolate between a set of points.
    Used for tools like Curve by Points and flexible ducts/pipes, plus imported geometry.

Mathematical representation

Mathematical representations of all of the Revit curve types are given in Appendix A of Scott’s
handout document,
and we include them here as well for easy online access.
This section describes the curve types encountered in Revit geometry, their properties, and their mathematical representations.

Bounded Line

Bound lines are defined by their endpoints.
In the Revit API, obtain the endpoints of the line from the Curve-level get_EndPoint() method.

The equation for a point on a bound line in terms of the normalized parameter ‘u’ and the line endpoints is

P(u) = P1 + u (P2 – P1)
Unbound lines

Unbound lines are handled specially in the Revit API.
Most curve properties cannot be used, however, Evaluate and ComputeDerivatives can be used to obtain locations along the curve when a raw parameter is provided.

The equation for a point for an unbound line in terms of the raw parameter ‘u’, the line origin P and normalized direction vector V is

P(u) = P0 + u V
Arcs and Circles

Arcs and Circles are represented in the Revit API by the Arc class.
They are defined in terms of their radius, center and vector normal to the plane of the arc, which are accessible in the Revit API directly from the Arc class as properties.

Circles have the IsBound property set to true.
This means they can only be evaluated by using a raw parameter (range from 0 to 2π), and the equation for a point on the circle in terms of the raw parameter is

P(u) = C + r ( nx cos(u) + ny sin(u) )

Here the assumption is made that the circle lies in the XY plane.

Arcs begin and end at a certain angle.
These angles can be obtained by the raw parameter values at each end of the arc, and angular values between these values can be plugged into the same equation as above.

Ellipse and Elliptical Arcs

Ellipses and elliptical arcs segments are represented in the Revit API by the Ellipse class.
Similar to arcs and circles, they are defined in a given plane in terms of their X and Y radii, center, and vector normal to the plane of the ellipse.

Full ellipses have the IsBound property set to true.
Similar to circles, they can be evaluated via raw parameter values between 0 and 2π:

P(u) = C + nx rx cos(u) + ny ry sin(u)
NurbSpline

NURBS (non-uniform rational B-splines) are used for spline segments sketched by the user as curves or portions of 3D object sketches.
They are also used to represent some types of imported geometry data.

The data for the NurbSpline include:

  • The control points array P, of length n + 1.
  • The weights array w, also of length n + 1.
  • The curve degree, whose value is equal to one less than the curve order k.
  • The knot vector N, of length n + k + 1.

The parametric formula for a point on the curve is given by

P(u) = ∑ Pi wi Ni,k(u)   /   ∑ wi Ni,k(u)

The sums are over i = 0,…n, and u is limited to the interval 0 < u ≤ umax.

HermiteSpline

Hermite splines are used for curves which are interpolated between a set of control points, like Curve by Points and flexible ducts and pipes in MEP.
They are also used to represent some types of imported geometry data.
In the Revit API, the HermiteSpline class offers access to the arrays of points, tangent vectors and parameters through the ControlPoints, Tangents, and Parameters properties.

The equation for the curve between two nodes in a Hermite spline is

P(u) = h00(u) Pk + (uk+1 – uk) h10(u) Mk + h01(u) Pk+1 + (uk+1 – uk) h11(u) Mk+1

Here Pk and Pk+1 represent the points at each node, Mk and Mk+1 the tangent vectors, and uk and uk+1 the parameters at the nodes, and the basis functions are:

h00(u) = 2u3 – 3u2 + 1

h10(u) = u3 – 2u2 + u

h01(u) = -2u3 + 3u2

h11(u) = u3 – u2

Curve analysis and processing

There are several Curve members which are tools suitable for use in geometric analysis.
In some cases, these APIs do more than you might expect by a quick review of their names.
We will discuss three of them:

  • Intersect
  • Project
  • Tessellate
Intersect

The Intersect method allows you compare two curves to find how they differ or how they are similar. It can be used in the manner you might expect, to obtain the point or point(s) where two curves intersect one another, but it can also be used to identify:

  • Collinear lines
  • Overlapping lines
  • Identical curves
  • Totally distinct curves with no intersections

The return value identifies these different results, and the output IntersectionSetResult contains information on the intersection point(s).

Project

The Project method projects a point onto the curve and returns information about the nearest point on the curve, its parameter, and the distance from the projection point.

Tessellate

This method splits the curve into a series of linear segments, accurate within a default tolerance. For Curve.Tessellate, the tolerance is slightly larger than 1/16′. This tolerance of approximation is the tolerance used internally by Revit as adequate for display purposes.

Note that only lines may be split into output of only two tessellation points; non-linear curves will always output more than two points, even if the curve has an extremely large radius which might mathematically equate to a straight line.

In the next instalment of this series, we will look the Revit API handling of faces.


Comments

17 responses to “Curves”

  1. Hi,
    Is there a way to change the endpoints of the curves?
    I’ve been trying to do this and have been looking for examples, but all I can find is examples of creating new curve-based elements. I’m looking for something like set_endpoints() (I know that method doesnt exist, but is there something like it?).
    Thanks!
    /Erik

  2. Dear Erik,
    It may seem easy to set the endpoint of a bounded line, but it is much more complex for curves in general.
    Furthermore, the Revit 2011 geometry library is mainly read-only, since it only provides read access to the geometry of the Revit building model elements.
    You cannot write to them directly through the geometry, since they are parametrically defined, and the geometry is only a view of them, so to speak.
    So in general the answer is no, no way to change the endpoint of an existing curve, you have to create a new curve from scratch and use that instead.
    Cheers, Jeremy.

  3. Long Nguyen Avatar
    Long Nguyen

    Hi Jeremy
    First of all, thank you for maintaing such a great blog. You and Zach Kron have been inspring me and my students with your blogs.
    In your article you mentioned NURB-Spline and Hermite Spline. I guessed that these correspond to “Spline” and “Spline through points” in Revit user interface. Is this correct?
    If so, Hermite Spline as mentioned in your article depends on the tangent at each control point. But Spline Through Points in Revit does not explicitly let the user control these tangents. So please can you clarify how the tangent is managed with spline-through-points.
    Thanks you very much,

  4. Dear Long Nguyen,
    Thank you for your appreciation, it is a pleasure!
    Zach Kron inspires and entertains me as well, very much!
    The Revit API documentation states that the NurbSpline class represents a NURB spline, and the HermiteSpline class a Hermite spline, so that is not really much help.
    In any case, the description above seems to match what you suggest.
    Does your question refer to the user interface or the programmatic control of these objects?
    Through the user interface, I have no idea whatsoever.
    To control these tangents programmatically, the Hermite spline creation method NewHermiteSpline provides two overloads:
    – (IList(XYZ), Boolean) creates a Hermite spline with default tangency at its endpoints.
    – (IList(XYZ), Boolean, XYZ, XYZ) creates a Hermite spline with specified tangency at its endpoints.
    Cheers, Jeremy.

  5. Long Nguyen Avatar
    Long Nguyen

    Thank you for your (very fast) reply Jeremy.
    I actually referred to the tangent in the user interface, not in the API.
    One question I have heard so many people asked is how to smoothly join two spline-through-points in Revit. I know that in order to do this, we must make sure that the tangents of the two spline-through-points where they meet line up perfectly. Sadly I cannot see how to achieve this since spline-through-points in the revit user interface does not explicitly let the user control the tangents. I know that the other type of spline in the user interface (the NURBS one) does expose the tangents to the user. However, since the control points of these NURB-Spline cannot be attached to reference points, the NURB-Spline are pretty much useless in parametric design where we want to use the parameters to control the shape of the curve.
    Probably I will try to look into the API to see if I can create a new class of Hermite Spline that expose the tangents in the user interface.

  6. Hi Kean,
    How to determine the Curve center between two Curves
    corresponding bellow?
    Arc – Arc
    Circle – Arc
    Elliptical arc – Ellipse
    Ellipse – Ellipse
    NURBS – NurbSpline
    Hermite – HermiteSpline
    Could you help me?
    Thank and Regards,

  7. Hi Bang,
    Is this question for Jeremy or for me? :-)
    Regards,
    Kean

  8. Dear Bang,
    That is a nice geometrical question you have.
    The Revit Geometry API does not provide direct support for that functionality, so you would have to implement it yourself, for instance by querying the two original curves for their underlying parametric definition data, calculating the input data for the curve between the two (complex!), and feeding that into the Revit API again to generate it, e.g.
    http://www.coe.org/p/fo/et/thread=18887
    Cheers, Jeremy.

  9. Hi Jeremy,
    http://www.coe.org/p/fo/et/thread=18887
    I read it and I’ll try, if you have code a specific example in Revit API with NurbSpline, HermiteSpline… I hope you share with me!
    Thank and Regards,

  10. Dear Bang,
    Thank you for the interesting pointer.
    It would be quite easy to implement in Revit, actually, making use of the generic parametrised curve functionality.
    Just determine the two curve parameter ranges, [begin(1),end[1)] and [begin[2], end(2)]. Iterate over the two ranges simultaneously, generating points p(1,i) and p(2,i), calculate the midpaoints between them, and connect the dots.
    Cheers, Jeremy.

  11. Dear Bang,
    I went and implemented my suggestion:
    http://thebuildingcoder.typepad.com/blog/2013/08/generating-a-midcurve-between-two-curve-elements.html
    I hope you like it.
    Cheers, Jeremy.

  12. sandee kumar Avatar
    sandee kumar

    Hello Jeremy,
    I have List of points through which I want to create curve so that I can create family instance.Actually in GSA analysis software there is explicit member which is made of number of elements.Currently I am importing elements of member one by one and so these are separate instance in Revit.If I can create curve through list of points and I will be in situation to create single instance in Revit.Can you please advice me something on this?

  13. Dear Sandeep,
    It is hard for me to say anything, because you leave so many aspects open.
    Especially since it sounds to me as if you are creating the family yourself on the fly.
    That leaves you free to implement it in any way you see fit.
    Sounds like fun.
    Good luck!
    Cheers, Jeremy.

  14. Hi Jeremy!
    could you tell, please, is it possible to create closed spline using Revit API.
    Theoretically it is possible to do using next method:
    NurbSpline Create(
    IList controlPoints,
    IList weights,
    IList knots,
    int degree,
    bool closed,
    bool rational)
    This method has parameter closed, but when I try to create spline with points:
    p1 = new XYZ(28, 4, 0.07);
    p2 = (new XYZ(28, 4, 0.11);
    p3 = (new XYZ(29, 4, 0.09);
    p4 = (new XYZ(30, 4, 0.07);
    p5 = (new XYZ(29, 4, 0.05);
    p6 = (new XYZ(28, 4, 0.03);
    p7 = (new XYZ(28, 4, 0.07);
    Knots are next:
    -0.333333; 0; 0; 0; 0.333333; 0.333333; 0.666667; 0.666667; 1.0; 1.0; 1.0;
    Curve degree = 3, points are 7,
    so knots count = 3 + 7 + 1 = 11.
    But I’m getting error:
    “The size of knots must equal the sum of degree, the size of the controlPoints array and 1. The first degree+1 knots should be identical, as should the last degree+1 knots. The knots in the middle of the sequence must be non-decreasing.”
    If I create spline with only part of points (from p1 to p4 ) I’m getting correct result.
    Does API has some special rule for closed splines?
    Thank you,
    Olga

  15. Dear Olga,
    Sorry this is taking so long. I am discussing the issue with the development team. Please hold on.
    Cheers, Jeremy.

  16. Dear Olga,
    I heard back from the development team. They say:
    We talked it over and couldn’t find a valid use of closed NURBS curves in Revit proper.
    The field is present, but never used. In fact, it would have been better not to expose it to the API in its current state.
    We introduced the method NurbSpline.Create(controlPnts, weights) without the extra options because the rest of the parameters are never really varied in the Revit implementation.
    That being said, the error reported is explaining what the method expects, specifically:
    “The first degree+1 knots should be identical, as should the last degree+1 knots”
    In general, the specified knot sequence doesn’t make sense to us.
    Assuming our closed splines are defined in the same way as open ones, we’d expect something like 0,0,0, [five evenly spaced numbers between 0 and 1], 1, 1, 1.
    I hope this clarifies.
    Cheers, Jeremy.

  17. Thank you very much, Jeremy!
    It’s clear now.
    Best regards,
    Olga

Leave a Reply to BangCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading