CurvesModeling.kl¶
Types¶
Curves (object)¶
The Curves geometry is a Curve container, which can hold one or multiple curves of various types. Currently supported types include linear, Bezier and NURBS curves. Bezier and NURBS can have rational weights, and NURBS can have explicit knots. All curves can be open or closed, and NURBS can be periodic.
Individual curves are assigned a curveIndex that allows to access their individual parameters. In order to ease the access to a single curve, the Curve class wraps the <Curves, curveIndex> pair, and provides the same methods in the context of that curve.
To increase performance with many curves, attributes of all curves, such as point positions, are regrouped in a single GeometryAttributes buffer. Similarly, the definitions of all curves is regrouped in big arrays, allowing to create and interactively draw thousands of curves. The Curves.getAttributeIndex method provides a mapping from a curve sub-point to a global GeometryAttributes index.
The draw sampling precision can be controlled by method Curves.setDrawSamplesPerSpan, and the default is 8 samples per span. GeometryAttribute values, such as UVs and colors, will be interpolated with curve interpolation, with the same weights as the points. To improve interactive display performance of deforming curves, regular sampled curve data can be created and cached with the method Curves.getUpdatedSampling. Curve interpolation weights are pre-computed and cached globally for optimal multithreaded computation speed.
Note: Methods that read Curve parameters, get or set their attributes are thread safe. Methods that modify the curve set or their topology (eg: Curve.addPoints) are not thread safe.
Next, we will give more details about the supported curve types.
Linear curves¶
A linear curve is defining line segments that join each curve points. An additional segment is added from the last to the first point if it is closed. The parametric domain of a linear curve goes from [0..number of segments-1] (Curves.getDomain).
Mathematically, tangents are constant over segments, and there is no curvature. However, in order to have more continuous values, smoothed tangents can be computed so they are interpolated between line segments. This behavior is enabled by default, but can be changed with the method Curves.smoothLinearCurveTangents.
Bezier curves¶
Bezier curves are defined as pieces, and the curve shape for each of these pieces is influenced by N points (N = order = curve degree + 1). Each piece corresponds to one curve span, and the curve’s parametric domain is defined from [0.. number of pieces-1] (Curves.getDomain).
An open Bezier curve of degree D (D = order-1) with N pieces has D*N+1 points. A closed Bezier curve of degree D with N pieces has D*N points. Note that, while it is possible to create a Bezier curve with any number of points, last points that are not forming a complete piece are ignored until more points are added to complete it.
While the curve is continuous inside a piece, curve’s smoothness at the pieces’ boundary depends on the alignment of previous and next points, which can be interpreted as “tangent points”.
NURBS curves¶
NURBS (Non-Uniform Rational B-Spline) curves are a superset of Bezier curves, which can define a curve that can be smooth over an arbitrary number of points (no intrinsic concept of “pieces” like Bezier curves).
Similarly to the Bezier curve, each NURBS curve span (curve section) is influenced by order (degree of the curve + 1) points. When moving from a span to the next one, the set of influencing points changes. For example, if the current span was influenced by points [A,B,C,D], the next span will be influenced by points [B,C,D,E]. At the span boundary, the weight of A becomes zero, while the weight of E becomes non-zero.
There exists three forms of NURBS:
- An open curve (curveForm_open) will clamp the curve to the first and last point positions. Curve’s evaluated position at the beginning of the parametric domain will be the same as point 0, and its position at the end of the parametric domain will be the same as point N-1. Unless specific conditions are set, the curve will not pass by other points, and will evolve between them. The number of curve spans (sections) can be computed as the number of points (P) minus degree (D): P - D. For example, a cubic open curve (degree 3) of 5 points will have 2 spans.
- A closed curve (curveForm_closed) will clamp the curve start and end at point 0. Curve’s evaluated position at the beginning and the end of the parametric domain will be the same as point 0. Unless the first and last points are properly aligned, the curve will not be smooth at point 0. Unless specific conditions are set, the curve will not pass by other points, and will evolve between them. The number of curve spans (sections) can be computed as the number of points (P) minus degree (D) plus one: P - D + 1. For example, a cubic closed curve (degree 3) of 5 points will have 2 spans. Note: As opposed to Maya, the closed curve points don’t include the repeated point.
- A periodic curve (curveForm_periodic) will be defined as if the points defined a circular list. As such, the curve will be smooth everywhere, since it is not clamped to end points. Unless specific conditions are set, the curve will pass by no points, and will evolve between them. The number of curve spans (sections) is equal to the number of points (exluding the repeated points). For example, a cubic periodic curve (degree 3) of 5 points will have 5 spans. Note: As opposed to Maya, the periodic curve points don’t include the D repeated points.
Additionally to points, NURBS curves’ definition include a notion of a knot vector. In most cases, the default knot vector is desired and the user doesn’t have to worry about the notion of knots. Knot values will be automatically created internally to match curve’s number of points and form (open, closed, periodic). Non-default knot values is mostly useful for preserving curve definition when importing from other software. The knot vector defines the parametric interval for each span. For example, this can allow to have the “U” parameter change more slowly depending on the knot vector (eg: knots [-2, -1, 0, 0.5, 2.0, 3.0...]). The number of knots depends strictly of the number of points and the degree of the curve:
- Open curve: the number of knots (K) equals the number of points (P) plus degree (D) - 1: K = P + D - 1
- Closed curve: the number of knots equals the number of points (P) plus degree (D) - 2: K = P + D - 2 Note: As opposed to Maya, the closed curve points don’t include the repeated point.
- Closed curve: the number of knots equals the number of points (P) plus 2*degree (2*D) - 1: K = P + 2*D - 1 Note: As opposed to Maya, the periodic curve points don’t include the D repeated point.
Note: Non-uniform knots are often used to express a Bezier in NURBS form. While this will work, it is better to create a Bezier curve instead, for optimal performance.
Rational curves¶
NURBS and Bezier curves can have rational weights. By default, points are associated with a weight of 1.0. However, it is possible to assign
a different weight to each point (Curves.setPointPosition( UInt32, UInt32, Vec3_d, Float32 )
). The weight is interpreted
relatively to other points that influence a span. Points of higher weight will attract the curve closer to them, while points
with smaller weight will have less influence on curve’s trajectory.
The rational weights for all curves are stored in a ScalarAttribute named “rationalWeights”. This attribute is created only if a weight != 1.0 is set.
A homogeneous coordinate is a 4D coordinate where XYZ are pre-multiplied with the weight: (w*x, w*y, w*z, w).
Before setting rational weights != 1.0 in parallel, ensure that the “rationalWeights” ScalarAttribute exists by calling ensureRationalWeightsAttributeExists
before the parallel evaluation.
Members¶
GeometryAttributes | attributes | Container for all attributes. |
String | debugName | Name that will be printed in descriptions. |
UInt32 | structureVersion | Version of the geometry structure itself, excluding the GeometryAttributes content. |
Boolean | computeGPUBoundingVolume | If positions are on the GPU: if true, the bounding volume is computed, else an infinite bbox is returned. |
ThreadsafeMetaDataContainer | metaData | Container for holding various user data (Geometry specific), such as the BoundingBox cache data, or raycast acceleration structures and data (Octree). |
CurvesStructure | data | |
UInt32 | memType | |
Ref<Vec3Attribute> | positionsAttribute | |
Ref<Vec3_dAttribute> | positionsAttribute_d | |
Ref<ScalarAttribute> | weightsAttribute | |
UInt32 | drawSamplesPerSpan | |
Float32 | drawThickness | |
UInt32 | topoChangesBracket | |
Curves_lengthComputeCache | lengthComputeCache | |
LockedInitialize | lengthComputeCacheInit |
Methods¶
Curves ( in Boolean float64Positions ) | |
Curves ( in Curves other ) | |
Curves ( in String debugName ) | |
Curves () | |
UInt32 | allCurvesPointRange ? () |
applyTransform ! ( in Mat44 transform ) | |
applyTransform ! ( in Xfo transform ) | |
Curves | clone ? () |
convertToCPU ! () | |
convertToGPU ! () | |
copy ! ( in Curves src ) | |
copy ! ( in Geometry src ) | |
copyCurve ! ( in Ref<Curves> sourceCurves, in UInt32 sourceCurveIndex, in UInt32 targetCurveIndex, in Boolean createMissingSourceAttributes ) | |
copyCurve ! ( in UInt32 sourceCurveIndex, in UInt32 targetCurveIndex ) | |
UInt32 | curveCount ? () |
Size | elementCount ? () |
endStructureChanges ! () | |
Vec3[] | getAllPointPositions ? () |
LocalBoundingVolume | getBoundingVolume ? () |
Vec3 | getCurvatureAtNormalizedParam ? ( in UInt32 curveIndex, in Float32 normalizedParam ) |
Vec3 | getCurvatureAtParam ? ( in UInt32 curveIndex, in Float32 param ) |
Curve | getCurve ? ( in UInt32 curveIndex ) |
UInt8 | getCurveType ? ( in UInt32 curveIndex ) |
String | getCurveTypeString ? ( in UInt32 curveIndex ) |
String | getDebugName ? () |
UInt8 | getDegree ? ( in UInt32 curveIndex ) |
Vec3 | getDerivativeAtNormalizedParam ? ( in UInt32 curveIndex, in Float32 normalizedParam ) |
Vec3 | getDerivativeAtParam ? ( in UInt32 curveIndex, in Float32 param ) |
getDerivativesAtNormalizedParam ? ( in UInt32 curveIndex, in Float32 normalizedParam, io Vec3 dU, io Vec3 dUU ) | |
getDerivativesAtParam ? ( in UInt32 curveIndex, in Float32 param, io Vec3 dU, io Vec3 dUU ) | |
Vec2 | getDomain ? ( in UInt32 curveIndex ) |
LocalBoundingVolume | getElementBoundingVolume ? ( in Size index ) |
UInt32 | getMemType ? () |
Ref<ThreadsafeMetaDataContainer> | getMetaData ? () |
Vec3 | getNormalAtNormalizedParam ? ( in UInt32 curveIndex, in Float32 normalizedParam ) |
Vec3 | getNormalAtParam ? ( in UInt32 curveIndex, in Float32 param ) |
UInt8 | getOrder ? ( in UInt32 curveIndex ) |
getPointIndicesAndWeightsAtNormalizedParam ? ( in UInt32 curveIndex, in Float32 normalizedParam, io LocalL8UInt32Array pointIndices, io LocalL8ScalarArray pointWeights ) | |
getPointIndicesAndWeightsAtNormalizedParam ? ( in UInt32 curveIndex, in Float32 normalizedParam, io LocalL8UInt32Array pointIndices, io LocalL8ScalarArray pointWeights, io LocalL8ScalarArray derivativePointWeights ) | |
getPointIndicesAndWeightsAtParam ? ( in UInt32 curveIndex, in Float32 param, io LocalL8UInt32Array pointIndices, io LocalL8ScalarArray pointWeights ) | |
getPointIndicesAndWeightsAtParam ? ( in UInt32 curveIndex, in Float32 param, io LocalL8UInt32Array pointIndices, io LocalL8ScalarArray pointWeights, io LocalL8ScalarArray derivativePointWeights ) | |
Vec3 | getPointPosition ? ( in Size point ) |
Vec3 | getPositionAtNormalizedParam ? ( in UInt32 curveIndex, in Float32 normalizedParam ) |
Vec3_d | getPositionAtNormalizedParam_d ? ( in UInt32 curveIndex, in Float32 normalizedParam ) |
Vec3 | getPositionAtParam ? ( in UInt32 curveIndex, in Float32 param ) |
Vec3_d | getPositionAtParam_d ? ( in UInt32 curveIndex, in Float32 param ) |
UInt32 | getStructureVersion ? () |
getTangentAndCurvatureAtNormalizedParam ? ( in UInt32 curveIndex, in Float32 normalizedParam, io Vec3 tangent, io Vec3 curvature ) | |
getTangentAndCurvatureAtParam ? ( in UInt32 curveIndex, in Float32 param, io Vec3 tangent, io Vec3 curvature ) | |
Vec3 | getTangentAtNormalizedParam ? ( in UInt32 curveIndex, in Float32 normalizedParam ) |
Vec3 | getTangentAtParam ? ( in UInt32 curveIndex, in Float32 param ) |
UInt32 | getVersion ? () |
Boolean | hasFloat64Positions ? () |
incrementPointPositionsVersion ! () | |
Boolean | isRemoved ? ( in UInt32 curveIndex ) |
UInt32 | mergeCurves ! ( in Curves sourceCurves[], in Boolean createMissingSourceAttributes ) |
UInt32 | mergeCurves ! ( in Ref<Curves> sourceCurves, in Boolean createMissingSourceAttributes ) |
Size | pointCount ? () |
Curve | pushCurve ! ( in Curve sourceCurve, in Boolean createMissingSourceAttributes ) |
UInt32 | pushCurve ! ( in Ref<Curves> sourceCurves, in UInt32 sourceCurveIndex, in Boolean createMissingSourceAttributes ) |
reservePoints ! ( in UInt32 curveIndex, in UInt32 pointCount ) | |
setAllPointPositions ! ( in Vec3 positions[] ) | |
setCurveCount ! ( in Size curveCount ) | |
setDrawSamplesPerSpan ! ( in UInt32 samples ) | |
setDrawThickness ! ( in UInt32 pixels ) | |
setPointPosition ! ( in Size point, in Vec3 position ) | |
smoothLinearCurveTangents ! ( in Boolean enable ) | |
Boolean | smoothedLinearCurveTangents ? () |
NURBS methods¶
Curve | addNURBS ! ( in UInt32 pointCount, in UInt8 degree, in UInt8 curveForm ) |
Curve | addNURBS ! ( in UInt8 degree, in UInt8 curveForm, in Float32 knots<> ) |
Curve | addNURBS ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in UInt8 degree, in UInt8 curveForm ) |
Curve | addNURBS ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in UInt8 degree, in UInt8 curveForm, in Float32 knots<> ) |
Curve | addNURBS ! ( in Vec3 pointPositions<>, in UInt8 degree, in UInt8 curveForm ) |
Curve | addNURBS ! ( in Vec3 pointPositions<>, in UInt8 degree, in UInt8 curveForm, in Float32 knots<> ) |
UInt32 | addNURBSIndex ! ( in UInt32 pointCount, in UInt8 degree, in UInt8 curveForm ) |
UInt32 | addNURBSIndex ! ( in UInt8 degree, in UInt8 curveForm, in Float32 knots<> ) |
UInt32 | addNURBSIndex ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in UInt8 degree, in UInt8 curveForm ) |
UInt32 | addNURBSIndex ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in UInt8 degree, in UInt8 curveForm, in Float32 knots<> ) |
UInt32 | addNURBSIndex ! ( in Vec3 pointPositions<>, in UInt8 degree, in UInt8 curveForm ) |
UInt32 | addNURBSIndex ! ( in Vec3 pointPositions<>, in UInt8 degree, in UInt8 curveForm, in Float32 knots<> ) |
Float32 | getNURBSKnot ? ( in UInt32 curveIndex, in UInt32 knotIndex ) |
UInt32 | getNURBSKnotCount ? ( in UInt32 curveIndex ) |
Float32[] | getNURBSKnots ? ( in UInt32 curveIndex ) |
Boolean | isPeriodic ? ( in UInt32 curveIndex ) |
setNURBSKnot ! ( in UInt32 curveIndex, in UInt32 knotIndex, in Float32 knotValue ) |
Attributes methods¶
Ref<GeometryAttributes> | getAttributes ? () |
Bezier methods¶
Curve | addBezier ! ( in UInt32 pieceCount, in UInt8 degree, in Boolean isClosed ) |
Curve | addBezier ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in UInt8 degree, in Boolean isClosed ) |
Curve | addBezier ! ( in Vec3 pointPositions<>, in UInt8 degree, in Boolean isClosed ) |
UInt32 | addBezierIndex ! ( in UInt32 pieceCount, in UInt8 degree, in Boolean isClosed ) |
UInt32 | addBezierIndex ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in UInt8 degree, in Boolean isClosed ) |
UInt32 | addBezierIndex ! ( in Vec3 pointPositions<>, in UInt8 degree, in Boolean isClosed ) |
Curve | addCubicBezier ! ( in UInt32 pieceCount, in Boolean isClosed ) |
Curve | addCubicBezier ! ( in Vec3 pointPositions<>, in Boolean isClosed ) |
Curve | addCubicBezier ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in Boolean isClosed ) |
UInt32 | addCubicBezierIndex ! ( in UInt32 pieceCount, in Boolean isClosed ) |
UInt32 | addCubicBezierIndex ! ( in Vec3 pointPositions<>, in Boolean isClosed ) |
UInt32 | addCubicBezierIndex ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in Boolean isClosed ) |
Curve | addQuadraticBezier ! ( in UInt32 pieceCount, in Boolean isClosed ) |
Curve | addQuadraticBezier ! ( in Vec3 pointPositions<>, in Boolean isClosed ) |
Curve | addQuadraticBezier ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in Boolean isClosed ) |
UInt32 | addQuadraticBezierIndex ! ( in UInt32 pieceCount, in Boolean isClosed ) |
UInt32 | addQuadraticBezierIndex ! ( in Vec3 pointPositions<>, in Boolean isClosed ) |
UInt32 | addQuadraticBezierIndex ! ( in Vec3 pointPositions<>, in Float32 rationalWeights<>, in Boolean isClosed ) |
Debugging methods¶
String | getCurveDesc ? ( in UInt32 curveIndex, in Boolean withAttributes, in Boolean useUnitTestPrint ) |
String | getCurveDescInternal ? ( in UInt32 curveIndex, in Boolean withAttributes, in Boolean useUnitTestPrint, in String indent ) |
String | getDesc ? ( in Boolean withAttributes ) |
String | getDesc ? ( in Boolean withAttributes, in Boolean useUnitTestPrint ) |
Length methods¶
Float32 | getCurveLength ? ( in UInt32 curveIndex ) |
Float32 | getLengthFromParameter ? ( in UInt32 curveIndex, in Float32 param ) |
Float32 | getLengthRatioFromNormalizedParameter ? ( in UInt32 curveIndex, in Float32 normalizedParam ) |
Float32 | getNormalizedParameterFromLengthRatio ? ( in UInt32 curveIndex, in Float32 ratio ) |
Float32 | getParameterFromLength ? ( in UInt32 curveIndex, in Float32 length ) |
setLengthComputeParameters ! ( in Boolean preciseMode, in UInt32 initialSamplesPerSpan, in Float32 preciseModeTolerance ) |
Linear methods¶
Curve | addLinearCurve ! ( in UInt32 pointCount, in Boolean isClosed ) |
Curve | addLinearCurve ! ( in Vec3 pointPositions<>, in Boolean isClosed ) |
UInt32 | addLinearCurveIndex ! ( in UInt32 pointCount, in Boolean isClosed ) |
UInt32 | addLinearCurveIndex ! ( in Vec3 pointPositions<>, in Boolean isClosed ) |
Modeling methods¶
UInt32 | addPoints ! ( in UInt32 curveIndex, in UInt32 addedPointCount ) |
UInt32 | addPoints ! ( in UInt32 curveIndex, in Vec3 pointPositions<> ) |
UInt32 | addPoints ! ( in UInt32 curveIndex, in Vec3 pointPositions<>, in Float32 rationalWeights<> ) |
beginStructureChanges ! () | |
closeCurve ! ( in UInt32 curveIndex ) | |
openCurve ! ( in UInt32 curveIndex ) | |
openOrCloseCurve ! ( in UInt32 curveIndex, in Boolean open ) | |
removeCurve ! ( in UInt32 curveIndex ) |
Point methods¶
ensureRationalWeightsAttributeExists ! () | |
UInt32 | getAttributeIndex ? ( in UInt32 curveIndex, in UInt32 curvePointIndex ) |
UInt32 | getFirstPointIndex ? ( in UInt32 curveIndex ) |
Vec4 | getHomogeneousPointPosition ? ( in UInt32 curveIndex, in UInt32 curvePointIndex ) |
Vec4_d | getHomogeneousPointPosition_d ? ( in UInt32 curveIndex, in UInt32 curvePointIndex ) |
UInt32 | getPointCount ? ( in UInt32 curveIndex ) |
UInt32 | getPointCount ? ( in UInt32 curveIndex, in Boolean includeRepeatedPoints ) |
UInt32 | getPointIndex ? ( in UInt32 curveIndex, in UInt32 curvePointIndex ) |
Vec3 | getPointPosition ? ( in UInt32 curveIndex, in UInt32 curvePointIndex ) |
Vec3_d | getPointPosition_d ? ( in UInt32 curveIndex, in UInt32 curvePointIndex ) |
getPointRange ? ( in UInt32 curveIndex, io UInt32 firstPoint, io UInt32 pointsEnd ) | |
Float32 | getRationalWeight ? ( in UInt32 curveIndex, in UInt32 curvePointIndex ) |
Boolean | isRational ? ( in UInt32 curveIndex ) |
setPointPosition ! ( in UInt32 curveIndex, in UInt32 curvePointIndex, in Vec3 position ) | |
setPointPosition ! ( in UInt32 curveIndex, in UInt32 curvePointIndex, in Vec3 position, in Float32 rationalWeight ) | |
setPointPosition_d ! ( in UInt32 curveIndex, in UInt32 curvePointIndex, in Vec3_d position ) | |
setPointPosition_d ! ( in UInt32 curveIndex, in UInt32 curvePointIndex, in Vec3_d position, in Float32 rationalWeight ) | |
setRationalWeight ! ( in UInt32 curveIndex, in UInt32 curvePointIndex, in Float32 weight ) |
Primitives methods¶
Curve | addLine ! ( in Vec3 start, in Vec3 end ) |
Curve | addLinearArc ! ( in Xfo xfo, in Scalar radius, in Vec2 angleMinMax, in Integer detail ) |
Curve | addLinearCircle ! ( in Xfo xfo, in Scalar radius, in Size detail ) |
addLinearSphere ! ( in Xfo xfo, in Scalar radius, in Size detail ) | |
UInt32 | addRectangle ! ( in Xfo xfo, in Scalar length, in Scalar width ) |
Sampling methods¶
Ref<Curves_samplingData> | getUpdatedSampling ? ( in Boolean computeSampledTangents ) |
Ref<GeometryAttribute> | updateAttributeSampling ! ( io Ref<Curves_samplingData> samplingData, in Ref<GeometryAttribute> attribute ) |