cutdigital / mcut

A library for detecting and resolving intersections between two surface meshes.
https://cutdigital.github.io/mcut.site
Other
413 stars 76 forks source link

Assertion failed: (int)intersection_test_ivtx_list.size() >= 2 #25

Closed jellychen closed 1 year ago

jellychen commented 1 year ago

Two of the same models will appear during the test

Assertion failed: 3rd/mcut/source/kernel.cpp, 3406 at '(int)intersection_test_ivtx_list.size() >= 2'

During operation, it is not very convenient to detect whether the input model is exactly the same. Is there any good way to avoid this crash?

chitalu commented 1 year ago

Hi @jellychen ,

Please share the simplest-possible model so that I may reproduce this error.

jellychen commented 1 year ago

HI chitalu

Thank you for your reply

I use the model in the attachment. As a test, my cut mesh and src mesh both use this model

s.obj.zip

McContext context = MC_NULL_HANDLE;
    McResult err = mcCreateContext(&context, 0);
    assert(err == MC_NO_ERROR);
    McUint32 attempts = 1 << 3;
    err = mcBindState(context, MC_CONTEXT_GENERAL_POSITION_ENFORCEMENT_ATTEMPTS, sizeof(McUint32), (void*)&attempts);
    assert(err == MC_NO_ERROR);
    McDouble epsilon = 1e-4;
    err = mcBindState(context, MC_CONTEXT_GENERAL_POSITION_ENFORCEMENT_CONSTANT, sizeof(McDouble), &epsilon);
    assert(err == MC_NO_ERROR);
    err = mcDispatch(
        context,
        MC_DISPATCH_VERTEX_ARRAY_FLOAT | MC_DISPATCH_ENFORCE_GENERAL_POSITION | flags,
        a->vcertices_.data(),
        a->faces_.data(),
        a->face_sizes_.data(),
        a->NumVertices(),
        a->NumFaces(),
        b->vcertices_.data(),
        b->faces_.data(),
        b->face_sizes_.data(),
        b->NumVertices(),
        b->NumFaces());
    if (MC_NO_ERROR != err)  {
        mcReleaseConnectedComponents(context, 0, nullptr);
        mcReleaseContext(context);
        return false;
    }

They all turned out to be wrong

operator()(...) -> Floating-polygon partitioning step could not find a usable fpSegment (EventID=0xdecb0)

jellychen commented 1 year ago

I see a lot of use of assert in my code. Can I change it to an exception? In this way, at least, there will be no crashes during the running of the program.

jellychen commented 1 year ago

I did a few more tests, using the following two meshes. The code simply modifies the path of the model in CSGBoolean.

But it didn't work out well.

compute A_NOT_B
operator()(...) -> invalid cut-mesh connectivity (EventID=0xdecb0)
MCUT error: err == MC_NO_ERROR

data.zip

yunku2002 commented 1 year ago

Thanks for the awesome, robust (apart from this issue?) CSG implementation @chitalu.

Let me demonstrate a minimal example involving two tetrahedra reproducing this problem. Note how the edges formed by the first two vertices of each mesh are coplanar. I'd imagine this to be a fairly common problem if the input meshes are symmetric to each other.

A.obj

v 5 1 0
v -3 5 -3
v 1 -5 0
v 1 1 6
f 1 3 2
f 1 2 4
f 1 4 3
f 2 3 4

B.obj

v -8 1 0
v 1 5 -3
v -1 -5 -1
v -1 0 6
f 1 2 3
f 1 4 2
f 1 3 4
f 2 4 3

Disabling asserts by defining NDEBUG leads to other problems (of course). In this case, the following exception is thrown: Floating-polygon partitioning step could not find a usable fpSegment.

But if I change the very first coordinate of A.obj, which is 5, to 7, what happens is different depending on the operation. For -u and -dc, an exception is thrown by the STL: invalid unordered_map<K, T> key (on Windows). For -i and -ds, the program terminates without any errors, but no connected component is found.

Now if I add another change to the first coordinate of B.obj, from -8 to -7, the STL exception is thrown for -i and -ds. For -u and -dc, the CSG model is computed correctly. Swapping the two models and testing on Linux also change the results slightly.

I think this must be a quite difficult problem to handle, so I wish you the best : )

stefnotch commented 11 months ago

@chitalu I apologise for the ping instead of simply testing it myself, but has the above issue been resolved? If not, may I suggest reopening this issue, and adding yunku2002's test case to the unit tests?