CSG operations on implicit marching cubes

I render isosurfaces using moving cubes (or maybe marching squares , since it's 2D), and I want to perform operations on sets, such as set difference, intersection, and union. I thought this was easy to implement by simply selecting one of the two vertex scalars from two different implicit surfaces, but it is not.

For initial testing, I tried with two areas and the difference of the given operation. those. A - B. One circle moves and the other is stationary. Here's the approach I tried, selecting scalar vertices and classifying angular vertices both inside and out. The code is written in C ++. OpenGL is used for rendering, but it doesn’t matter. Normal rendering without any CSG operations gives the expected result.



void march(const vec2& cmin, //min x and y for the grid cell const vec2& cmax, //max x and y for the grid cell std::vector<vec2>& tri, float iso, float (*cmp1)(const vec2&), //distance from stationary circle float (*cmp2)(const vec2&) //distance from moving circle ) { unsigned int squareindex = 0; float scalar[4]; vec2 verts[8]; /* initial setup of the grid cell */ verts[0] = vec2(cmax.x, cmax.y); verts[2] = vec2(cmin.x, cmax.y); verts[4] = vec2(cmin.x, cmin.y); verts[6] = vec2(cmax.x, cmin.y); float s1,s2; /********************************** ********For-loop of interest****** *******Set difference between **** *******two implicit surfaces****** **********************************/ for(int i=0,j=0; i<4; ++i, j+=2){ s1 = cmp1(verts[j]); s2 = cmp2(verts[j]); if((s1 < iso)){ //if inside circle1 if((s2 < iso)){ //if inside circle2 scalar[i] = s2; //then set the scalar to the moving circle } else { scalar[i] = s1; //only inside circle1 squareindex |= (1<<i); //mark as inside } } else { scalar[i] = s1; //inside neither circle } } if(squareindex == 0) return; /* Usual interpolation between edge points to compute the new intersection points */ verts[1] = mix(iso, verts[0], verts[2], scalar[0], scalar[1]); verts[3] = mix(iso, verts[2], verts[4], scalar[1], scalar[2]); verts[5] = mix(iso, verts[4], verts[6], scalar[2], scalar[3]); verts[7] = mix(iso, verts[6], verts[0], scalar[3], scalar[0]); for(int i=0; i<10; ++i){ //10 = maxmimum 3 triangles, + one end token int index = triTable[squareindex][i]; //look up our indices for triangulation if(index == -1) break; tri.push_back(verts[index]); } } 

This causes me strange bumps: here
(source: mechcore.net )

It appears that the CSG operation is performed without interpolation. It just β€œdrops” the entire triangular nick. Do I need to interpolate in any other way or combine scalar values ​​of the vertices? I would like to help with this. A complete test case can be downloaded HERE

UPDATE: Basically, my implementation of marching squares works fine. This is my scalar field, which is broken, and I wonder how the correct path will look. Preferably, I am looking for a general approach for implementing the three operations on sets that I discussed above for ordinary primitives (circle, rectangle / square, plane)

UPDATE 2: Here are some new images after implementing the defendant document:

1.Difference
2.Intersection
3.Union

UPDATE 3: I also implemented this in 3D, with proper shading / lighting:

1. The difference between a larger sphere and a smaller sphere
2. The difference between the larger sphere and the smaller sphere in the center, cut off by two planes on both sides, and then merging with the sphere in the center.
3. The connection between the two cylinders.

+7
math graphics marching-cubes
source share
1 answer

This is not how you mix scalar fields. Your scalars say one thing, but whether your flags are inside or not say the other. First merge the fields, and then make it look like you are making a single compound object:

 for(int i=0,j=0; i<4; ++i, j+=2){ s1 = cmp1(verts[j]); s2 = cmp2(verts[j]); s = max(s1, iso-s2); // This is the secret sauce if(s < iso) { // inside circle1, but not inside circle2 squareindex |= (1<<i); } scalar[i] = s; } 

This article may be helpful: Combining CSG modeling with soft blending using Lipschitz implicit surfaces .

+3
source share

All Articles