mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-28 22:31:07 +00:00
Fix crashes induced by typeid
- implement virtual accessors in FarSubdivision tables that return a Scheme enum - implement a safe typeid comparison in FarMeshFactory to get the same information from Hbr subdivision classes fixes #240
This commit is contained in:
parent
fdfdb1cc8b
commit
ab0cd0f8a2
@ -46,10 +46,15 @@ template <class U> class FarBilinearSubdivisionTables : public FarSubdivisionTab
|
||||
|
||||
public:
|
||||
|
||||
/// Returns the number of indexing tables needed to represent this particular
|
||||
/// subdivision scheme.
|
||||
/// \brief Returns the number of indexing tables needed to represent this
|
||||
/// particular subdivision scheme.
|
||||
virtual int GetNumTables() const { return 7; }
|
||||
|
||||
/// \brief Returns the subdivision scheme of the tables
|
||||
virtual typename FarSubdivisionTables<U>::Scheme GetScheme() const {
|
||||
return FarSubdivisionTables<U>::BILINEAR;
|
||||
}
|
||||
|
||||
private:
|
||||
template <class X, class Y> friend class FarBilinearSubdivisionTablesFactory;
|
||||
template <class X, class Y> friend class FarMultiMeshFactory;
|
||||
|
@ -46,10 +46,15 @@ template <class U> class FarCatmarkSubdivisionTables : public FarSubdivisionTabl
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Returns the number of indexing tables needed to represent this
|
||||
/// \brief Returns the number of indexing tables needed to represent this
|
||||
/// particular subdivision scheme.
|
||||
virtual int GetNumTables() const { return 7; }
|
||||
|
||||
/// \brief Returns the subdivision scheme of the tables
|
||||
virtual typename FarSubdivisionTables<U>::Scheme GetScheme() const {
|
||||
return FarSubdivisionTables<U>::CATMARK;
|
||||
}
|
||||
|
||||
private:
|
||||
template <class X, class Y> friend class FarCatmarkSubdivisionTablesFactory;
|
||||
template <class X, class Y> friend class FarMultiMeshFactory;
|
||||
|
@ -47,6 +47,11 @@ template <class U> class FarLoopSubdivisionTables : public FarSubdivisionTables<
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Returns the subdivision scheme of the tables
|
||||
virtual typename FarSubdivisionTables<U>::Scheme GetScheme() const {
|
||||
return FarSubdivisionTables<U>::LOOP;
|
||||
}
|
||||
|
||||
private:
|
||||
template <class X, class Y> friend class FarLoopSubdivisionTablesFactory;
|
||||
template <class X, class Y> friend class FarMultiMeshFactory;
|
||||
|
@ -171,6 +171,9 @@ private:
|
||||
FarMeshFactory( FarMeshFactory const & );
|
||||
FarMeshFactory<T,U> & operator=(FarMeshFactory<T,U> const &);
|
||||
|
||||
// True if t1 and t2 are the same, even accounting for plugins
|
||||
static bool compareType(std::type_info const & t1, std::type_info const & t2);
|
||||
|
||||
// True if the HbrMesh applies the bilinear subdivision scheme
|
||||
static bool isBilinear(HbrMesh<T> const * mesh);
|
||||
|
||||
@ -637,19 +640,37 @@ FarMeshFactory<T,U>::FarMeshFactory( HbrMesh<T> * mesh, int maxlevel, bool adapt
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class U> bool
|
||||
FarMeshFactory<T,U>::compareType(std::type_info const & t1, std::type_info const & t2) {
|
||||
|
||||
if (t1==t2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// On some systems, distinct instances of \c type_info objects compare equal if
|
||||
// their name() functions return equivalent strings. On other systems, distinct
|
||||
// type_info objects never compare equal. The latter can cause problems in the
|
||||
// presence of plugins loaded without RTLD_GLOBAL, because typeid(T) returns
|
||||
// different \c type_info objects for the same T in the two plugins.
|
||||
for (char const * p1 = t1.name(), *p2 = t2.name(); *p1 == *p2; ++p1, ++p2)
|
||||
if (*p1 == '\0')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T, class U> bool
|
||||
FarMeshFactory<T,U>::isBilinear(HbrMesh<T> const * mesh) {
|
||||
return typeid(*(mesh->GetSubdivision()))==typeid(HbrBilinearSubdivision<T>);
|
||||
return compareType(typeid(*(mesh->GetSubdivision())), typeid(HbrBilinearSubdivision<T>));
|
||||
}
|
||||
|
||||
template <class T, class U> bool
|
||||
FarMeshFactory<T,U>::isCatmark(HbrMesh<T> const * mesh) {
|
||||
return typeid(*(mesh->GetSubdivision()))==typeid(HbrCatmarkSubdivision<T>);
|
||||
return compareType(typeid(*(mesh->GetSubdivision())), typeid(HbrCatmarkSubdivision<T>));
|
||||
}
|
||||
|
||||
template <class T, class U> bool
|
||||
FarMeshFactory<T,U>::isLoop(HbrMesh<T> const * mesh) {
|
||||
return typeid(*(mesh->GetSubdivision()))==typeid(HbrLoopSubdivision<T>);
|
||||
return compareType(typeid(*(mesh->GetSubdivision())), typeid(HbrLoopSubdivision<T>));
|
||||
}
|
||||
|
||||
template <class T, class U> void
|
||||
|
@ -34,8 +34,6 @@
|
||||
#include "../far/patchTablesFactory.h"
|
||||
#include "../far/vertexEditTablesFactory.h"
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
namespace OpenSubdiv {
|
||||
namespace OPENSUBDIV_VERSION {
|
||||
|
||||
@ -101,7 +99,10 @@ FarMultiMeshFactory<T, U>::Create(std::vector<FarMesh<U> const *> const &meshes)
|
||||
if (meshes.empty()) return NULL;
|
||||
|
||||
int totalFVarWidth = meshes[0]->GetTotalFVarWidth();
|
||||
const std::type_info &scheme = typeid(*(meshes[0]->GetSubdivisionTables()));
|
||||
|
||||
typename FarSubdivisionTables<U>::Scheme scheme =
|
||||
meshes[0]->GetSubdivisionTables()->GetScheme();
|
||||
|
||||
_maxlevel = 0;
|
||||
_maxvalence = 0;
|
||||
_isLoop = false;
|
||||
@ -110,7 +111,7 @@ FarMultiMeshFactory<T, U>::Create(std::vector<FarMesh<U> const *> const &meshes)
|
||||
FarMesh<U> const *mesh = meshes[i];
|
||||
|
||||
// meshes have to have a same subdivision scheme
|
||||
if (scheme != typeid(*(mesh->GetSubdivisionTables()))) {
|
||||
if (scheme != mesh->GetSubdivisionTables()->GetScheme()) {
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
@ -241,19 +242,26 @@ FarMultiMeshFactory<T, U>::spliceSubdivisionTables(FarMesh<U> *farMesh, FarMeshV
|
||||
}
|
||||
|
||||
FarSubdivisionTables<U> *result = NULL;
|
||||
const std::type_info &scheme = typeid(*(meshes[0]->GetSubdivisionTables()));
|
||||
typename FarSubdivisionTables<U>::Scheme scheme =
|
||||
meshes[0]->GetSubdivisionTables()->GetScheme();
|
||||
|
||||
if (scheme == typeid(FarCatmarkSubdivisionTables<U>) ) {
|
||||
result = new FarCatmarkSubdivisionTables<U>(farMesh, _maxlevel);
|
||||
_isLoop = false;
|
||||
} else if (scheme == typeid(FarBilinearSubdivisionTables<U>) ) {
|
||||
result = new FarBilinearSubdivisionTables<U>(farMesh, _maxlevel);
|
||||
_isLoop = false;
|
||||
} else if (scheme == typeid(FarLoopSubdivisionTables<U>) ) {
|
||||
result = new FarLoopSubdivisionTables<U>(farMesh, _maxlevel);
|
||||
_isLoop = true;
|
||||
switch (scheme) {
|
||||
case FarSubdivisionTables<U>::CATMARK:
|
||||
result = new FarCatmarkSubdivisionTables<U>(farMesh, _maxlevel);
|
||||
_isLoop = false;
|
||||
break;
|
||||
case FarSubdivisionTables<U>::LOOP:
|
||||
result = new FarLoopSubdivisionTables<U>(farMesh, _maxlevel);
|
||||
_isLoop = true;
|
||||
break;
|
||||
case FarSubdivisionTables<U>::BILINEAR:
|
||||
result = new FarBilinearSubdivisionTables<U>(farMesh, _maxlevel);
|
||||
_isLoop = false;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
result->_F_ITa.resize(total_F_ITa);
|
||||
result->_F_IT.resize(total_F_IT);
|
||||
result->_E_IT.resize(total_E_IT);
|
||||
@ -293,11 +301,13 @@ FarMultiMeshFactory<T, U>::spliceSubdivisionTables(FarMesh<U> *farMesh, FarMeshV
|
||||
fvOffset += (int)tables->Get_F_ITa().size()/2;
|
||||
V_IToffset += (int)tables->Get_V_IT().size();
|
||||
|
||||
if (scheme == typeid(FarCatmarkSubdivisionTables<U>) ||
|
||||
scheme == typeid(FarLoopSubdivisionTables<U>)) {
|
||||
if (scheme == FarSubdivisionTables<U>::CATMARK or
|
||||
scheme == FarSubdivisionTables<U>::LOOP) {
|
||||
|
||||
evOffset += (int)tables->Get_E_IT().size()/4;
|
||||
vvOffset += (int)tables->Get_V_ITa().size()/5;
|
||||
} else {
|
||||
|
||||
evOffset += (int)tables->Get_E_IT().size()/2;
|
||||
vvOffset += (int)tables->Get_V_ITa().size();
|
||||
}
|
||||
@ -335,10 +345,12 @@ FarMultiMeshFactory<T, U>::spliceSubdivisionTables(FarMesh<U> *farMesh, FarMeshV
|
||||
E_W = copyWithOffset(E_W, tables->Get_E_W(), 0);
|
||||
|
||||
// copy vert tables
|
||||
if (scheme == typeid(FarCatmarkSubdivisionTables<U>) ||
|
||||
scheme == typeid(FarLoopSubdivisionTables<U>)) {
|
||||
if (scheme == FarSubdivisionTables<U>::CATMARK or
|
||||
scheme == FarSubdivisionTables<U>::LOOP) {
|
||||
|
||||
V_ITa = copyWithOffsetV_ITa(V_ITa, tables->Get_V_ITa(), V_IToffsets[i], vertexOffsets[i]);
|
||||
} else {
|
||||
|
||||
V_ITa = copyWithOffset(V_ITa, tables->Get_V_ITa(), vertexOffsets[i]);
|
||||
}
|
||||
V_W = copyWithOffset(V_W, tables->Get_V_W(), 0);
|
||||
|
@ -65,6 +65,14 @@ template <class U> class FarMesh;
|
||||
template <class U> class FarSubdivisionTables {
|
||||
|
||||
public:
|
||||
|
||||
enum Scheme {
|
||||
UNDEFINED=0,
|
||||
BILINEAR,
|
||||
CATMARK,
|
||||
LOOP
|
||||
};
|
||||
|
||||
enum TableType {
|
||||
E_IT, ///< edge-vertices adjacency indexing table
|
||||
E_W, ///< edge-vertices weights
|
||||
@ -128,6 +136,10 @@ public:
|
||||
/// \brief Returns the vertex vertices weights table
|
||||
std::vector<float> const & Get_V_W() const { return _V_W; }
|
||||
|
||||
/// \brief Returns the subdivision scheme of the tables
|
||||
/// (sidesteps typeinfo dependency)
|
||||
virtual Scheme GetScheme() const { return UNDEFINED; }
|
||||
|
||||
/// \brief Returns the number of indexing tables needed to represent this particular
|
||||
/// subdivision scheme.
|
||||
virtual int GetNumTables() const { return 5; }
|
||||
|
Loading…
Reference in New Issue
Block a user