Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for dead-simple examples #193

Closed
dougepps opened this issue Jul 13, 2013 · 22 comments
Closed

Request for dead-simple examples #193

dougepps opened this issue Jul 13, 2013 · 22 comments

Comments

@dougepps
Copy link

I strongly believe we need some dead-simple, self-contained, no gl-hoopla sample-code.

I'm trying to use osd "just to do some evaluations" and am flailing-wildly and having to look through "a bunch" of files to figure out what's what.

Monday I'll attempt to do something proper and send it, but having someone to help would be great !

I'm thinking something where I've got some simple arrays of indices, vertex and texture data and then voila, I can do stuff.

As it stands now there's code in the common/ section, but it's not terribly clear. And all the context bind/unbind stuff is still a mystery to me. I think the intent is to let me have a buffer (that I own) of "P" (etc) data and then somehow copy in/out of them, but I havent' quite grocked it.

I think it's all there, I'm just wanting a really-dumb version to see what's what all in one spot.

(unless it already exists !)

thanks,

-doug

@blackencino
Copy link

I agree with this whole-heartedly.

It's cool that there are these great GPU accelerated tools for SubDivs, but
it still seems to me that CPU-only paths are the ones that will open the
most doors.

Chris

On Fri, Jul 12, 2013 at 10:58 PM, Doug Epps notifications@github.comwrote:

I strongly believe we need some dead-simple, self-contained, no gl-hoopla
sample-code.

I'm trying to use osd "just to do some evaluations" and am flailing-wildly
and having to look through "a bunch" of files to figure out what's what.

Monday I'll attempt to do something proper and send it, but having someone
to help would be great !

I'm thinking something where I've got some simple arrays of indices,
vertex and texture data and then voila, I can do stuff.

As it stands now there's code in the common/ section, but it's not
terribly clear. And all the context bind/unbind stuff is still a mystery to
me. I think the intent is to let me have a buffer (that I own) of "P" (etc)
data and then somehow copy in/out of them, but I havent' quite grocked it.

I think it's all there, I'm just wanting a really-dumb version to see
what's what all in one spot.

(unless it already exists !)

thanks,

-doug


Reply to this email directly or view it on GitHubhttps://github.com//issues/193
.

I think this situation absolutely requires that a really futile and stupid
gesture be done on somebody's part. And we're just the guys to do it.

@ghost ghost assigned manuelk Jul 15, 2013
@manuelk
Copy link

manuelk commented Jul 15, 2013

Doug: please take a look at the evalLimit example which keeps the GL code to a minimum and shows a simpler approach to Controllers, Contexts & VertexData binding.

I have also been adding a bunch of higher-level documentation which should come on-line in graphics.pixar.com soon-ish.

I agree that we need more code examples: our original examples have turned into tech-demos because that is what we use to debug / write the new features.

@blackencino
Copy link

Is there a way to use Open Subdiv with zero GL/GPU?

On Mon, Jul 15, 2013 at 11:25 AM, Manuel Kraemer
notifications@github.comwrote:

Doug: please take a look at the evalLimit example which keeps the GL code
to a minimum and shows a simpler approach to Controllers, Contexts &
VertexData binding.

I have also been adding a bunch of higher-level documentation which should
come on-line in graphics.pixar.com soon-ish.

I agree that we need more code examples: our original examples have turned
into tech-demos because that is what we use to debug / write the new
features.


Reply to this email directly or view it on GitHubhttps://github.com//issues/193#issuecomment-20991903
.

I think this situation absolutely requires that a really futile and stupid
gesture be done on somebody's part. And we're just the guys to do it.

@manuelk
Copy link

manuelk commented Jul 15, 2013

Certainly: look at the evalLimit example. In that example, GL is only used because displaying 3D points beats printf()... it's also slightly more commented than the rest.

@bdcline
Copy link

bdcline commented Jul 15, 2013

Eval Limit is a good reference for developing a CPU only evaluation. I've successfully (after a little investigation for some details) derived a CPU implementation with Eval Limit as a starting point. I'll see if I can post a sample soon - or if you have any specific questions I may be able to share from my experience.

@dougepps
Copy link
Author

I think I'll be able to clean up my hacking tomorrow and send a simple example.

(typos due to Illuminati conspiracy and/or because I'm sending this from an iPhone while driving and eating Cheetos)

On Jul 15, 2013, at 11:50 AM, bdcline notifications@github.com wrote:

Eval Limit is a good reference for developing a CPU only evaluation. I've successfully (after a little investigation for some details) derived a CPU implementation with Eval Limit as a starting point. I'll see if I can post a sample soon - or if you have any specific questions I may be able to share from my experience.


Reply to this email directly or view it on GitHub.

@dougepps
Copy link
Author

Got something compiling (isn), but don't have the right points yet, working on that.

In trying to debug I'm also trying to let you output the subdivided mesh but not sure how to get the point values.

std::vector<OpenSubdiv::OsdVertex> & subverts = farMesh->GetVertices();

 int firstvert = farMesh->GetSubdivisionTables()->GetFirstVertexOffset(level),
        numverts = farMesh->GetSubdivisionTables()->GetNumVertices(level);

float x = subverts[0].GetPos()[0]; /// GACK !  OpenSubdiv::OsdVertex doesn't have a GetPos !

Is it possible to do this if I'm using OpenSubdiv::OsdVertex (instead of an xyzVertex type of thing ?)

-doug

On Jul 15, 2013, at 11:50 AM, bdcline notifications@github.com wrote:

Eval Limit is a good reference for developing a CPU only evaluation. I've successfully (after a little investigation for some details) derived a CPU implementation with Eval Limit as a starting point. I'll see if I can post a sample soon - or if you have any specific questions I may be able to share from my experience.


Reply to this email directly or view it on GitHub.

@gelder
Copy link
Contributor

gelder commented Jul 16, 2013

Hi Doug,

I have a work-in-progress cpu only library for developing the projection part of the Eval API. It is not release quality code yet, but see tessellator.h and tessellator.cpp in:

https://github.com/gelder/OpenSubdiv/tree/dev/examples/tessellator

That has a GetPositions method that can be called after Refine that might help. This will get checked into the main repo when it's in better shape. Thanks for diving into OpenSubdiv!

@brechtvl
Copy link

Here's the ~250 lines of code in my renderer to quickly hack in OpenSubdiv with the limit evaluation API, just in case it's useful to someone:
https://gist.github.com/brechtvl/6007262

@manuelk
Copy link

manuelk commented Jul 16, 2013

Is it possible to do this if I'm using OpenSubdiv::OsdVertex (instead of an xyzVertex type of thing ?)

OsdVertex is deliberately a "no-op" implementation of the vertex class: Osd uses it with both Hbr & Far as a way of performing topological analysis without paying the cost of interpolating arbitrary data. The pattern that we use in Osd is to push all the vertex, varying and face-varying data into inter-operable buffers (like OsdCpuVertexBuffer).

Once the "factories" in Far have generated all the requisite topological tables, Osd (and Far to a limited extent) can then launch parallel computations on the vertex buffer data. The original Hbr mesh can be safely discarded, without having OsdVertex to ever have to carry the data for a single vertex position.

The larger question, without knowing much about what your goals are, would be which of the layers you need:

  • uniform subdivision, single-frame use: Hbr probably does everything you need with a fully implemented vertex class
  • limit evaluation or animation: Osd

Far is mostly functional, but it is usually a transitional stage to get to the hardware implementation in Osd.

My apologies if all this is maybe overly complicated: high-level documentation is on the way (will be going live on graphics.pixar.com soon, maybe even today)

@dougepps
Copy link
Author

Ok,

I'm trying to make the simplest possible, self-contained example imaginable.

Sounds like two different ones are in-order - superSimpleEval and superSimpleSubdivision, the later of which will use a full Vertex class (at least for the Far bits ?)

-doug

On Jul 16, 2013, at 11:12 AM, Manuel Kraemer notifications@github.com wrote:

Is it possible to do this if I'm using OpenSubdiv::OsdVertex (instead of an xyzVertex type of thing ?)

OsdVertex is deliberately a "no-op" implementation of the vertex class: Osd uses it with both Hbr & Far as a way of performing topological analysis without paying the cost of interpolating arbitrary data. The pattern that we use in Osd is to push all the vertex, varying and face-varying data into inter-operable buffers (like OsdCpuVertexBuffer).

Once the "factories" in Far have generated all the requisite topological tables, Osd (and Far to a limited extent) can then launch parallel computations on the vertex buffer data. The original Hbr mesh can be safely discarded, without having OsdVertex to ever have to carry the data for a single vertex position.

The larger question, without knowing much about what your goals are, would be which of the layers you need:

uniform subdivision, single-frame use: Hbr probably does everything you need with a fully implemented vertex class
limit evaluation or animation: Osd

Reply to this email directly or view it on GitHub.

@dougepps
Copy link
Author

Attached is a tar (superSimpleEval.tar.gz)

With a CMakeLists.txt and a main.cpp for 'superSimpleEval'.

Hopefully it accomplishes what I wanted it to.

If you guys can give it a once-over, that'd be great.

It doesn't do any fvar stuff, which it probably should as that can make your head-hurt the first-tme.

Thanks to everyone for pointers to the important-bits !

most gratifyingly, you can put this in the examples/CMakeLists.txt outside of any GL-stuff !

On Jul 16, 2013, at 11:32 AM, Doug Epps dougie@acm.org wrote:

Ok,

I'm trying to make the simplest possible, self-contained example imaginable.

Sounds like two different ones are in-order - superSimpleEval and superSimpleSubdivision, the later of which will use a full Vertex class (at least for the Far bits ?)

-doug

On Jul 16, 2013, at 11:12 AM, Manuel Kraemer notifications@github.com wrote:

Is it possible to do this if I'm using OpenSubdiv::OsdVertex (instead of an xyzVertex type of thing ?)

OsdVertex is deliberately a "no-op" implementation of the vertex class: Osd uses it with both Hbr & Far as a way of performing topological analysis without paying the cost of interpolating arbitrary data. The pattern that we use in Osd is to push all the vertex, varying and face-varying data into inter-operable buffers (like OsdCpuVertexBuffer).

Once the "factories" in Far have generated all the requisite topological tables, Osd (and Far to a limited extent) can then launch parallel computations on the vertex buffer data. The original Hbr mesh can be safely discarded, without having OsdVertex to ever have to carry the data for a single vertex position.

The larger question, without knowing much about what your goals are, would be which of the layers you need:

uniform subdivision, single-frame use: Hbr probably does everything you need with a fully implemented vertex class
limit evaluation or animation: Osd

Reply to this email directly or view it on GitHub.

@fivethousand
Copy link

I have working code for uniform subdivision using OSD, where I can get all vertex indices and their positions.
However, I still cannot figure out how to do that for adaptive subdivision.

I need to determine all relevant data for each type of patch. However, the indices I obtained seem to be wrong.
Current procedure is: Loop over the PatchArrayVector, Loop over each PatchArray. Then use GetVertIndex() to get the first vertex and increment it for all vertices of all patches in that array.

Am I missing something? Is there yet another remapping?
I guess this is something like 5-10 lines of code (given that I already set up the mesh, refined it etc).

I tried to find something like that in the examples, but couldn't figure it out.

@manuelk
Copy link

manuelk commented Sep 25, 2013

No remapping that i can think of - all the CV indices should be absolute in the vertex buffer.

I believe what you are describing is implemented here:
https://github.com/PixarAnimationStudios/OpenSubdiv/blob/master/opensubdiv/osd/cpuEvalLimitController.cpp

The patch kernel code is here:
https://github.com/PixarAnimationStudios/OpenSubdiv/blob/master/opensubdiv/osd/cpuEvalLimitKernel.cpp

@fivethousand
Copy link

Thanks for your fast help, that is in fact very close to what I am trying to achieve :-)

However, there is still one tiny bit missing: In that example, there is another offset (handle->vertexOffset) that I cannot get because my procedure is slightly different:

OsdFarPatchTables const * patchTables = g_farMesh->GetPatchTables();
OsdFarPatchTables::PatchArray const * patchArray = patchTables->GetPatchArray(OsdFarPatchTables::Descriptor(OpenSubdiv::FarPatchTables::REGULAR, 0, 0));
unsigned int const * vertexIds = &g_evalContext->GetControlVertices()[patchArray->GetVertIndex() /*+handle->vertexOffset*/]; // <---- HERE

I guess the answer is easy... could you help again? :-)

Edit: I removed the wrong output code at the bottom and found a small mistake. It seems to work now, but I am still wondering what this offset is....

@manuelk
Copy link

manuelk commented Sep 26, 2013

The FarPatchMap is a quadtree that maps the bi-cubic patches within the parametric space of a ptex face (aka a coarse face, except for non-quads). Given a random location in a face, this minimalistic quadtree speeds up the search for sub-patches, particularly when a high feature isolation threshold can see faces split into 100+ sub-patches.

Given a (u,v) within the coarse face parametric space, FindPatch returns an adjusted (u,v) pair within the local parametric space of the sub-patch, as well as the offset to the control vertices of said patch within the FarPatchArray held in the FarPatchTables.

That's what handle->vertexOffset is. The FarPatchMap constructor should give you all the details as to how these offsets are generated.

@fivethousand
Copy link

I see. Thanks for your detailed explanation.
Given that all shapes look fine and you explained the only thing that was still missing for me, I guess I have everything I need :-)

@manuelk
Copy link

manuelk commented Sep 26, 2013

You're welcome.

This Eval code was written somewhat in a hurry and i have a few other things that i want to build on top of it, so there is both room and plans for improvement... Let me know how things go.

@rjmercier1
Copy link

A nieve question, it appears FarMeshFactory::refine modifies an Hbr mesh in-place if you
use a proper Vertex template class. Extracting faces where GetDepth() == desired_level
seems to give an appropriately subdivided mesh. Is this ok for offline cases?

Bob

@manuelk
Copy link

manuelk commented Jan 10, 2014

refine() is a private member of the factory so should not be accessed directly.

Providing an implemented vertex class however does work with Far: once you have created the far mesh with the factory, you can use the FarDispatcher::Refine() to properly execute all the kernels.

Depending on your use-case though (say a renderer ?), unless you are taking advantage of the subdivision tables over multiple frames of animation, you are probably better off just subdividing the Hbr mesh directly.

@rjmercier1
Copy link

Yes, I saw that refine() is private; the FarMeshFactory constructor calls it on the Hbr
mesh that’s passed in, so has the side effect of refining the Hbr to whatever level is passed
to the constructor. I guess what I wanted know is should I /rely/ on this behavior?

Yes, it’s a renderer. I’ll take a look at FarDispatcher. Thanks!

Bob

On Jan 10, 2014, at 8:16 AM, Manuel Kraemer notifications@github.com wrote:

refine() is a private member of the factory so should not be accessed directly.

Providing an implemented vertex class however does work with Far: once you have created the far mesh with the factory, you can use the FarDispatcher::Refine() to properly execute all the kernels.

Depending on your use-case though (say a renderer ?), unless you are taking advantage of the subdivision tables over multiple frames of animation, you are probably better off just subdividing the Hbr mesh directly.


Reply to this email directly or view it on GitHub.

@manuelk
Copy link

manuelk commented Sep 24, 2014

OpenSubdiv 3.0 now has tutorials - this should address the needs for "dead simple examples"

Please feel free to open more threads if specific issues require attention again.

@manuelk manuelk closed this as completed Sep 24, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants