Knot vecrtor calculation of Maya curves in AbcImport was wrong

317 views
Skip to first unread message

Syoyo Fujita

unread,
Nov 3, 2011, 8:29:52 AM11/3/11
to alembic-d...@googlegroups.com
Hello,

We found a Maya NURBS curve cannot be reconstructed correctly by
AbcExport, then AbcImport.

Attached image illustrates the situation.

I'm not so familiar with definition of Maya curves, but knot vector
must be calculated as follows to match the shape of original Maya
curves
(in the context of open, cubic and multiple-endknots-enabled Maya NURBS curve)

NurbsCurveHelper.cpp::createCurves()

...

MDoubleArray knots;
int numKnots = numVerts + degree - 1;

// Wrong!
//for (j = 0; j < numKnots; ++j)
//{
// knots.append(j/(double)(numKnots-1));
//}

// Correct solution(For open, cubic and multiple-endknots curve).
for (j = 0; j < degree-1; ++j) {
knots.append(0.0);
}

for (j = 0; j < numVerts - 2; ++j) {
knots.append(j);
}

for (j = 0; j < degree-1; ++j) {
knots.append(numVerts - 2 - 1);
}

...


More to say, another problem arising is that how Alembic defines
curves primitive.

Apparently, AbcExport only exports CVs in straight manner, so it is
easy to cause incompatibility with 3rd party tools, e.g. RenderMan's
RiCurves.
Alembic wiki does not describe so much on how curves are defined and exchanged.
(For example, I can see a property of basis matrix in OCurves, but
AbcExport doesn't use this field, and also wiki doesn't describe
it...).

As I said, I am not a Maya curves and NURBS expert, so any comments on
curves primitive are welcome.

Thanks in advance,
Syoyo

screenshot_curve.jpg

Lucas Miller

unread,
Nov 3, 2011, 2:15:30 PM11/3/11
to alembic-d...@googlegroups.com
I think what you are really asking for is a different default
calculation of the knot values.

The solution you provide doesn't allow for a uniform distribution of end knots.

The full snippet of code from AbcImport:

// for now evenly distribute the knots


MDoubleArray knots;
int numKnots = numVerts + degree - 1;

for (j = 0; j < numKnots; ++j)
{
knots.append(j/(double)(numKnots-1));
}

// we need to make sure the first 3 and last 3 knots repeat
if (form == MFnNurbsCurve::kClosed && degree == 3 && numKnots > 2)
{
knots[1] = knots[0];
knots[2] = knots[0];
knots[numKnots-2] = knots[numKnots-1];
knots[numKnots-3] = knots[numKnots-1];
}

The knots are evenly distributed, and if the curve happens to be
cubic, and closed the end knots are repeated.

We haven't tried to support the other types of basis functions in Maya
(when possible).

We would gladly accept any contributions from the community if this is
needed in various pipelines.

Lucas

> --
> You received this message because you are subscribed to the Google
> Groups "alembic-discussion" group.
> To post to this group, send email to alembic-d...@googlegroups.com
> To unsubscribe from this group, send email to
> alembic-discuss...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/alembic-discussion?hl=en
>
> For RSS or Atom feeds related to Alembic, see:
>
> http://groups.google.com/group/alembic-dev/feeds
>
> http://groups.google.com/group/alembic-discussion/feeds
>

Nelson Yu

unread,
Nov 3, 2011, 5:27:15 PM11/3/11
to alembic-discussion
I can confirm that curves exported by Alembic do not match the ones
imported. We export control curves for finalers + lighters to
constrain to so I'm not concerned about the visual shape.

From first glance, it does appear to be a knot issue because all my
closed control curves are imported open and all the sharp creases are
rounded. Haven't looked at the code to see how the knots are written
out and/or read. My initial guess is that knots need to be added at
the end and the discontinuities.

Nelson

Lucas Miller

unread,
Nov 3, 2011, 5:42:31 PM11/3/11
to alembic-d...@googlegroups.com
Knots aren't written to the OCurves, some default knot values are
calculated when read back in.

Aghiles

unread,
Nov 4, 2011, 4:17:16 AM11/4/11
to alembic-discussion
Hello,

I just wanted to step in to explain how we convert Maya NuCurves into
a valid RenderMan Standard representation, hoping that this could be
useful to you guys. But first:

1) If knots are not stored with the actual Nurbs curve there is no way
to make it work.
2) Repeating last knows to some default values like "0" (as suggested
by Mr. Fujita) will also fail once in a while. If something has to be
repeated , that's the values already stored at the beginning and the
end of the knot vector (there is no guarantee that the knot sequence
starts at 0).

Now, if I remember correctly, Maya stores Nurbs curves in some kind of
"shortened" form and has 2 knots less than the equivalent RenderMan
standard representation (one at the beginning and one at the end is
missing). In our 3Delight For Maya plug-in, the knot is constructed
like this:

void
DL_RiNuCurvesNode::setKnots(int i_curve_num, const MDoubleArray&
i_knots )
{
...
int num_in_knots;
int num_knots;

/*
NOTE
- Repeat first and last knot for compatiblity with RenderMan's
representation.
- This function handles many curves at once.
*/
num_in_knots = i_knots.length();
num_knots = num_in_knots + 2;

m_numKnots[i_curve_num] = num_knots;
m_knots[i_curve_num] = new float[num_knots];

for( int i=0; i < num_in_knots; i++ )
m_knots[i_curve_num][i+1] = i_knots[i];

m_knots[i_curve_num][0] = m_knots[i_curve_num][1];
m_knots[i_curve_num][num_in_knots+1] = m_knots[i_curve_num]
[num_in_knots];
}


Exporting this resulting know vector along with the geo using
RiNuCurves will render correct curves using renderman.

I hope this helps.

-- aghiles
www.3delight.com

Syoyo Fujita

unread,
Nov 4, 2011, 11:28:51 AM11/4/11
to alembic-d...@googlegroups.com
Hello Aghiles,

Thanks for the explanation!

> 1) If knots are not stored with the actual Nurbs curve there is no way
> to make it work.
> 2) Repeating last knows to some default values like "0" (as suggested
> by Mr. Fujita) will also fail once in a while. If something has to be
> repeated , that's the values already stored at the beginning and the
> end of the knot vector (there is no guarantee that the knot sequence
> starts at 0).
>
> Now, if I remember correctly, Maya stores Nurbs curves in some kind of
> "shortened" form and has 2 knots less than the equivalent RenderMan
> standard representation (one at the beginning and one at the end is
> missing). In our 3Delight For Maya plug-in, the knot is constructed
> like this:

I have just discussed NURBS things internally with a NURBS expert guy,
and yes, as you pointed out,

1) Knot vectors should be exported by AbcExport.
2) # of knot vectors to be exported should be +2'ed and replicate knot
value in beginning and ending element, in terms of standard NURBS
definition.
3) Knot values are not necessarily in range [0, 1]. It depends on how
knots values are defined in Maya(or more generally in NURBS modeler
and NURBS modeling designer)

So, in next phase, I would like to propose defining "knot" property as
a predefined symbol in curves primitive(OCurves, ICurves), and
AbcExport care about to exporting knot vectors in standard NURBS
manner.

I am ready to provide a patch if a proposal was accepted.

--
Syoyo

Lucas Miller

unread,
Nov 4, 2011, 8:33:12 PM11/4/11
to alembic-d...@googlegroups.com
Not all tools fully support Nurbs Curves, but we could add optional
knots to OCurves.

> 1) Knot vectors should be exported by AbcExport.

They should be optionally exported with a flag.

> 2) # of knot vectors to be exported should be +2'ed and replicate knot
> value in beginning and ending element, in terms of standard NURBS
> definition.

Agreed.

> 3) Knot values are not necessarily in range [0, 1]. It depends on how
> knots values are defined in Maya(or more generally in NURBS modeler
> and NURBS modeling designer)

The uniform range 0 to 1 import, would only occur in AbcImport if the
knot values weren't filled in.

> So, in next phase, I would like to propose defining "knot" property as
> a predefined symbol in curves primitive(OCurves, ICurves), and
> AbcExport care about to exporting knot vectors in standard NURBS
> manner.

It should be part of the schema but treated as optional (only created
if knot values are specified) and a flag should be added to write this
data out.

> I am ready to provide a patch if a proposal was accepted.

Please do, feel free to add the location of the patch to the ticket
you opened for this issue.

Thanks,

Lucas

Aghiles

unread,
Nov 6, 2011, 10:45:25 AM11/6/11
to alembic-discussion

Hello Lucas,

> It should be part of the schema but treated as optional (only created
> if knot values are specified) and a flag should be added to write this
> data out.

Regarding this flag: if you have a flag for not exporting an exisiting
knot vector you should name is something like: export "broken nurbs
curve" :)

What I mean is that there is absolutely no valid reason to export a
nurbs curve without its knot vector. It is equivalent to exporting a
polygon mesh without the Z component for the vertices.

Of course, if there is no knot vector, there is no reason to add one.

-- aghiles

Steve LaVietes

unread,
Nov 6, 2011, 11:54:55 AM11/6/11
to alembic-d...@googlegroups.com
That's not quite fair. It's not "broken nurbs curve" but rather "not a nurbs curve."

The current Curves schema in AbcGeom is not for nurbs curves. It was designed for use with RiCurves calls in the RenderMan spec. To my knowledge, RiNuCurves is not part of that specification -- despite being included in otherwise compliant renderers.

What we're proposing is to allow for knot values to be optionally included so that nurbs curves could be represented for supported systems. Also for cases in which knots are not included, we could provide a more accurate conversion in AbcExport.

-stevel

Aghiles

unread,
Nov 6, 2011, 10:46:57 PM11/6/11
to alembic-discussion
Hello Steve,

On Nov 7, 1:54 am, Steve LaVietes <steve.lavie...@gmail.com> wrote:
> That's not quite fair. It's not "broken nurbs curve" but rather "not a nurbs curve."

Understood. But I hope you see how that can be confusing ? I simply
don't see how someone can export a Nurbs without knots and expecting
something nice. Can someone provide an example ?

> The current Curves schema in AbcGeom is not for nurbs curves. It was designed for use with RiCurves calls in the RenderMan spec. To my knowledge, RiNuCurves is not part of that specification -- despite being included in otherwise compliant renderers.

Understood. IMHO, if it was designed for RiCurves, it should not
include any possibility for RiNuCurves actually, since that is
confusing. I was under the impression that your aim was represent data
as to export any curve correctly and independently of a final render
scheme .

> What we're proposing is to allow for knot values to be optionally included so that nurbs curves could be represented for supported systems. Also for cases in which knots are not included, we could provide a more accurate conversion in AbcExport.

The question is: why not convert correctly at each shot, knots or no
knots ? Is it something people aren't interested in ? Especially that
the good conversion is actually easier than what's in the code now (or
so it seems).

If your aim is efficiency of representation, a better solution might
be: curve is able to hold curve geometry and knot vector data to
correctly represent any curve. If knots are provided, analyse to
detect uniformity, in which case they can be omitted. Analyse 4th
component of each vertex (w) and it is unity, the nurbs is not
rational and the w can be omitted. If both condition hold true, the
nurbs is a BSpline and can be stored as an array of 3D vectors.

Now, in the RenderMan standard:

1) No knots, no W: RiCurves.
2) knots, no W : RiNuCurves with "P" geometry.
3) knots, W : RiNuCurves with "Pw" geometry.

-- aghiles

P.S. I am not an Alembic expert, so I might now understand what your
goals are.

>
> -stevel
>
>
>
> On Sunday, November 6, 2011 at 7:45 AM, Aghiles wrote:
>
> > Hello Lucas,
>
> > > It should be part of the schema but treated as optional (only created
> > > if knot values are specified) and a flag should be added to write this
> > > data out.
>
> > Regarding this flag: if you have a flag for not exporting an exisiting
> > knot vector you should name is something like: export "broken nurbs
> > curve" :)
>
> > What I mean is that there is absolutely no valid reason to export a
> > nurbs curve without its knot vector. It is equivalent to exporting a
> > polygon mesh without the Z component for the vertices.
>
> > Of course, if there is no knot vector, there is no reason to add one.
>
> > -- aghiles
>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "alembic-discussion" group.
> > To post to this group, send email to alembic-d...@googlegroups.com (mailto:alembic-d...@googlegroups.com)
> > To unsubscribe from this group, send email to
> > alembic-discuss...@googlegroups.com (mailto:alembic-discuss...@googlegroups.com)

Steve LaVietes

unread,
Nov 7, 2011, 11:48:55 AM11/7/11
to alembic-d...@googlegroups.com
I think the confusion arises because this discussion involves two
independent issues:

1) What does AbcGeom's Curves schema describe? As previously
mentioned, it maps directly to the RiCurves interface within the
RenderMan specification. It does not currently store enough
information to describe a nurbs curve.

While Alembic has proven useful in additional ways, its initial use at
the original contributing studios (ILM and Sony) has been as a baked
cache for rendering and comparable downstream hand-offs. While it
appears to be a fairly common extension to the RenderMan interface,
RiNuCurves is not officially part of that specification (at least it
doesn't appear in Pixar's RenderMan documentation). At both of our
studios, our experience with the RenderMan interface is primarily
through prman -- which explains why AbcGeom 1.0 does not include a
schema matching RiNuCurves.

If there's a consensus that storing NURBS curves in AbcGeom would be
useful -- and it sounds like there might be -- there are a few
approaches we could take.

There could be a separate AbcGeom schema matching RiNuCurves or the
existing Curves schema could grow optional fields for knots and
weights so that it could answer, "Am I NURBS or not?" Given that some
of its existing fields (such as CurveType, CurvePeriodicity,
BasisType) wouldn't apply directly for NURBS curves (at least as
described by RiNuCurves), it probably makes more sense as a separate
schema. That's a departure from our initial thoughts but we haven't
had many internal discussions yet -- much less reached any decisions.

In either case, that means that some curves are NURBS and some curves
aren't -- which leads us to the second issue.

2) Alembic includes reference implementations of Maya export and
import plugins (AbcExport and AbcImport). Because it's the only
exporter currently included with the Alembic library, it's easy to
conflate its behaviors with the design and intentions of the AbcGeom
layer.

NURBS curves are the common (only?) curve primitives in Maya. Even if
AbcGeom supported NURBS curves directly, it'd still be necessary and
useful to have the option to export to the existing RiCurves-like form
for use in systems which don't support NURBS curves. With the existing
implementation, that can create situations in which a round trip out
and into maya doesn't produce an identical curve -- which is what I
think started this thread. The same issue applies when reading
RiCurves-like data back into Maya.

Assuming that NURBS curves are natively supported in AbcGeom in some
form or another, the second issue is specific to the behavior of
AbcExport and AbcImport:

a) What's the convention (either with command flags or maya
attributes) for indicating whether a NURBS curve should be written as
NURBS or the RiCurves-like form?
b) When writing a NURBS curve in RiCurves form, what technique should
be used to convert the data? It's clear that the current technique
(based on code we've used internally for a long time) does not fit
everyone's needs.

These behaviors are specific to AbcExport and AbcImport and are best
addressed independently of the AbcGeom-level decisions.

-stevel

Reply all
Reply to author
Forward
0 new messages