code-google-com / alembic

Automatically exported from code.google.com/p/alembic
Other
0 stars 0 forks source link

Feature Request - Render Poly as Subd in alembic prman #129

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
This is a feature of 3delight my studio uses a lot, so I am implementing it in 
the DSO right now. I just thought a lot of people would be happy to have this 
option in the next release of the repository.

Best regards,
Nik Velinov

What steps will reproduce the problem?
1.
2.
3.

What is the expected output? What do you see instead?

What version of the product are you using? On what operating system?

Please provide any additional information below.

Original issue reported on code.google.com by nik.veli...@gmail.com on 30 Dec 2010 at 3:22

GoogleCodeExporter commented 9 years ago
Hi Nik, that sounds pretty great!  I have a question, though: without creases, 
a polymesh will be all rounded (eg, the vertices of a poly cube will render as 
a sphere if given to RiSubdivisionMesh()); are crease or corner data added to 
the polymesh?

The naive way to do this is to simply tweak the conditionals in WriteGeo.cpp to 
check for a special name or piece of MetaData that would tell it to call 
ProcessSubD() on a PolyMesh object.  It may be worthwhile to establish a 
convention for MetaData on meshes, something like "RenderAs=subd" or 
"RenderAs=polymesh".

Original comment by ard...@gmail.com on 30 Dec 2010 at 10:00

GoogleCodeExporter commented 9 years ago
I think it would be most useful for the procedural to be able to produce 
different geometric representations for the same object in the upon request.  
So this would be an argument to the procedural, not a hint on the object in the 
archive itself.  That way you could have a single mesh stored but have it 
presented to the rendered as a subdued for primary/camera rays but a poly 
surface (faster to ray trace, uses less memory) for secondary rays.  This will 
definitely be useful and was on my own internal wish-list for the procedural, 
so by all means go for it :)

Don't forget to sign the contributor agreement if you want your changes 
included in the distribution!

Original comment by tommy.bu...@gmail.com on 30 Dec 2010 at 11:39

GoogleCodeExporter commented 9 years ago
Hey, Joe and Tommy, Happy New Year and best wishes to both of you!

My original idea for the implementation was more along the lines of Tommy's
suggestion -- there is a flag "-renderAsSubd" that can be applied to the
Procedural call in the rib file and sets a boolean in the ProcArgs. When the
Subdivide() function is processing a polymesh, it checks against this
boolean, and consequently calls a subdivision primitive instead of a polygon
one. It also strips the poly normals from the parameter list, as they only
produce a faceted look if kept. Really simple and naive but works. ;)

So, in this manner we can have a cube render both as a cube and as a sphere
from the same archive. If anyone needs to use corners and creases data, I
suppose they could export the animation straight to a subdivision surface
archive. It just did not seem right to me to change the internal
representation of a polymesh by adding data for something it is not - a
subd.

I've attached the files I messed with -- ProcArgs.h ProcArgs.cpp and
WriteGeo.cpp. If you by chance happen to like the changes, you can include
them in the distribution or modify them as you wish, I've signed whatever
agreement was necessary. :)
Have a great day!

Nik

Original comment by nik.veli...@gmail.com on 3 Jan 2011 at 4:57

GoogleCodeExporter commented 9 years ago
Hi Nik and folks,

I do think we need to able to go the other direction as well- i.e. render an 
object that is in the archive as a subd out to prman as a polysurface.  it 
would mean having to compute the normals for the poly on the fly, but I don't 
think that should be too difficult.  For my purposes I think this one would be 
even more useful than rendering a poly as subd, or at least it is something 
that I have definitely found a need for in the past.

is there any meaningful way to support this kind of "output as" idea in a more 
general way or is poly -> subd and subd -> poly the only real use case?

Original comment by tommy.bu...@gmail.com on 4 Jan 2011 at 2:57

GoogleCodeExporter commented 9 years ago
assigning to myself for now until we get assigned to a dev resource.

Original comment by scottmmo...@gmail.com on 5 Jan 2011 at 1:30

GoogleCodeExporter commented 9 years ago
This is an interesting question, Tommy. I have given it a little thought
myself. Theoretically, I think all the types of geometry that one can easily
animate in Maya as one type and then convert to some other type with
predictable results at render time are worth considering. At first glance,
it seems to me it might be useful at some point to render, say, a polygon
mesh as a point cloud, nurbs surface as polygons, or a fluid simulation as
poly or subdiv... So far I haven't come across a case where I needed to use
any of those, though...So, just thinking aloud and would love to hear from
someone with more production experience if any similar features seem
applicable in practice and are actually worth the trouble implementing. :)

Nik

Original comment by nik.veli...@gmail.com on 5 Jan 2011 at 8:20

GoogleCodeExporter commented 9 years ago
Hi Nik,

Thanks so much for your contributions. We are really enjoying the community 
aspect of open source, especially on such a significant project.

For some housekeeping on our side, you had mentioned previously that you signed 
a copy of the contributor agreement. If you had done that, would you mind 
sending a copy our way or attaching it to this ticket. If you wish to email it 
to me directly, please send it to smorrissey@ilm.com

If you hadn't done that, let me know and we'll be sure to get the agreement out 
to you.

Thanks, Scott

Original comment by scottmmo...@gmail.com on 5 Jan 2011 at 8:24

GoogleCodeExporter commented 9 years ago

Original comment by ard...@gmail.com on 13 Jan 2011 at 9:21

GoogleCodeExporter commented 9 years ago

Original comment by ble...@gmail.com on 7 Jul 2011 at 10:21

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I think that this type of thing would be better handled using RenderMan user 
attributes.

They can be hierarchial, so if your facility insists on rendering all polygon 
surfaces as subd's (the norm in my experience), then you can do that by simply 
putting a user attribute at the top of the rib.  For instance:

Attribute "user" "float abcRenderasSubd" [1]

Then you can still, due to the hierarchy, turn that off at an individual object 
level, for instance (via attribute blocks).

That's what RenderMan attributes are for.

IMO there should be no arguments to the procedural at all.  It should take all 
of it's arguments via user attributes in the rib - including the filename of 
the alembic file, etc. etc.  Especially for things like the shutter this makes 
sense, since a per-object shutter is rare, encouraging you to simply set it 
once, at the top of the rib file.

This also makes editing RIBs (if you are in a small facility this tends to 
happen a fair bit) an easier alternative then having to edit every single 
procedural call to the alembic procedural.

Some food for thought.

I used this technique on a very large production recently that churned through 
thousands and thousands of frames per day containing hundreds of thousands of 
procedural calls each (not Alembic, it was a different but similar HDF5-based 
system I designed about 4 years ago), and the attribute method was a big 
organizational win over the argument passing method.

cheers,

Luke

Original comment by evolutio...@gmail.com on 14 Feb 2012 at 10:29

GoogleCodeExporter commented 9 years ago
Another important thing to note is the subdivision optional arguments - the 
most important of which is the "interpolateboundary" flag.  If you are going to 
support a renderassubd option, then you should also support that flag.

The way I implemented this in the past was a bit more flexible though.

A polygon mesh can be represented at rendertime as an RiPointsPolygons (1 for 
1), an RiSubdivisionMesh (input data the same, but output subdivided at render 
time) with or without interpolated boundary, a set of RiPoints (if no topology 
is specified), a set of blobby points RiBlobby, or a set of curves RiCurves.

The RiCurves can be defined using each polygon of the input mesh as a closed or 
open curve.  This assumes that the Alembic polygon mesh was exported with this 
in mind, and, hence, all polygons would not be welded to each other.

This is the technique I have used before, in a simpler system without direct 
support for these types.

The attributes were:

Attribute "user" "string type" 
["RiPointsPolygons"|"RiSubdivisionMesh"|"RiPoints"|"RiBlobby"|"RiCurves"]

with optional arguments such as:

Attribute "user" "float interpolateboundary" [1]

for instance.

This system is very flexible too, especially when a client can't directly 
export a set of curves for instance, you can encode them into a mesh, and still 
make use of primitive attributes for things like width definition (since a mesh 
still has primitive attribute ability per vertex).

Original comment by evolutio...@gmail.com on 14 Feb 2012 at 10:37

GoogleCodeExporter commented 9 years ago
The included RenderMan procedural is a reference implementation. The argument 
parsing portion of the code is isolated to ProcArgs.cpp -- so it should be 
pretty easy to season to taste while keeping in sync with ongoing development.

Original comment by steve.lavietes@gmail.com on 14 Feb 2012 at 10:43

GoogleCodeExporter commented 9 years ago
I understand that, and agree.
But part of the allure for smaller studios with Alembic is the potential that 
it could supply "a small-project pipeline" backbone.  It's just really not 
currently in that state at the moment.  Out of the box it still needs work to 
be useful straight away.  I understand the points about customising it for a 
studio etc. but that really just creates a divide between bigger studios with 
technical support, and smaller ones without it.  I don't really understand why 
this needs to be the case.

Reference implementation are nice, but fully functioning and small-production 
read implementations are much nicer.

I'll make some suggestions, write some code, contribute it back, and see what 
happens.

Original comment by evolutio...@gmail.com on 15 Feb 2012 at 12:45

GoogleCodeExporter commented 9 years ago
The way the code in ProcArgs.cpp is structured, we could add user attributes 
checks prior to the string parsing code -- so either would work.

Since user attributes aren't ordered and can only be queried by known name, not 
all of the existing individual arguments make sense in that form. Specially, 
the -resource and -args flags can appear more than once and their order is 
meaningful. But, the common cases you cite (like shutter) would certainly 
benefit 

Original comment by steve.lavietes@gmail.com on 15 Feb 2012 at 12:54

GoogleCodeExporter commented 9 years ago
Absolutely agreed, however, since -resouce and -args are strings anyway, there 
is no reason they could not have Attribute support:

Attribute "user" "string abcResource" ["somestuff"]
Attribute "user" "string abcArgs" ["somestuff"]

seem perfectly reasonable and equivalent considering they are passed as strings 
anyway.

Original comment by evolutio...@gmail.com on 15 Feb 2012 at 1:09

GoogleCodeExporter commented 9 years ago
Yes -- but the order in which they appear relative to one another can be 
meaningful. 

-args /tmp/some.args -resource someShape someResource 
...can differ from...
-resource someShape someResource -args /tmp/some.args 
...if /tmp/some.args contains...
-resource someShape someOtherResource

It's not going to be a common case. As long as both forms (attribute and 
paramstr flag) are supported, it seems reasonable to accept minor limitations 
of the attribute form.

My intital response was driven mostly by reluctance to open debate on details 
which are equivalent but for studio or personal preference (or uniquely 
established workflow). But, the attribute query form is additionally useful in 
many cases -- so I concede the point. :)

(In the unlikely event that there's measurable overhead to many attribute 
queries per procedural instantiation, we could also activate it via a paramstr 
flag.)

Original comment by steve.lavietes@gmail.com on 15 Feb 2012 at 1:25

GoogleCodeExporter commented 9 years ago
All valid points.  In fact my experience with this is that the Attribute form 
(at least in the case of 3Delight, I can't speak for anything else, as the last 
major project I worked on was all 3Delight based) is many many times faster 
than parsing the data yourself.

This is mostly because you only need to parse the data once if it is defined at 
the root level of the rib, the rest of the times you are looking up an entry in 
a constant time hash-table.  With the standard version it's a requirement to 
pass everything every time - which can have other more low-level implications.  
The speed win, for a VERY dense scene of procedurals, is quite surprising.

But yes, adding such dual support would be fantastic, so thanks for 
understanding my points and I look forward to seeing this in the future.  When 
adding such features, what standards do you have for naming and feature lists, 
or is this something continually in flux?

With the rib case I think that prefixing the Attribute names with "abc" or 
"abc:" would be quite useful to kind of "namespace" them in rib land to avoid 
clashes.

Another quick point.  For the shutter time, an implementation that I've used 
and works well, is to read the "Frame:Shutter" attribute directly to obtain the 
float[2] data for the open and close shutter times.  This along with the other 
available data (outlined below) can cover all generic cases for automatic 
inference of the shutter type (leading/centred/trailing), width and frame, 
without the user having to specify a thing.  In 3Delight you can access this 
using (this is for C++, and is something similar to but I didn't check this):

float shutter[2];
RxAttribute( "Shutter", &shutter, 2, NULL, NULL );

and the same is true of "shutter:offset" and "Ri:FrameBegin".

Using these was how previous procedurals I've written work.  Also reading the 
shutter offset allows you to cater for the "all ribs start at frame 0" approach 
that 3Delight for Maya takes, along with a more typical general case, all 
automatically.

cheers again,

Luke

Original comment by evolutio...@gmail.com on 15 Feb 2012 at 3:39

GoogleCodeExporter commented 9 years ago
Having though this over further, here's my proposed idea.
User attribute querying is activated in these cases:
1) the paramstr is empty
2) a -fromAttrs flag is present

This places no burden on someone wanting to rely exclusively on user 
attributes. It also allows for control over the precedence of user attributes 
vs paramstr flags as -fromAttrs can be present anywhere within the string.

Original comment by steve.lavietes@gmail.com on 15 Feb 2012 at 3:25

GoogleCodeExporter commented 9 years ago
I think this makes a lot of sense.
Personally however, I would therefore choose to use it with the paramstr empty 
every time (ideally this test would be an early bail immediately after an 
std::string.empty() call to keep things as efficient as possible), but I can 
totally understand that you would want to keep supporting the paramstring args, 
and, doing it that way with the two options for doing so is a very good idea.

Thanks!

Original comment by evolutio...@gmail.com on 15 Feb 2012 at 10:59

GoogleCodeExporter commented 9 years ago
Another option, not that I am intending on making things more complex, but it's 
an option to consider, is to actually parse in the entire argument line via an 
attribute.

You could do this using a string array attribute for the options and arguments, 
i.e.

Attribute "user" "string[] abc:argstring" ["-filename" "thing.abc" "-frame" 
"10"] etc. etc. etc.

Not sure if there is any huge gain doing things this way, however, it's worth 
considering if someone else pipes up in this thread and asks for that.

For the moment however, I am still preferring the existing versions we have 
discussed.

Original comment by evolutio...@gmail.com on 15 Feb 2012 at 11:03

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Actually, scratch that string array Attribute idea.
It is interesting, but it disallows easy overriding of parameters at the 
different levels of Attribute Block hierarchy within a scene - which is the 
major attraction of the Attribute method in the first place.

Original comment by evolutio...@gmail.com on 16 Feb 2012 at 12:44