mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2025-01-18 04:00: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
|
.. image:: images/far_stencil8.png
|
||||||
:align: center
|
:align: center
|
||||||
|
|
||||||
|
See implementation details, see the Far cascading stencil `tutorial
|
||||||
|
<tutorials.html>`_
|
||||||
|
|
||||||
Limit Stencils
|
Limit Stencils
|
||||||
**************
|
**************
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -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})
|
||||||
|
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