Add Chromium-only Blender WebEngine parity work

This commit is contained in:
mes123456
2026-08-12 04:47:48 -04:00
commit 9fd26010f6
18225 changed files with 11622124 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
#
# Copyright 2013 Pixar
#
# Licensed under the terms set forth in the LICENSE.txt file available at
# https://opensubdiv.org/license.
#
set(TUTORIALS
tutorial_0
tutorial_1
tutorial_2
)
foreach(tutorial ${TUTORIALS})
add_subdirectory("${tutorial}")
list(APPEND TUTORIAL_TARGETS "hbr_${tutorial}")
endforeach()
add_custom_target(hbr_tutorials DEPENDS ${TUTORIAL_TARGETS})
set_target_properties(hbr_tutorials
PROPERTIES
FOLDER "tutorials/hbr"
)

View File

@@ -0,0 +1,17 @@
#
# Copyright 2013 Pixar
#
# Licensed under the terms set forth in the LICENSE.txt file available at
# https://opensubdiv.org/license.
#
set(SOURCE_FILES
hbr_tutorial_0.cpp
)
osd_add_executable(hbr_tutorial_0 "tutorials/hbr"
${SOURCE_FILES}
)
install(TARGETS hbr_tutorial_0 DESTINATION "${CMAKE_BINDIR_BASE}/tutorials")

View File

@@ -0,0 +1,145 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
//------------------------------------------------------------------------------
// Tutorial description:
//
// This tutorial presents in a very succinct way the requisite steps to
// instantiate an Hbr mesh from simple topological data.
//
#include <opensubdiv/hbr/mesh.h>
#include <opensubdiv/hbr/catmark.h>
#include <cstdio>
//------------------------------------------------------------------------------
// Vertex container implementation.
//
// The HbrMesh<T> class is a templated interface that expects a vertex class to
// perform interpolation on arbitrary vertex data.
//
// For the template specialization of the HbrMesh interface to be met, our
// Vertex object to implement a minimal set of constructors and member
// functions.
//
// Since we are not going to subdivide the mesh, the struct presented here has
// been left minimalistic. The only customization added to our container was to
// provide storage and accessors for the position of a 3D vertex.
//
struct Vertex {
// Hbr minimal required interface ----------------------
Vertex() { }
Vertex(int /*i*/) { }
Vertex(Vertex const & src) {
_position[0] = src._position[0];
_position[1] = src._position[1];
_position[2] = src._position[2];
}
void Clear( void * =0 ) { }
void AddWithWeight(Vertex const &, float ) { }
void AddVaryingWithWeight(Vertex const &, float) { }
// Public interface ------------------------------------
void SetPosition(float x, float y, float z) {
_position[0]=x;
_position[1]=y;
_position[2]=z;
}
const float * GetPosition() const {
return _position;
}
private:
float _position[3];
};
typedef OpenSubdiv::HbrMesh<Vertex> Hmesh;
typedef OpenSubdiv::HbrFace<Vertex> Hface;
typedef OpenSubdiv::HbrVertex<Vertex> Hvertex;
typedef OpenSubdiv::HbrHalfedge<Vertex> Hhalfedge;
//------------------------------------------------------------------------------
// Pyramid geometry from catmark_pyramid.h
static float verts[5][3] = {{ 0.0f, 0.0f, 2.0f},
{ 0.0f, -2.0f, 0.0f},
{ 2.0f, 0.0f, 0.0f},
{ 0.0f, 2.0f, 0.0f},
{-2.0f, 0.0f, 0.0f}};
static int nverts = 5,
nfaces = 5;
static int facenverts[5] = { 3, 3, 3, 3, 4 };
static int faceverts[16] = { 0, 1, 2,
0, 2, 3,
0, 3, 4,
0, 4, 1,
4, 3, 2, 1 };
//------------------------------------------------------------------------------
int main(int, char **) {
// Create a subdivision scheme (Catmull-Clark here)
OpenSubdiv::HbrCatmarkSubdivision<Vertex> * catmark =
new OpenSubdiv::HbrCatmarkSubdivision<Vertex>();
// Create an empty Hbr mesh
Hmesh * hmesh = new Hmesh(catmark);
// Populate the vertices
Vertex v;
for (int i=0; i<nverts; ++i) {
// Primitive variable data must be set here: in our case we set
// the 3D position of the vertex.
v.SetPosition(verts[i][0], verts[i][1], verts[i][2]);
// Add the vertex to the mesh.
hmesh->NewVertex(i, v);
}
// Create the topology
int * fv = faceverts;
for (int i=0; i<nfaces; ++i) {
int nv = facenverts[i];
hmesh->NewFace(nv, fv, 0);
fv+=nv;
}
// Set subdivision options
//
// By default vertex interpolation is set to "none" on boundaries, which
// can produce un-expected results, so we change it to "edge-only".
//
hmesh->SetInterpolateBoundaryMethod(Hmesh::k_InterpolateBoundaryEdgeOnly);
// Call 'Finish' to finalize the data structures before using the mesh.
hmesh->Finish();
printf("Created a pyramid with %d faces and %d vertices.\n",
hmesh->GetNumFaces(), hmesh->GetNumVertices());
delete hmesh;
delete catmark;
}
//------------------------------------------------------------------------------

View File

@@ -0,0 +1,17 @@
#
# Copyright 2013 Pixar
#
# Licensed under the terms set forth in the LICENSE.txt file available at
# https://opensubdiv.org/license.
#
set(SOURCE_FILES
hbr_tutorial_1.cpp
)
osd_add_executable(hbr_tutorial_1 "tutorials/hbr"
${SOURCE_FILES}
)
install(TARGETS hbr_tutorial_1 DESTINATION "${CMAKE_BINDIR_BASE}/tutorials")

View File

@@ -0,0 +1,180 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
//------------------------------------------------------------------------------
// Tutorial description:
//
// This tutorial shows how to safely create Hbr meshes from arbitrary topology.
// Because Hbr is a half-edge data structure, it cannot represent non-manifold
// topology. Ensuring that the geometry used is manifold is a requirement to use
// Hbr safely. This tutorial presents some simple tests to detect inappropriate
// topology.
//
#include <opensubdiv/hbr/mesh.h>
#include <opensubdiv/hbr/catmark.h>
#include <cstdio>
//------------------------------------------------------------------------------
struct Vertex {
// Hbr minimal required interface ----------------------
Vertex() { }
Vertex(int /*i*/) { }
Vertex(Vertex const & src) {
_position[0] = src._position[0];
_position[1] = src._position[1];
_position[2] = src._position[2];
}
void Clear( void * =0 ) { }
void AddWithWeight(Vertex const &, float ) { }
void AddVaryingWithWeight(Vertex const &, float) { }
// Public interface ------------------------------------
void SetPosition(float x, float y, float z) {
_position[0]=x;
_position[1]=y;
_position[2]=z;
}
const float * GetPosition() const {
return _position;
}
private:
float _position[3];
};
typedef OpenSubdiv::HbrMesh<Vertex> Hmesh;
typedef OpenSubdiv::HbrFace<Vertex> Hface;
typedef OpenSubdiv::HbrVertex<Vertex> Hvertex;
typedef OpenSubdiv::HbrHalfedge<Vertex> Hhalfedge;
//------------------------------------------------------------------------------
// Non-manifold geometry from catmark_fan.h
//
// o
// /|
// / |
// / |
// / |
// o |
// | f2 |
// | |
// o--------+----o------------o
// / | / /
// / | / /
// / f0 | / f1 /
// / |/ /
// o------------ o------------o
//
// The shared edge of a fan is adjacent to 3 faces, and therefore non-manifold.
//
static float verts[8][3] = {{-1.0, 0.0, -1.0},
{-1.0, 0.0, 0.0},
{ 0.0, 0.0, 0.0},
{ 0.0, 0.0, -1.0},
{ 1.0, 0.0, 0.0},
{ 1.0, 0.0, -1.0},
{ 0.0, 1.0, 0.0},
{ 0.0, 1.0, -1.0}};
static int nverts = 8,
nfaces = 3;
static int facenverts[3] = { 4, 4, 4 };
static int faceverts[12] = { 0, 1, 2, 3,
3, 2, 4, 5,
3, 2, 6, 7 };
//------------------------------------------------------------------------------
int main(int, char **) {
OpenSubdiv::HbrCatmarkSubdivision<Vertex> * catmark =
new OpenSubdiv::HbrCatmarkSubdivision<Vertex>();
Hmesh * hmesh = new Hmesh(catmark);
Vertex v;
for (int i=0; i<nverts; ++i) {
v.SetPosition(verts[i][0], verts[i][1], verts[i][2]);
hmesh->NewVertex(i, v);
}
// Create the topology
int * fv = faceverts;
for (int i=0; i<nfaces; ++i) {
int nv = facenverts[i];
bool valid = true;
for(int j=0;j<nv;j++) {
Hvertex const * origin = hmesh->GetVertex(fv[j]),
* destination = hmesh->GetVertex(fv[(j+1)%nv]);
Hhalfedge const * opposite = destination->GetEdge(origin);
// Make sure that the vertices exist in the mesh
if (origin==NULL || destination==NULL) {
printf(" An edge was specified that connected a nonexistent vertex\n");
valid=false;
break;
}
// Check for a degenerate edge
if (origin == destination) {
printf(" An edge was specified that connected a vertex to itself\n");
valid=false;
break;
}
// Check that no more than 2 faces are adjacent to the edge
if (opposite && opposite->GetOpposite() ) {
printf(" A non-manifold edge incident to more than 2 faces was found\n");
valid=false;
break;
}
// Check that the edge is unique and oriented properly
if (origin->GetEdge(destination)) {
printf(" An edge connecting two vertices was specified more than once."
" It's likely that an incident face was flipped\n");
valid=false;
break;
}
}
if (valid) {
hmesh->NewFace(nv, fv, 0);
} else {
printf(" Skipped face %d\n", i);
}
fv+=nv;
}
hmesh->SetInterpolateBoundaryMethod(Hmesh::k_InterpolateBoundaryEdgeOnly);
hmesh->Finish();
printf("Created a fan with %d faces and %d vertices.\n",
hmesh->GetNumFaces(), hmesh->GetNumVertices());
delete hmesh;
delete catmark;
}
//------------------------------------------------------------------------------

View File

@@ -0,0 +1,17 @@
#
# Copyright 2013 Pixar
#
# Licensed under the terms set forth in the LICENSE.txt file available at
# https://opensubdiv.org/license.
#
set(SOURCE_FILES
hbr_tutorial_2.cpp
)
osd_add_executable(hbr_tutorial_2 "tutorials/hbr"
${SOURCE_FILES}
)
install(TARGETS hbr_tutorial_2 DESTINATION "${CMAKE_BINDIR_BASE}/tutorials")

View File

@@ -0,0 +1,247 @@
//
// Copyright 2013 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://opensubdiv.org/license.
//
//------------------------------------------------------------------------------
// Tutorial description:
//
// This tutorial shows how to subdivide uniformly a simple Hbr mesh. We are
// building upon previous tutorials and assuming a fully instantiated mesh:
// we start with an HbrMesh pointer initialized from the same pyramid shape
// used in hbr_tutorial_0.
//
// We then apply the Refine() function sequentially to all the faces in the
// mesh to generate several levels of uniform subdivision. The resulting data
// is then dumped to the terminal in Wavefront OBJ format for inspection.
//
#include <opensubdiv/hbr/mesh.h>
#include <opensubdiv/hbr/catmark.h>
#include <cassert>
#include <cstdio>
//------------------------------------------------------------------------------
//
// For this tutorial, we have to flesh out the Vertex class further. Note that now
// the copy constructor, Clear() and AddwithWeight() methods have been
// implemented to interpolate our float3 position data.
//
// This vertex specialization pattern leaves client-code free to implement
// arbitrary vertex primvar data schemes (or none at all to conserve efficiency)
//
struct Vertex {
// Hbr minimal required interface ----------------------
Vertex() { }
Vertex(int /*i*/) { }
Vertex(Vertex const & src) {
_position[0] = src._position[0];
_position[1] = src._position[1];
_position[2] = src._position[2];
}
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;
}
const float * GetPosition() const {
return _position;
}
private:
float _position[3];
};
typedef OpenSubdiv::HbrMesh<Vertex> Hmesh;
typedef OpenSubdiv::HbrFace<Vertex> Hface;
typedef OpenSubdiv::HbrVertex<Vertex> Hvertex;
typedef OpenSubdiv::HbrHalfedge<Vertex> Hhalfedge;
Hmesh * createMesh();
//------------------------------------------------------------------------------
int main(int, char **) {
Hmesh * hmesh = createMesh();
int maxlevel=2, // 2 levels of subdivision
firstface=0, // marker to the first face index of level 2
firstvertex=0; // marker to the first vertex index of level 2
// Refine the mesh to 'maxlevel'
for (int level=0; level<maxlevel; ++level) {
// Total number of faces in the mesh, across all levels
//
// Note: this function iterates over the list of faces and can be slow
int nfaces = hmesh->GetNumFaces();
if (level==(maxlevel-1)) {
// Save our vertex marker
firstvertex = hmesh->GetNumVertices();
}
// Iterate over the faces of the current level of subdivision
for (int face=firstface; face<nfaces; ++face) {
Hface * f = hmesh->GetFace(face);
// Note: hole tags would have to be dealt with here.
f->Refine();
}
// Save our face index marker for the next level
firstface = nfaces;
}
{ // Output OBJ of the highest level refined -----------
// Print vertex positions
int nverts = hmesh->GetNumVertices();
for (int vert=firstvertex; vert<nverts; ++vert) {
float const * pos = hmesh->GetVertex(vert)->GetData().GetPosition();
printf("v %f %f %f\n", pos[0], pos[1], pos[2]);
}
// Print faces
for (int face=firstface; face<hmesh->GetNumFaces(); ++face) {
Hface * f = hmesh->GetFace(face);
assert(f->GetNumVertices()==4 );
printf("f ");
for (int vert=0; vert<4; ++vert) {
// OBJ uses 1-based arrays
printf("%d ", f->GetVertex(vert)->GetID() - firstvertex + 1);
}
printf("\n");
}
}
}
//------------------------------------------------------------------------------
// Creates an Hbr mesh
//
// see hbr_tutorial_0 and hbr_tutorial_1 for more details
//
Hmesh *
createMesh() {
// Pyramid geometry from catmark_pyramid.h
static float verts[5][3] = {{ 0.0f, 0.0f, 2.0f},
{ 0.0f, -2.0f, 0.0f},
{ 2.0f, 0.0f, 0.0f},
{ 0.0f, 2.0f, 0.0f},
{-2.0f, 0.0f, 0.0f}};
static int nverts = 5,
nfaces = 5;
static int facenverts[5] = { 3, 3, 3, 3, 4 };
static int faceverts[16] = { 0, 1, 2,
0, 2, 3,
0, 3, 4,
0, 4, 1,
4, 3, 2, 1 };
OpenSubdiv::HbrCatmarkSubdivision<Vertex> * catmark =
new OpenSubdiv::HbrCatmarkSubdivision<Vertex>();
Hmesh * hmesh = new Hmesh(catmark);
// Populate the vertices
Vertex v;
for (int i=0; i<nverts; ++i) {
v.SetPosition(verts[i][0], verts[i][1], verts[i][2]);
hmesh->NewVertex(i, v);
}
// Create the topology
int * fv = faceverts;
for (int i=0; i<nfaces; ++i) {
int nv = facenverts[i];
bool valid = true;
for(int j=0;j<nv;j++) {
Hvertex const * origin = hmesh->GetVertex(fv[j]),
* destination = hmesh->GetVertex(fv[(j+1)%nv]);
Hhalfedge const * opposite = destination->GetEdge(origin);
// Make sure that the vertices exist in the mesh
if (origin==NULL || destination==NULL) {
printf(" An edge was specified that connected a nonexistent vertex\n");
valid=false;
break;
}
// Check for a degenerate edge
if (origin == destination) {
printf(" An edge was specified that connected a vertex to itself\n");
valid=false;
break;
}
// Check that no more than 2 faces are adjacent to the edge
if (opposite && opposite->GetOpposite() ) {
printf(" A non-manifold edge incident to more than 2 faces was found\n");
valid=false;
break;
}
// Check that the edge is unique and oriented properly
if (origin->GetEdge(destination)) {
printf(" An edge connecting two vertices was specified more than once."
" It's likely that an incident face was flipped\n");
valid=false;
break;
}
}
if (valid) {
hmesh->NewFace(nv, fv, 0);
} else {
printf(" Skipped face %d\n", i);
}
fv+=nv;
}
hmesh->SetInterpolateBoundaryMethod(Hmesh::k_InterpolateBoundaryEdgeOnly);
hmesh->Finish();
return hmesh;
}
//------------------------------------------------------------------------------