fix(IfcImporter): add vertex key to geometry dedup hash - #238
Conversation
|
The issue references an concise ifc repro fixture that can be used as a test case (once vitest is in) |
ShaMan123
left a comment
There was a problem hiding this comment.
The vertex key construction is Claude's suggestion.
|
Actually I am not sure this is a correct fix. |
|
Great repro, it makes the problem obvious: both plates share outline, area, volume and centroid, and the only difference is where the holes sit, which is exactly what the old key never looked at. Direction is right. One thing to fix first: the let h = Math.round(position[i] * p) % MODULUS;
if (h < 0) h += MODULUS;And a question: does the key need to be order-invariant at all? The commutative sum buys a match on a permuted buffer but costs collision resistance, where an ordered polynomial hash is stronger and simpler. Do we actually see web-ifc emit permuted duplicates? If not, I'd take the ordered one. Minor: the AABB doesn't separate your two plates (same outline, same box), so The #237 repro would make a good regression test. Still a draft, what's left on your side? |
|
I am not an expert of hashing so I do not feel comfortable suggesting the correct solution. I do understand and agree that the current is lacking due to sign cancellation (part of why the PR is a draft).
I am not sure how web-ifc handles it. I am very cautious due to the last month (working on Tekla garbage ifc dedup). I would argue that we could add a simple sort on the holes before hashing and that will cover all cases.
You mean that the AABB isn't needed any longer since the vertex key handles it? Is there no other case that relies on the AABB? |
|
Ran it through web-ifc 0.0.77 so we stop guessing. Three cases, reading the exact vertex buffer the dedup key sees:
So web-ifc never spontaneously permutes, but it hands back a permuted buffer when the source lists the same triangles in a different order (case 3). It emits in face-iteration order, so triangle order in the IFC is what leaks through. What that means for the key. The common duplicate case (an exporter repeating a product, or a shared representation map / mapped items) is case 1, byte-identical, so an ordered polynomial hash over the buffer dedups it, and it drops the sign-cancellation problem for free since you never sum commutatively. The only thing ordered misses is case 3: geometrically identical but triangle-order-permuted, which is what your commutative sum buys today. Dropping to ordered would stop deduping those, a memory miss, not wrong geometry. So the real decision is whether case 3 is worth chasing. If yes, don't keep the commutative sum (weak collisions plus the cancellation trap). Do it order-invariant the robust way: hash each vertex to a canonical value, sort those hashes, then fold them with an ordered polynomial. That is where a sort belongs, over all per-vertex hashes, not over holes, since case 3 shows the permutation is whole-buffer triangle order with no separable holes list to sort. My read: case 3 needs two products that are the same shape but authored with different triangle order, which a single exporter rarely does within one file. I would ship the ordered hash, which fixes #237 and is simpler and stronger, and add the sorted order-invariant variant only if a real file actually shows triangle-order-permuted duplicates. Happy to go straight to the sorted version if your Tekla files make you want belt and braces, it is just the extra On performance: no meaningful cost either way. The vertex-key loop runs once per distinct geometry, not per instance (the On the AABB: keep it, I wasn't calling it redundant. In your repro the two plates share the same box, so there the |
Description
closes #237
Additional context
What is the purpose of this pull request?
Before submitting the PR, please make sure you do the following:
feat(examples): add hello-world example).fixes #123).