mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2025-01-17 19:50:06 +00:00
Add cascading stencils Far tutorial
This commit is contained in:
parent
58c8accbe9
commit
c10e18a035
@ -356,6 +356,9 @@ vertex data to a higher level of refinement.
|
||||
.. image:: images/far_stencil8.png
|
||||
:align: center
|
||||
|
||||
See implementation details, see the Far cascading stencil `tutorial
|
||||
<tutorials.html>`_
|
||||
|
||||
Limit Stencils
|
||||
**************
|
||||
|
||||
|
@ -80,7 +80,7 @@ or in your local ``<repository root>/turorials``.
|
||||
data.
|
||||
| |far_tut_1|
|
||||
|
|
||||
- | **Tutorial 3**
|
||||
| **Tutorial 3**
|
||||
| Building on tutorial 0, this example shows how to instantiate a simple mesh,
|
||||
refine it uniformly and then interpolate both 'vertex' and 'face-varying'
|
||||
primvar data.
|
||||
@ -88,7 +88,7 @@ or in your local ``<repository root>/turorials``.
|
||||
'face-varying' data recorded in the uv texture layout.
|
||||
| |far_tut_3|
|
||||
|
|
||||
| **Tutorial 4**
|
||||
- | **Tutorial 4**
|
||||
| This tutorial shows how to create and manipulate FarStencilTables. We use the
|
||||
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.
|
||||
| |far_tut_6|
|
||||
|
|
||||
| **Tutorial 7**
|
||||
| This tutorial shows how to create and manipulate tables of cascading
|
||||
stencils to apply hierarchical vertex edits.
|
||||
|
|
||||
|
||||
----
|
||||
|
||||
|
@ -30,6 +30,7 @@ set(TUTORIALS
|
||||
tutorial_4
|
||||
tutorial_5
|
||||
tutorial_6
|
||||
tutorial_7
|
||||
)
|
||||
|
||||
foreach(tutorial ${TUTORIALS})
|
||||
|
39
tutorials/far/tutorial_7/CMakeLists.txt
Normal file
39
tutorials/far/tutorial_7/CMakeLists.txt
Normal 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")
|
||||
|
237
tutorials/far/tutorial_7/far_tutorial_7.cpp
Normal file
237
tutorials/far/tutorial_7/far_tutorial_7.cpp
Normal 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);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
Loading…
Reference in New Issue
Block a user