Add Chromium-only Blender WebEngine parity work
This commit is contained in:
27
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/CMakeLists.txt
vendored
Normal file
27
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/CMakeLists.txt
vendored
Normal 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"
|
||||
)
|
||||
17
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_0/CMakeLists.txt
vendored
Normal file
17
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_0/CMakeLists.txt
vendored
Normal 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")
|
||||
|
||||
145
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_0/hbr_tutorial_0.cpp
vendored
Normal file
145
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_0/hbr_tutorial_0.cpp
vendored
Normal 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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
17
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_1/CMakeLists.txt
vendored
Normal file
17
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_1/CMakeLists.txt
vendored
Normal 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")
|
||||
|
||||
180
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_1/hbr_tutorial_1.cpp
vendored
Normal file
180
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_1/hbr_tutorial_1.cpp
vendored
Normal 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;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
17
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_2/CMakeLists.txt
vendored
Normal file
17
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_2/CMakeLists.txt
vendored
Normal 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")
|
||||
|
||||
247
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_2/hbr_tutorial_2.cpp
vendored
Normal file
247
blender-5.2.0/extern/opensubdiv-source/tutorials/hbr/tutorial_2/hbr_tutorial_2.cpp
vendored
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user