CSG2: Error invoking FromMesh with a mesh from CSG2

Version: 7.31.2
CSG2 Version: manifold-3d@2.5.1
Engine: WebGL, WebGL2, and WebGPU
Browser: Chrome and Firefox and MS Edge
OS: Windows 10
Playground:

Desc:
Using CSG2 to dig holes from a mesh, and update the vertex data of the mesh using vertex data produced by CSG2, the first 25 operations are ok, but the next one (indexed 25) throws error.

Expected:
Meshes with vertex data from CSG2 should be ok to be used to contruct a CSG2 without errors.

Actual:
Uncaught Error: Incorrect volume detected. Make sure you are not using a double sided geometry
at e._ProcessData (csg2.ts:312:19)


Extra info:
If finalCsg is reused, then all points can be processed, but it still should be considered a bug since mesh produced by CSG2 can not be imported back:

pinging the master @Deltakosh

This is not a bug per se. You are creating a volume that will end up not being watertight and as such its genus will be negative and thus CSG2 will not be able to work with it anymore

2 Likes

But the mesh was created by CSG2 itself, should CSG2 produce CSG2-compatible mesh?
Also, CSG works without errors:

Yes csg2 is very picky but that’s the price for perf and accuracy.

Regarding your problem I would tend to agree with you but this is a limitation of manifold.

1 Like

So, should it be upstreamed to manifold devs?
But as shown in the main post, the csg instance that produces mesh that can not be imported back, can be used for futher boolean operations.

Yes I think so! Do you mind opening a case there?

1 Like

I tried to dump raw calls to manifold using the playground here:

And I can run converted code in https://manifoldcad.org/

// gzip compressed json, to save space
var gzip = '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';
// This is gunzipSync from fflate <https://github.com/101arrowz/fflate/issues/138>
var r=Uint8Array,e=Uint16Array,n=Uint32Array,a=new r([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),t=new r([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),i=new r([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),f=function(r,a){for(var t=new e(31),i=0;i<31;++i)t[i]=a+=1<<r[i-1];var f=new n(t[30]);for(i=1;i<30;++i)for(var o=t[i];o<t[i+1];++o)f[o]=o-t[i]<<5|i;return[t,f]},o=f(a,2),v=o[0],u=o[1];v[28]=258,u[258]=28;for(var l=f(t,0),c=l[0],d=(l[1],new e(32768)),s=0;s<32768;++s){var w=(43690&s)>>>1|(21845&s)<<1;w=(61680&(w=(52428&w)>>>2|(13107&w)<<2))>>>4|(3855&w)<<4,d[s]=((65280&w)>>>8|(255&w)<<8)>>>1}var h=function(r,n,a){for(var t=r.length,i=0,f=new e(n);i<t;++i)r[i]&&++f[r[i]-1];var o,v=new e(n);for(i=0;i<n;++i)v[i]=v[i-1]+f[i-1]<<1;if(a){o=new e(1<<n);var u=15-n;for(i=0;i<t;++i)if(r[i])for(var l=i<<4|r[i],c=n-r[i],s=v[r[i]-1]++<<c,w=s|(1<<c)-1;s<=w;++s)o[d[s]>>>u]=l}else for(o=new e(t),i=0;i<t;++i)r[i]&&(o[i]=d[v[r[i]-1]++]>>>15-r[i]);return o},b=new r(288);for(s=0;s<144;++s)b[s]=8;for(s=144;s<256;++s)b[s]=9;for(s=256;s<280;++s)b[s]=7;for(s=280;s<288;++s)b[s]=8;var g=new r(32);for(s=0;s<32;++s)g[s]=5;var E=h(b,9,1),y=h(g,5,1),p=function(r){for(var e=r[0],n=1;n<r.length;++n)r[n]>e&&(e=r[n]);return e},k=function(r,e,n){var a=e/8|0;return(r[a]|r[a+1]<<8)>>(7&e)&n},T=function(r,e){var n=e/8|0;return(r[n]|r[n+1]<<8|r[n+2]<<16)>>(7&e)},m=function(r){return(r+7)/8|0},x=function(a,t,i){(null==t||t<0)&&(t=0),(null==i||i>a.length)&&(i=a.length);var f=new(2==a.BYTES_PER_ELEMENT?e:4==a.BYTES_PER_ELEMENT?n:r)(i-t);return f.set(a.subarray(t,i)),f},M=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],S=function(r,e,n){var a=new Error(e||M[r]);if(a.code=r,Error.captureStackTrace&&Error.captureStackTrace(a,S),!n)throw a;return a},U=function(e,n,f){var o=e.length;if(!o||f&&f.f&&!f.l)return n||new r(0);var u=!n||f,l=!f||f.i;f||(f={}),n||(n=new r(3*o));var d=function(e){var a=n.length;if(e>a){var t=new r(Math.max(2*a,e));t.set(n),n=t}},s=f.f||0,w=f.p||0,b=f.b||0,g=f.l,M=f.d,U=f.m,_=f.n,A=8*o;do{if(!g){s=k(e,w,1);var q=k(e,w+1,3);if(w+=3,!q){var z=e[(C=m(w)+4)-4]|e[C-3]<<8,B=C+z;if(B>o){l&&S(0);break}u&&d(b+z),n.set(e.subarray(C,B),b),f.b=b+=z,f.p=w=8*B,f.f=s;continue}if(1==q)g=E,M=y,U=9,_=5;else if(2==q){var D=k(e,w,31)+257,F=k(e,w+10,15)+4,L=D+k(e,w+5,31)+1;w+=14;for(var N=new r(L),P=new r(19),R=0;R<F;++R)P[i[R]]=k(e,w+3*R,7);w+=3*F;var Y=p(P),O=(1<<Y)-1,j=h(P,Y,1);for(R=0;R<L;){var C,G=j[k(e,w,O)];if(w+=15&G,(C=G>>>4)<16)N[R++]=C;else{var H=0,I=0;for(16==C?(I=3+k(e,w,3),w+=2,H=N[R-1]):17==C?(I=3+k(e,w,7),w+=3):18==C&&(I=11+k(e,w,127),w+=7);I--;)N[R++]=H}}var J=N.subarray(0,D),K=N.subarray(D);U=p(J),_=p(K),g=h(J,U,1),M=h(K,_,1)}else S(1);if(w>A){l&&S(0);break}}u&&d(b+131072);for(var Q=(1<<U)-1,V=(1<<_)-1,W=w;;W=w){var X=(H=g[T(e,w)&Q])>>>4;if((w+=15&H)>A){l&&S(0);break}if(H||S(2),X<256)n[b++]=X;else{if(256==X){W=w,g=null;break}var Z=X-254;if(X>264){var $=a[R=X-257];Z=k(e,w,(1<<$)-1)+v[R],w+=$}var rr=M[T(e,w)&V],er=rr>>>4;rr||S(3),w+=15&rr;K=c[er];if(er>3){$=t[er];K+=T(e,w)&(1<<$)-1,w+=$}if(w>A){l&&S(0);break}u&&d(b+131072);for(var nr=b+Z;b<nr;b+=4)n[b]=n[b-K],n[b+1]=n[b+1-K],n[b+2]=n[b+2-K],n[b+3]=n[b+3-K];b=nr}}f.l=g,f.p=W,f.b=b,f.f=s,g&&(s=1,f.m=U,f.d=M,f.n=_)}while(!s);return b==n.length?n:x(n,0,b)},_=new r(0),A=function(r){31==r[0]&&139==r[1]&&8==r[2]||S(6,"invalid gzip data");var e=r[3],n=10;4&e&&(n+=r[10]|2+(r[11]<<8));for(var a=(e>>3&1)+(e>>4&1);a>0;a-=!r[n++]);return n+(2&e)},q=function(r){var e=r.length;return(r[e-4]|r[e-3]<<8|r[e-2]<<16|r[e-1]<<24)>>>0};function z(e,n){return U(e.subarray(A(e),-8),n||new r(q(e)))}var B="undefined"!=typeof TextDecoder&&new TextDecoder;try{B.decode(_,{stream:!0}),1}catch(r){}"function"==typeof queueMicrotask?queueMicrotask:"function"==typeof setTimeout&&setTimeout;
const gunzipSync = z;
/**
 * Converts a given base64 string as an ASCII encoded stream of data
 * @param base64Data The base64 encoded string to decode
 * @returns Decoded ASCII string
 */
const DecodeBase64ToString = (base64Data) => {
    return atob(base64Data);
};

/**
 * Converts a given base64 string into an ArrayBuffer of raw byte data
 * @param base64Data The base64 encoded string to decode
 * @returns ArrayBuffer of byte data
 */
const DecodeBase64ToBinary = (base64Data) => {
    const decodedString = DecodeBase64ToString(base64Data);
    const bufferLength = decodedString.length;
    const bufferView = new Uint8Array(new ArrayBuffer(bufferLength));

    for (let i = 0; i < bufferLength; i++) {
        bufferView[i] = decodedString.charCodeAt(i);
    }

    return bufferView.buffer;
};
var buffer = gunzipSync(new Uint8Array(DecodeBase64ToBinary(gzip)), undefined);

function toMesh(mesh): Mesh {
  const meshDecl: MeshOptions = {
    numProp: mesh.numProp,
    runIndex: new Uint32Array(mesh.runIndex),
    runOriginalID: new Uint32Array(mesh.runOriginalID),
    vertProperties: new Float32Array(DecodeBase64ToBinary(mesh.vertProperties)),
    triVerts: new Uint32Array(DecodeBase64ToBinary(mesh.triVerts)),
  };
  const manifoldMesh = new Mesh(meshDecl);
  manifoldMesh.merge();
  return manifoldMesh;
}

var {mesh1, mesh2, mesh3} = JSON.parse(new TextDecoder().decode(buffer));
// first pass
const manifold1 = new Manifold(toMesh(mesh1));
console.log('manifold1.genus', manifold1.genus());
const manifold2 = new Manifold(toMesh(mesh2));
console.log('manifold2.genus', manifold2.genus());

const result = Manifold.difference(manifold1, manifold2);
console.log('result.genus', result.genus());
const resultMesh = result.getMesh();
console.log(resultMesh)

// second pass
const resultManifold = new Manifold(resultMesh);
console.log('resultManifold.genus', resultManifold.genus())
const manifold3 = new Manifold(toMesh(mesh3));
console.log('manifold3.genus', manifold3.genus());

const result2 = Manifold.difference(resultManifold, manifold3)
console.log('result2.genus', result2.genus())
const result2Mesh = result2.getMesh();
console.log(result2Mesh)

Note this code has been compressed since the original code is too large to be posted here, see the original stuff here: https://playground.babylonjs.com/#OTT4DR#4

It just runs without errors, and the genus printed in my console are:

manifold1.genus 0
manifold2.genus 0
result.genus -1
resultManifold.genus -1
manifold3.genus 0
result2.genus -2

Does this help? Or is this a bug that should be upstreamed?

1 Like

Yes as we can see the genus are negative

Posted here:

But since upstream can just run the Manifold.difference with negative genus, could there be a “permissive” mode that logs instead of throws in cases like this?

1 Like

I can totally do that!

Let me do a PR :slight_smile:

Based on the comments upstream, I realize that it must not be an error
It is ok to have disjoint manifold

I’ll simply remove the throw :wink:

1 Like

The commit is here, for reference:

1 Like