Skip to content

Commit 0aa521c

Browse files
authored
Merge pull request #1526 from johnhaddon/curvePinning
CurvesPrimitive : Add WrapMode enum
2 parents d1b950c + a07334f commit 0aa521c

26 files changed

Lines changed: 1224 additions & 459 deletions

Changes

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
11
10.7.x.x (relative to 10.7.0.0a7)
22
========
33

4+
Improvements
5+
------------
6+
7+
- CurvesPrimitive :
8+
- Added `Wrap` enum, with `Periodic`, `NonPeriodic` and `Pinned`. This generalises the previous `periodic` boolean property.
9+
- Added argument names to `variableSize()` and `numSegments()` Python bindings, so they can be passed as keywords.
10+
- USDScene : Added support for pinned curves.
11+
- CurvesAlgo : Added `isPinned()` and `convertPinnedToNonPeriodic()` utilities.
12+
13+
Fixes
14+
-----
15+
16+
- CurvesAlgo : Fixed handling of periodic curves in `deleteCurves()`.
17+
- CurvesAlgo : Fixed `resamplePrimitiveVariable()` to handle Vertex<->Varying conversion for linear curves correctly.
18+
19+
Breaking Changes
20+
----------------
421

22+
- CurvesPrimitive : Made protected members private.
523

624
10.7.0.0a7 (relative to 10.7.0.0a6)
725
==========

contrib/IECoreUSD/src/IECoreUSD/CurvesAlgo.cpp

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,15 @@ using namespace IECoreUSD;
5656
namespace
5757
{
5858

59-
IECore::ObjectPtr readCurves( pxr::UsdGeomCurves &curves, pxr::UsdTimeCode time, const IECore::CubicBasisf &basis, bool periodic, const Canceller *canceller )
59+
IECore::ObjectPtr readCurves( pxr::UsdGeomCurves &curves, pxr::UsdTimeCode time, const IECore::CubicBasisf &basis, CurvesPrimitive::Wrap wrap, const Canceller *canceller )
6060
{
6161
Canceller::check( canceller );
6262
pxr::VtIntArray vertexCountsArray;
6363
curves.GetCurveVertexCountsAttr().Get( &vertexCountsArray, time );
6464
IECore::IntVectorDataPtr countData = DataAlgo::fromUSD( vertexCountsArray );
6565

6666
Canceller::check( canceller );
67-
IECoreScene::CurvesPrimitivePtr newCurves = new IECoreScene::CurvesPrimitive( countData, basis, periodic );
67+
IECoreScene::CurvesPrimitivePtr newCurves = new IECoreScene::CurvesPrimitive( countData.get(), basis, wrap );
6868
PrimitiveAlgo::readPrimitiveVariables( curves, time, newCurves.get(), canceller );
6969

7070
Canceller::check( canceller );
@@ -116,19 +116,23 @@ IECore::ObjectPtr readBasisCurves( pxr::UsdGeomBasisCurves &curves, pxr::UsdTime
116116

117117
// Wrap
118118

119-
bool periodic = false;
120-
pxr::TfToken wrap;
121-
curves.GetWrapAttr().Get( &wrap, time );
122-
if( wrap == pxr::UsdGeomTokens->periodic )
119+
CurvesPrimitive::Wrap wrap = IECoreScene::CurvesPrimitive::Wrap::NonPeriodic;
120+
pxr::TfToken usdWrap;
121+
curves.GetWrapAttr().Get( &usdWrap, time );
122+
if( usdWrap == pxr::UsdGeomTokens->periodic )
123+
{
124+
wrap = IECoreScene::CurvesPrimitive::Wrap::Periodic;
125+
}
126+
else if( usdWrap == pxr::UsdGeomTokens->pinned )
123127
{
124-
periodic = true;
128+
wrap = IECoreScene::CurvesPrimitive::Wrap::Pinned;
125129
}
126-
else if( wrap != pxr::UsdGeomTokens->nonperiodic )
130+
else if( usdWrap != pxr::UsdGeomTokens->nonperiodic )
127131
{
128-
IECore::msg( IECore::Msg::Warning, "USDScene", "Unsupported wrap \"{}\" reading \"{}\"", wrap.GetString(), curves.GetPath().GetAsString() );
132+
IECore::msg( IECore::Msg::Warning, "USDScene", "Unsupported wrap \"{}\" reading \"{}\"", usdWrap.GetString(), curves.GetPath().GetAsString() );
129133
}
130134

131-
return readCurves( curves, time, basis, periodic, canceller );
135+
return readCurves( curves, time, basis, wrap, canceller );
132136
}
133137

134138
bool basisCurvesMightBeTimeVarying( pxr::UsdGeomBasisCurves &curves )
@@ -153,7 +157,7 @@ IECore::ObjectPtr readNurbsCurves( pxr::UsdGeomNurbsCurves &curves, pxr::UsdTime
153157
basis = CubicBasisf::bSpline();
154158
}
155159

156-
return readCurves( curves, time, basis, false, canceller );
160+
return readCurves( curves, time, basis, CurvesPrimitive::Wrap::NonPeriodic, canceller );
157161
}
158162

159163
bool nurbsCurvesMightBeTimeVarying( pxr::UsdGeomNurbsCurves &curves )
@@ -185,10 +189,20 @@ bool writeCurves( const IECoreScene::CurvesPrimitive *curves, const pxr::UsdStag
185189

186190
usdCurves.CreateCurveVertexCountsAttr().Set( DataAlgo::toUSD( curves->verticesPerCurve() ), time );
187191

188-
usdCurves.CreateWrapAttr().Set(
189-
curves->periodic() ? pxr::UsdGeomTokens->periodic : pxr::UsdGeomTokens->nonperiodic,
190-
time
191-
);
192+
pxr::TfToken wrap;
193+
switch( curves->wrap() )
194+
{
195+
case CurvesPrimitive::Wrap::NonPeriodic :
196+
wrap = pxr::UsdGeomTokens->nonperiodic;
197+
break;
198+
case CurvesPrimitive::Wrap::Periodic :
199+
wrap = pxr::UsdGeomTokens->periodic;
200+
break;
201+
case CurvesPrimitive::Wrap::Pinned :
202+
wrap = pxr::UsdGeomTokens->pinned;
203+
break;
204+
}
205+
usdCurves.CreateWrapAttr().Set( wrap, time );
192206

193207
pxr::TfToken basis;
194208
if( curves->basis() == CubicBasisf::bezier() )

glsl/IECoreGL/CurvesPrimitive.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@
4747
layout( lines_adjacency ) in;\
4848
layout( line_strip, max_vertices = 10 ) out;\
4949
\
50+
in int geometryIsCurveEndPoint[];\
51+
\
5052
uniform mat4x4 basis;\
53+
uniform mat4x4 phantomBasis0;\
54+
uniform mat4x4 phantomBasis1;\
55+
uniform mat4x4 phantomBasis2;\
5156
\
5257
IECOREGL_CURVESPRIMITIVE_DECLARE_VERTEX_PASS_THROUGH_PARAMETERS
5358

@@ -65,16 +70,36 @@
6570
layout( lines_adjacency ) in;\
6671
layout( triangle_strip, max_vertices = 20 ) out;\
6772
\
73+
in int geometryIsCurveEndPoint[];\
74+
\
6875
uniform mat4x4 basis;\
76+
uniform mat4x4 phantomBasis0;\
77+
uniform mat4x4 phantomBasis1;\
78+
uniform mat4x4 phantomBasis2;\
6979
uniform float width;\
7080
\
7181
IECOREGL_CURVESPRIMITIVE_DECLARE_VERTEX_PASS_THROUGH_PARAMETERS
7282

83+
#define IECOREGL_CURVESPRIMITIVE_SELECT_BASIS \
84+
mat4x4 selectedBasis;\
85+
if( bool( geometryIsCurveEndPoint[1] ) )\
86+
{\
87+
selectedBasis = bool( geometryIsCurveEndPoint[2] ) ? phantomBasis2 : phantomBasis0;\
88+
}\
89+
else if( bool( geometryIsCurveEndPoint[2] ) )\
90+
{\
91+
selectedBasis = phantomBasis1;\
92+
}\
93+
else\
94+
{\
95+
selectedBasis = basis;\
96+
}
97+
7398
#define IECOREGL_CURVESPRIMITIVE_COEFFICIENTS( t ) \
74-
ieCurvesPrimitiveCoefficients( basis, t )
99+
ieCurvesPrimitiveCoefficients( selectedBasis, t )
75100

76101
#define IECOREGL_CURVESPRIMITIVE_DERIVATIVE_COEFFICIENTS( t ) \
77-
ieCurvesPrimitiveDerivativeCoefficients( basis, t )
102+
ieCurvesPrimitiveDerivativeCoefficients( selectedBasis, t )
78103

79104
#define IECOREGL_CURVESPRIMITIVE_POSITION( coeffs )\
80105
ieCurvesPrimitivePosition( coeffs )
@@ -96,7 +121,7 @@ vec4 ieCurvesPrimitiveCoefficients( in mat4x4 basis, in float t )
96121
float t2 = t * t;
97122
float t3 = t2 * t;
98123

99-
return vec4(
124+
return vec4(
100125
basis[0][0] * t3 + basis[1][0] * t2 + basis[2][0] * t + basis[3][0],
101126
basis[0][1] * t3 + basis[1][1] * t2 + basis[2][1] * t + basis[3][1],
102127
basis[0][2] * t3 + basis[1][2] * t2 + basis[2][2] * t + basis[3][2],

include/IECoreGL/CurvesPrimitive.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
#include "IECoreGL/Export.h"
3939
#include "IECoreGL/Primitive.h"
4040

41+
#include "IECoreScene/CurvesPrimitive.h"
42+
4143
#include "IECore/CubicBasis.h"
4244
#include "IECore/VectorTypedData.h"
4345

@@ -52,6 +54,8 @@ class IECOREGL_API CurvesPrimitive : public Primitive
5254

5355
IE_CORE_DECLARERUNTIMETYPEDEXTENSION( IECoreGL::CurvesPrimitive, CurvesPrimitiveTypeId, Primitive );
5456

57+
CurvesPrimitive( const IECore::CubicBasisf &basis, IECoreScene::CurvesPrimitive::Wrap wrap, IECore::ConstIntVectorDataPtr vertsPerCurve, float width=1.0f );
58+
/// \deprecated Use the version taking `wrap` argument instead.
5559
CurvesPrimitive( const IECore::CubicBasisf &basis, bool periodic, IECore::ConstIntVectorDataPtr vertsPerCurve, float width=1.0f );
5660
~CurvesPrimitive() override;
5761

@@ -89,10 +93,6 @@ class IECOREGL_API CurvesPrimitive : public Primitive
8993

9094
void renderMode( const State *state, bool &linear, bool &ribbons ) const;
9195

92-
static const std::string &cubicLinesGeometrySource();
93-
static const std::string &cubicRibbonsGeometrySource();
94-
static const std::string &linearRibbonsGeometrySource();
95-
9696
void ensureVertIds() const;
9797
void ensureAdjacencyVertIds() const;
9898
void ensureLinearAdjacencyVertIds() const;

include/IECoreGL/PointsPrimitive.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ class IECOREGL_API PointsPrimitive : public Primitive
9595

9696
Type effectiveType( const State *state ) const;
9797

98-
static std::string &instancingVertexSource();
99-
10098
IE_CORE_FORWARDDECLARE( MemberData );
10199

102100
MemberDataPtr m_memberData;

include/IECoreScene/CurvesAlgo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,15 @@ IECORESCENE_API CurvesPrimitivePtr deleteCurves( const CurvesPrimitive *curvesPr
6464
/// completely segmententing the curves based on the unique values in a primitive variable.
6565
IECORESCENE_API std::vector<CurvesPrimitivePtr> segment( const CurvesPrimitive *curves, const PrimitiveVariable &primitiveVariable, const IECore::Data *segmentValues = nullptr, const IECore::Canceller *canceller = nullptr );
6666

67+
/// Returns true if wrap is pinned and basis is BSpline or CatmullRom.
68+
IECORESCENE_API bool isPinned( const CurvesPrimitive *curves );
69+
70+
/// If `Curves::wrap()` is `pinned`, converts it to `NonPeriodic`, adding "phantom" endpoints as required.
71+
/// If wrap is not pinned, does nothing.
72+
IECORESCENE_API void convertPinnedToNonPeriodic( CurvesPrimitive *curves, const IECore::Canceller *canceller = nullptr );
73+
6774
/// Update the number of replicated end points based on the basis.
75+
/// \deprecated Use pinned curves instead.
6876
IECORESCENE_API CurvesPrimitivePtr updateEndpointMultiplicity( const CurvesPrimitive *curves, const IECore::CubicBasisf& cubicBasis, const IECore::Canceller *canceller = nullptr );
6977

7078
} // namespace CurveAlgo

include/IECoreScene/CurvesPrimitive.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,17 @@ class IECORESCENE_API CurvesPrimitive : public Primitive
5151
{
5252
public :
5353

54+
enum class Wrap
55+
{
56+
NonPeriodic,
57+
Periodic,
58+
Pinned
59+
};
60+
5461
CurvesPrimitive();
55-
/// Copies of vertsPerCurve and p are taken.
62+
/// Copies of `vertsPerCurve` and `p` are taken.
63+
CurvesPrimitive( const IECore::IntVectorData *vertsPerCurve, const IECore::CubicBasisf &basis=IECore::CubicBasisf::linear(), Wrap wrap = Wrap::NonPeriodic, const IECore::V3fVectorData *p = nullptr );
64+
/// \deprecated Use the version taking `wrap` argument.
5665
CurvesPrimitive( IECore::ConstIntVectorDataPtr vertsPerCurve, const IECore::CubicBasisf &basis=IECore::CubicBasisf::linear(), bool periodic = false, IECore::ConstV3fVectorDataPtr p = nullptr );
5766
~CurvesPrimitive() override;
5867

@@ -61,7 +70,12 @@ class IECORESCENE_API CurvesPrimitive : public Primitive
6170
size_t numCurves() const;
6271
const IECore::IntVectorData *verticesPerCurve() const;
6372
const IECore::CubicBasisf &basis() const;
73+
Wrap wrap() const;
74+
/// \deprecated Use `wrap() == Wrap::Periodic`.
6475
bool periodic() const;
76+
/// A copy of `verticesPerCurve` is taken.
77+
void setTopology( const IECore::IntVectorData *verticesPerCurve, const IECore::CubicBasisf &basis, Wrap wrap );
78+
/// \deprecated Use the version taking `wrap` argument.
6579
void setTopology( IECore::ConstIntVectorDataPtr verticesPerCurve, const IECore::CubicBasisf &basis, bool periodic );
6680

6781
/// Follows the RenderMan specification for variable sizes.
@@ -72,27 +86,25 @@ class IECORESCENE_API CurvesPrimitive : public Primitive
7286
/// Returns the number of segments in a given curve.
7387
unsigned numSegments( unsigned curveIndex ) const;
7488
/// Returns the number of segments of a curve with the given topology.
89+
static unsigned numSegments( const IECore::CubicBasisf &basis, Wrap wrap, unsigned numVerts );
90+
/// \deprecated Use the version taking `wrap` argument.
7591
static unsigned numSegments( const IECore::CubicBasisf &basis, bool periodic, unsigned numVerts );
7692

7793
/// Creates a wireframe box of the specified size.
7894
static Ptr createBox( const Imath::Box3f &b );
7995

8096
void topologyHash( IECore::MurmurHash &h ) const override;
8197

82-
protected :
83-
84-
/// Throws an exception if numVerts is an inappropriate number for the current basis.
85-
static unsigned int numSegments( bool linear, int step, bool periodic, int numVerts );
98+
private :
8699

87100
IECore::CubicBasisf m_basis;
88-
bool m_linear;
89-
bool m_periodic;
101+
// Cached from `m_basis.standardBasis()`.
102+
IECore::StandardCubicBasis m_standardBasis;
103+
Wrap m_wrap;
90104
IECore::IntVectorDataPtr m_vertsPerCurve;
91105
unsigned m_numVerts;
92106
unsigned m_numFaceVarying;
93107

94-
private :
95-
96108
static const unsigned int m_ioVersion;
97109

98110
};

include/IECoreScene/CurvesPrimitiveEvaluator.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ class IECORESCENE_API CurvesPrimitiveEvaluator : public PrimitiveEvaluator
118118
};
119119
IE_CORE_DECLAREPTR( Result );
120120

121+
/// > Note : If `curves` are Pinned, then they are converted to NonPeriodic
122+
/// > internally. PrimitiveVariable queries must therefore be made using
123+
/// > `CurvesPrimitiveEvaluator::primitive()` rather than the original `curves`
124+
/// > object.
121125
CurvesPrimitiveEvaluator( ConstCurvesPrimitivePtr curves );
122126
~CurvesPrimitiveEvaluator() override;
123127

@@ -184,7 +188,7 @@ class IECORESCENE_API CurvesPrimitiveEvaluator : public PrimitiveEvaluator
184188

185189
float integrateCurve( unsigned curveIndex, float vStart, float vEnd, int samples, Result& typedResult ) const;
186190

187-
CurvesPrimitivePtr m_curvesPrimitive;
191+
ConstCurvesPrimitivePtr m_curvesPrimitive;
188192
const std::vector<int> &m_verticesPerCurve;
189193
std::vector<int> m_vertexDataOffsets; // one value per curve
190194
std::vector<int> m_varyingDataOffsets; // one value per curve

include/IECoreScene/private/PrimitiveVariableAlgos.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,7 @@ class DeleteFlaggedVaryingFunctor : public DeleteFlagged<U>
291291
size_t offset = 0;
292292
for( size_t c = 0; c < m_curvesPrimitive->numCurves(); ++c )
293293
{
294-
int numVarying = m_curvesPrimitive->numSegments( c ) + 1;
295-
294+
const int numVarying = m_curvesPrimitive->variableSize( PrimitiveVariable::Varying, c );
296295
if( this->shouldKeepPrimitive( c ) )
297296
{
298297
for( int v = 0; v < numVarying; ++v )

0 commit comments

Comments
 (0)