Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugging Weird Issue #1444

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
buildType: RELEASE
containerImage: ghcr.io/gafferhq/build/build:3.0.0
options: .github/workflows/main/options.posix
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/8.0.1/gafferDependencies-8.0.1-linux-gcc11.tar.gz
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/9.0.0/gafferDependencies-9.0.0-linux-gcc11.tar.gz
tests: testCore testCorePython testScene testImage testAlembic testUSD testVDB
publish: true

Expand All @@ -52,23 +52,23 @@ jobs:
buildType: DEBUG
containerImage: ghcr.io/gafferhq/build/build:3.0.0
options: .github/workflows/main/options.posix
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/8.0.1/gafferDependencies-8.0.1-linux-gcc11.tar.gz
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/9.0.0/gafferDependencies-9.0.0-linux-gcc11.tar.gz
tests: testCore testCorePython testScene testImage testAlembic testUSD testVDB
publish: false

- name: windows
os: windows-2019
os: windows-2022
buildType: RELEASE
options: .github/workflows/main/options.windows
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/8.0.1/gafferDependencies-8.0.1-windows.zip
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/9.0.0/gafferDependencies-9.0.0-windows.zip
tests: testCore testCorePython testScene testImage testAlembic testUSD testVDB
publish: true

- name: windows-debug
os: windows-2019
os: windows-2022
buildType: RELWITHDEBINFO
options: .github/workflows/main/options.windows
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/8.0.1/gafferDependencies-8.0.1-windows.zip
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/9.0.0/gafferDependencies-9.0.0-windows.zip
tests: testCore testCorePython testScene testImage testAlembic testUSD testVDB
publish: false

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main/options.windows
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import os

deps = os.environ.get( "CORTEX_BUILD_NAME" )
includes = os.path.join( deps, "include" )
libs = os.path.join( deps, "lib" )
libs = os.path.join( deps, "lib" ) + os.pathsep + os.path.join( deps, "bin" )

build = os.environ.get( "CORTEX_BUILD_NAME" )

Expand Down
2 changes: 2 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Build
- CI :
- IECoreHoudini tests updated to pass on newer environments.
- IECoreGL tests updated with relaxed precisions for image comparisons.
- Updated to GafferHQ/dependencies 9.0.0.
- Updated Windows build to use MSVC 2022.

10.5.10.0 (relative to 10.5.9.5)
=========
Expand Down
2 changes: 1 addition & 1 deletion SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,7 @@ o.Add(
###########################################################################################

env = Environment(
MSVC_VERSION = "14.2",
MSVC_VERSION = "14.3",
options = o
)

Expand Down
182 changes: 73 additions & 109 deletions src/IECoreScene/MeshAlgoSplit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,115 +335,7 @@ void initializeFaceToSegments(

IECoreScene::MeshAlgo::MeshSplitter::MeshSplitter( ConstMeshPrimitivePtr mesh, const PrimitiveVariable &segmentPrimitiveVariable, const IECore::Canceller *canceller ) : m_mesh( mesh ), m_segmentPrimitiveVariable( segmentPrimitiveVariable )
{
if( segmentPrimitiveVariable.interpolation != IECoreScene::PrimitiveVariable::Interpolation::Uniform )
{
throw IECore::Exception( "Primitive variable passed to MeshSplitter must be uniform." );
}

if( !mesh->isPrimitiveVariableValid( segmentPrimitiveVariable ) )
{
throw IECore::Exception( "Primitive variable passed to MeshSplitter must be valid." );
}

const size_t numFaces = mesh->numFaces();
if( numFaces == 0 )
{
// If we don't initialize anything, numMeshes() will return 0, meaning there is no valid context to
// call mesh() in, which is correct for an empty mesh
return;
}

int numSegments = 0;
ConstIntVectorDataPtr faceToSegmentIndexData;
std::vector<int> remapSegmentIndices;
// remapSegmentIndexMin specifies the lowest value in the faceToSegmentIndexBuffer that we need to remap:
// it shifts all accesses to the remapSegmentIndices, allowing remapSegmentIndices to be used when the
// lowest element is not 0
int remapSegmentIndexMin = 0;


IECore::dispatch( segmentPrimitiveVariable.data.get(), [ segmentPrimitiveVariable, &numSegments, &faceToSegmentIndexData, &remapSegmentIndices, &remapSegmentIndexMin, canceller]( const auto *primVarData )
{
using DataType = typename std::remove_pointer_t< decltype( primVarData ) >;
if constexpr ( !TypeTraits::IsVectorTypedData<DataType>::value )
{
throw IECore::Exception( "Invalid PrimitiveVariable, data is not a vector." );
}
else
{
initializeFaceToSegments< typename DataType::ValueType::value_type >(
primVarData,
segmentPrimitiveVariable.indices.get(),
numSegments,
faceToSegmentIndexData,
remapSegmentIndices,
remapSegmentIndexMin,
canceller
);
}
}
);

const std::vector<int> &faceToSegmentIndex = faceToSegmentIndexData->readable();

// Now that we have our faceToSegmentIndex and remapSegmentIndices vector, we can count the number of faces
// for each output mesh
std::vector<int> faceCounts;
faceCounts.resize( numSegments, 0 );

Canceller::check( canceller );

for( int i : faceToSegmentIndex )
{
faceCounts[ remapSegmentIndices[ i - remapSegmentIndexMin ] ]++;
}

// We need store the faces so that it's easy to access all the faces for one output mesh at a time.
// To keep things nice and contiguous, and avoid small allocations for small meshes, we will allocate
// some vectors with the original size of the verticesPerFace vector, but sorted by output mesh index

Canceller::check( canceller );

// meshIndices stores the offset in m_faceRemap where each mesh starts
m_meshIndices.reserve( faceCounts.size() );
int meshStartIndex = 0;
for( int c : faceCounts )
{
m_meshIndices.push_back( meshStartIndex );
meshStartIndex += c;
}

// Now output the faceRemap vector, which tells us for each output face, the index of the source face
const std::vector<int> &verticesPerFace = mesh->verticesPerFace()->readable();

// We do this by keeping track of the current position for each output mesh, and scanning through
// all the input faces, incrementing the correct output mesh position when we find a face for that
// mesh.
std::vector<int> curMeshIndices( m_meshIndices );

Canceller::check( canceller );

m_faceRemap.resize( numFaces );
for( unsigned int faceIndex = 0; faceIndex < numFaces; faceIndex++ )
{
int meshId = remapSegmentIndices[ faceToSegmentIndex[ faceIndex ] - remapSegmentIndexMin ];
m_faceRemap[ curMeshIndices[ meshId ] ] = faceIndex;
curMeshIndices[ meshId ]++;
}

Canceller::check( canceller );

// When accessing faces through m_faceRemap, we need to independently access a face based on its index.
// We don't want to scan from the start summing all the verticesPerFace each time, so this requires
// us to pre-accumulate a running sum of verticesPerFace, that we can index directly into
int faceVertexIndex = 0;
m_faceIndices.reserve( numFaces );
for( int f : verticesPerFace )
{
m_faceIndices.push_back( faceVertexIndex );
faceVertexIndex += f;
}

throw IECore::Exception( "Hello world" );
}

namespace {
Expand Down Expand Up @@ -596,6 +488,13 @@ class Reindexer
}
}
}

std::string message;
for( int i = 0; i < (int)dataRemap.size(); i++ )
{
message += std::to_string( dataRemap[ i ] ) + " ";
}
throw IECore::Exception( "DEBUG: " + message );
}

private:
Expand All @@ -611,6 +510,11 @@ class Reindexer

m_indicesComputed = true;

std::cout << "COMPUTE INDICES\n";


m_numIdsUsed = 0;

for( unsigned int blockId = 0; blockId < m_fromOldIds.size(); blockId++ )
{
auto &block = m_fromOldIds[ blockId ];
Expand All @@ -629,13 +533,55 @@ class Reindexer
}
}


for( int &id : m_newIndices )
{
int blockId = id / m_blockSize;
int subIndex = id % m_blockSize;

std::cout << id << " : " << (*m_fromOldIds[ blockId ])[subIndex] << "\n";
id = (*m_fromOldIds[ blockId ])[subIndex];

}

std::cout << "DONE COMPUTE INDICES\n";


std::vector<int> debugIds;

for( unsigned int blockId = 0; blockId < m_fromOldIds.size(); blockId++ )
{
auto &block = m_fromOldIds[ blockId ];
if( !block )
{
continue;
}

for( int i = 0; i < m_blockSize; i++ )
{
if( (*block)[i] != -1 )
{
debugIds.push_back( (*block)[i] );
}
}
}

bool failed = false;
for( int i = 0; i < (int)debugIds.size(); i++ )
{
failed |= debugIds[i] != i;
}

if( failed )
{
std::string message;
for( int i = 0; i < (int)debugIds.size(); i++ )
{
message += std::to_string( debugIds[ i ] ) + " ";
}
throw IECore::Exception( "BAD IDS " + message );
}

}

// IntVectorData to hold the new indices
Expand Down Expand Up @@ -868,6 +814,24 @@ MeshPrimitivePtr IECoreScene::MeshAlgo::MeshSplitter::mesh( int segmentId, const
std::vector<int> vertRemapBackwards;
vertReindexer.getDataRemapping( vertRemapBackwards );

bool failure = false;
for( int i = startIndex; i < endIndex; i++ )
{
int originalFaceIndex = m_faceRemap[i];
int faceVerts = sourceVerticesPerFace[ originalFaceIndex ];
int faceStart = m_faceIndices[ originalFaceIndex ];
for( int j = 0; j < faceVerts; j++ )
{
int q = sourceVertexIds[ faceStart + j ];
failure |= vertRemapBackwards[ vertReindexer.testIndex( q ) ] != q;
}
}

if( failure )
{
throw IECore::Exception( "detected" );
}

MeshPrimitivePtr ret = new MeshPrimitive( verticesPerFaceData, vertReindexer.getNewIndices(), m_mesh->interpolation() );

// In order to remap the corners, we test every vertex in the original corner list, and see if it is
Expand Down
Loading