11#include < gtest/gtest.h>
22#include " core/Compressor.h"
3+ #include " core/Splitter.h"
34#include " MeshFixtures.h"
45#include " utils/MeshTools.h"
56
@@ -92,12 +93,18 @@ TEST_F(CompressorTest, DoesNotCompressDisconnectedQuads) {
9293
9394TEST_F (CompressorTest, CompressWithHoleCreatesInnerContour) {
9495 // Create 8 quads forming a ring with a hole in the middle
95- // Should be merged into one surface with inner contour
96+ // The ring decomposes into 3 rectangles (left col, right col, center cols)
9697
9798 Mesh mesh;
9899 mesh.grid = grid_;
99100
100101 // Outer ring of quads (leaving center 1,1 to 2,2 empty)
102+ // Layout:
103+ // x=0 x=1 x=2 x=3
104+ // y=3 [5] [8] [6]
105+ // y=2 [3] hole [4]
106+ // y=1 [1] [7] [2]
107+ // y=0
101108 // Bottom row
102109 addQuad (mesh, {0 , 0 , 0 }, {1 , 0 , 0 }, {1 , 1 , 0 }, {0 , 1 , 0 });
103110 addQuad (mesh, {2 , 0 , 0 }, {3 , 0 , 0 }, {3 , 1 , 0 }, {2 , 1 , 0 });
@@ -115,7 +122,14 @@ TEST_F(CompressorTest, CompressWithHoleCreatesInnerContour) {
115122
116123 auto merged = core::Compressor::compressSurfaces (mesh);
117124
118- EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 4u );
125+ auto finalCount = countMeshElementsIf (mesh, isQuad);
126+
127+ // Optimal decomposition: 3 rectangles
128+ // - Left column (quads 1,3,5): cells x=0, y=0-3
129+ // - Right column (quads 2,4,6): cells x=2-3, y=0-3
130+ // - Center (quads 7,8): cells x=1-2, y=0 and y=2-3
131+ EXPECT_EQ (finalCount, 3u );
132+ EXPECT_EQ (merged, 5u ); // 8 - 3 = 5 surfaces merged
119133}
120134
121135TEST_F (CompressorTest, DoesNotCompressQuadsWithDifferentNormals) {
@@ -137,4 +151,97 @@ TEST_F(CompressorTest, DoesNotCompressQuadsWithDifferentNormals) {
137151 EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 2u );
138152}
139153
154+ TEST_F (CompressorTest, CompressAndSplit2x2GridRoundTrip) {
155+ // Create 4 quads in 2x2 grid, compress to 1 surface, split back to 4 quads
156+
157+ Mesh mesh;
158+ mesh.grid = grid_;
159+
160+ // 2x2 grid of quads
161+ addQuad (mesh, {0 , 0 , 0 }, {1 , 0 , 0 }, {1 , 1 , 0 }, {0 , 1 , 0 });
162+ addQuad (mesh, {1 , 0 , 0 }, {2 , 0 , 0 }, {2 , 1 , 0 }, {1 , 1 , 0 });
163+ addQuad (mesh, {0 , 1 , 0 }, {1 , 1 , 0 }, {1 , 2 , 0 }, {0 , 2 , 0 });
164+ addQuad (mesh, {1 , 1 , 0 }, {2 , 1 , 0 }, {2 , 2 , 0 }, {1 , 2 , 0 });
165+
166+ EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 4u );
167+
168+ // Compress: 4 quads -> 1 surface
169+ auto merged = core::Compressor::compressSurfaces (mesh);
170+ EXPECT_EQ (merged, 3u );
171+ EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 1u );
172+
173+ // Debug: print compressed surface
174+ std::cerr << " Compressed surface vertices: " ;
175+ for (auto vid : mesh.groups [0 ].elements [0 ].vertices ) {
176+ std::cerr << " (" << mesh.coordinates [vid](0 ) << " ,"
177+ << mesh.coordinates [vid](1 ) << " ,"
178+ << mesh.coordinates [vid](2 ) << " ) " ;
179+ }
180+ std::cerr << std::endl;
181+
182+ // Split: 1 surface -> 4 quads
183+ auto splitCount = core::Splitter::splitSurfaces (mesh);
184+ std::cout << " Split count: " << splitCount << std::endl;
185+ EXPECT_EQ (splitCount, 4u );
186+ EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 4u );
187+ }
188+
189+ TEST_F (CompressorTest, CompressAndSplitRingRoundTrip) {
190+ // Create ring of 8 quads, compress, split back
191+
192+ Mesh mesh;
193+ mesh.grid = grid_;
194+
195+ // Ring of 8 quads (same as CompressWithHoleCreatesInnerContour)
196+ addQuad (mesh, {0 , 0 , 0 }, {1 , 0 , 0 }, {1 , 1 , 0 }, {0 , 1 , 0 });
197+ addQuad (mesh, {2 , 0 , 0 }, {3 , 0 , 0 }, {3 , 1 , 0 }, {2 , 1 , 0 });
198+ addQuad (mesh, {0 , 1 , 0 }, {1 , 1 , 0 }, {1 , 2 , 0 }, {0 , 2 , 0 });
199+ addQuad (mesh, {2 , 1 , 0 }, {3 , 1 , 0 }, {3 , 2 , 0 }, {2 , 2 , 0 });
200+ addQuad (mesh, {0 , 2 , 0 }, {1 , 2 , 0 }, {1 , 3 , 0 }, {0 , 3 , 0 });
201+ addQuad (mesh, {2 , 2 , 0 }, {3 , 2 , 0 }, {3 , 3 , 0 }, {2 , 3 , 0 });
202+ addQuad (mesh, {1 , 0 , 0 }, {2 , 0 , 0 }, {2 , 1 , 0 }, {1 , 1 , 0 });
203+ addQuad (mesh, {1 , 3 , 0 }, {2 , 3 , 0 }, {2 , 2 , 0 }, {1 , 2 , 0 });
204+
205+ EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 8u );
206+
207+ // Compress: 8 quads -> 3 surfaces
208+ auto merged = core::Compressor::compressSurfaces (mesh);
209+ EXPECT_EQ (merged, 5u );
210+ auto compressedCount = countMeshElementsIf (mesh, isQuad);
211+ EXPECT_EQ (compressedCount, 3u );
212+
213+ // Split: 3 surfaces -> 8 quads
214+ auto splitCount = core::Splitter::splitSurfaces (mesh);
215+ EXPECT_EQ (splitCount, 8u );
216+ EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 8u );
217+ }
218+
219+ TEST_F (CompressorTest, CompressAndSplit3x3GridRoundTrip) {
220+ // Create 9 quads in 3x3 grid, compress to 1 surface, split back to 9 quads
221+
222+ Mesh mesh;
223+ mesh.grid = grid_;
224+
225+ // 3x3 grid of quads
226+ for (int i = 0 ; i < 3 ; i++) {
227+ for (int j = 0 ; j < 3 ; j++) {
228+ addQuad (mesh,
229+ {i, j, 0 }, {i+1 , j, 0 },
230+ {i+1 , j+1 , 0 }, {i, j+1 , 0 });
231+ }
232+ }
233+
234+ EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 9u );
235+
236+ // Compress: 9 quads -> 1 surface
237+ auto merged = core::Compressor::compressSurfaces (mesh);
238+ EXPECT_EQ (merged, 8u );
239+ EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 1u );
240+
241+ // Split: 1 surface -> 9 quads
242+ auto splitCount = core::Splitter::splitSurfaces (mesh);
243+ EXPECT_EQ (splitCount, 9u );
244+ EXPECT_EQ (countMeshElementsIf (mesh, isQuad), 9u );
245+ }
246+
140247}
0 commit comments