Add cascading stencils Far tutorial

This commit is contained in:
manuelk 2014-11-18 16:52:32 -08:00
parent 58c8accbe9
commit c10e18a035
5 changed files with 286 additions and 2 deletions

View File

@ -356,6 +356,9 @@ vertex data to a higher level of refinement.
.. image:: images/far_stencil8.png .. image:: images/far_stencil8.png
:align: center :align: center
See implementation details, see the Far cascading stencil `tutorial
<tutorials.html>`_
Limit Stencils Limit Stencils
************** **************

View File

@ -80,7 +80,7 @@ or in your local ``<repository root>/turorials``.
data. data.
| |far_tut_1| | |far_tut_1|
| |
- | **Tutorial 3** | **Tutorial 3**
| Building on tutorial 0, this example shows how to instantiate a simple mesh, | Building on tutorial 0, this example shows how to instantiate a simple mesh,
refine it uniformly and then interpolate both 'vertex' and 'face-varying' refine it uniformly and then interpolate both 'vertex' and 'face-varying'
primvar data. primvar data.
@ -88,7 +88,7 @@ or in your local ``<repository root>/turorials``.
'face-varying' data recorded in the uv texture layout. 'face-varying' data recorded in the uv texture layout.
| |far_tut_3| | |far_tut_3|
| |
| **Tutorial 4** - | **Tutorial 4**
| This tutorial shows how to create and manipulate FarStencilTables. We use the | This tutorial shows how to create and manipulate FarStencilTables. We use the
factorized stencils to interpolate vertex primvar data buffers. factorized stencils to interpolate vertex primvar data buffers.
| |
@ -102,6 +102,10 @@ or in your local ``<repository root>/turorials``.
parametric locations using feature adaptive Far::PatchTables. parametric locations using feature adaptive Far::PatchTables.
| |far_tut_6| | |far_tut_6|
| |
| **Tutorial 7**
| This tutorial shows how to create and manipulate tables of cascading
stencils to apply hierarchical vertex edits.
|
---- ----

View File

@ -30,6 +30,7 @@ set(TUTORIALS
tutorial_4 tutorial_4
tutorial_5 tutorial_5
tutorial_6 tutorial_6
tutorial_7
) )
foreach(tutorial ${TUTORIALS}) foreach(tutorial ${TUTORIALS})

View File

@ -0,0 +1,39 @@
#
# Copyright 2013 Pixar
#
# Licensed under the Apache License, Version 2.0 (the "Apache License")
# with the following modification; you may not use this file except in
# compliance with the Apache License and the following modification to it:
# Section 6. Trademarks. is deleted and replaced with:
#
# 6. Trademarks. This License does not grant permission to use the trade
# names, trademarks, service marks, or product names of the Licensor
# and its affiliates, except as required to comply with Section 4(c) of
# the License and to reproduce the content of the NOTICE file.
#
# You may obtain a copy of the Apache License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the Apache License with the above modification is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the Apache License for the specific
# language governing permissions and limitations under the Apache License.
#
include_directories("${PROJECT_SOURCE_DIR}/opensubdiv")
set(SOURCE_FILES
far_tutorial_7.cpp
)
_add_executable(far_tutorial_7
${SOURCE_FILES}
$<TARGET_OBJECTS:sdc_obj>
$<TARGET_OBJECTS:vtr_obj>
$<TARGET_OBJECTS:far_obj>
)
install(TARGETS far_tutorial_7 DESTINATION "${CMAKE_BINDIR_BASE}/tutorials")

View File

@ -0,0 +1,237 @@
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
//
//------------------------------------------------------------------------------
// Tutorial description:
//
// This tutorial shows how to create and manipulate tables of cascading stencils.
//
// We initalize a Far::TopologyRefiner initalized with a cube and apply uniform
// refinement. We then use a Far::StencilTablesFactory to generate stencil
// tables. We set the factory Options to not factorize intermediate levels,
// thus giving tables of "cascading" stencils.
//
// We then apply the stencils to the vertex position primvar data, and insert
// a hierarchical edit at level 1. This edit is smoothed by the application
// of the subsequent stencil cascades.
//
// The results are dumped into an OBJ file that shows the intermediate levels
// of refinement of the original cube.
//
#include <far/topologyRefinerFactory.h>
#include <far/stencilTables.h>
#include <far/stencilTablesFactory.h>
#include <cstdio>
#include <cstring>
//------------------------------------------------------------------------------
// Vertex container implementation.
//
struct Vertex {
// Minimal required interface ----------------------
Vertex() { }
Vertex(Vertex const & src) {
_position[0] = src._position[0];
_position[1] = src._position[1];
_position[1] = src._position[1];
}
void Clear( void * =0 ) {
_position[0]=_position[1]=_position[2]=0.0f;
}
void AddWithWeight(Vertex const & src, float weight) {
_position[0]+=weight*src._position[0];
_position[1]+=weight*src._position[1];
_position[2]+=weight*src._position[2];
}
void AddVaryingWithWeight(Vertex const &, float) { }
// Public interface ------------------------------------
void SetPosition(float x, float y, float z) {
_position[0]=x;
_position[1]=y;
_position[2]=z;
}
float const * GetPosition() const {
return _position;
}
float * GetPosition() {
return _position;
}
private:
float _position[3];
};
//------------------------------------------------------------------------------
// Cube geometry from catmark_cube.h
static float g_verts[24] = {-0.5f, -0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, 0.5f,
-0.5f, 0.5f, -0.5f,
0.5f, 0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
0.5f, -0.5f, -0.5f };
static int g_nverts = 8,
g_nfaces = 6;
static int g_vertsperface[6] = { 4, 4, 4, 4, 4, 4 };
static int g_vertIndices[24] = { 0, 1, 3, 2,
2, 3, 5, 4,
4, 5, 7, 6,
6, 7, 1, 0,
1, 7, 5, 3,
6, 0, 2, 4 };
using namespace OpenSubdiv;
static Far::TopologyRefiner * createTopologyRefiner();
//------------------------------------------------------------------------------
int main(int, char **) {
// Generate some FarTopologyRefiner (see far_tutorial_0 for details).
Far::TopologyRefiner * refiner = createTopologyRefiner();
// Uniformly refine the topolgy up to 'maxlevel'.
int maxlevel = 4;
refiner->RefineUniform( maxlevel );
// Use the FarStencilTables factory to create cascading stencil tables
// note: we want stencils for the each refinement level
// "cascade" mode is achieved by setting "factorizeIntermediateLevels"
// to false
Far::StencilTablesFactory::Options options;
options.generateIntermediateLevels=true;
options.factorizeIntermediateLevels=false;
options.generateOffsets=true;
Far::StencilTables const * stencilTables =
Far::StencilTablesFactory::Create(*refiner, options);
std::vector<Vertex> vertexBuffer(refiner->GetNumVerticesTotal()-g_nverts);
Vertex * destVerts = &vertexBuffer[0];
int start = 0, end = 0; // stencils batches for each level of subdivision
for (int level=0; level<maxlevel; ++level) {
int nverts = refiner->GetNumVertices(level+1);
Vertex const * srcVerts = reinterpret_cast<Vertex *>(g_verts);
if (level>0) {
srcVerts = &vertexBuffer[start];
}
start = end;
end += nverts;
stencilTables->UpdateValues(srcVerts, destVerts, start, end);
// apply 2 hierarchical edits on level 1 vertices
if (level==1) {
float * pos = destVerts[start+5].GetPosition();
pos[1] += 0.5f;
pos = destVerts[start+20].GetPosition();
pos[0] += 0.25f;
}
}
{ // Output OBJ of the highest level refined -----------
Vertex * verts = &vertexBuffer[0];
// Print vertex positions
for (int level=1, firstvert=0; level<=maxlevel; ++level) {
printf("g level_%d\n", level);
int nverts = refiner->GetNumVertices(level);
for (int vert=0; vert<nverts; ++vert) {
float const * pos = verts[vert].GetPosition();
printf("v %f %f %f\n", pos[0], pos[1], pos[2]);
}
verts += nverts;
// Print faces
for (int face=0; face<refiner->GetNumFaces(level); ++face) {
Far::IndexArray fverts = refiner->GetFaceVertices(level, face);
// all refined Catmark faces should be quads
assert(fverts.size()==4);
printf("f ");
for (int vert=0; vert<fverts.size(); ++vert) {
printf("%d ", fverts[vert]+firstvert+1); // OBJ uses 1-based arrays...
}
printf("\n");
}
firstvert+=nverts;
}
}
delete refiner;
delete stencilTables;
}
//------------------------------------------------------------------------------
static Far::TopologyRefiner *
createTopologyRefiner() {
// Populate a topology descriptor with our raw data.
typedef Far::TopologyRefinerFactoryBase::TopologyDescriptor Descriptor;
Sdc::Type type = OpenSubdiv::Sdc::TYPE_CATMARK;
Sdc::Options options;
options.SetVVarBoundaryInterpolation(Sdc::Options::VVAR_BOUNDARY_EDGE_ONLY);
Descriptor desc;
desc.numVertices = g_nverts;
desc.numFaces = g_nfaces;
desc.vertsPerFace = g_vertsperface;
desc.vertIndices = g_vertIndices;
// Instantiate a FarTopologyRefiner from the descriptor.
return Far::TopologyRefinerFactory<Descriptor>::Create(type, options, desc);
}
//------------------------------------------------------------------------------