@@ -59,6 +59,153 @@ std::size_t Compressor::compressSurfaces(Mesh& mesh) {
5959 return totalOriginal - totalCompressed;
6060}
6161
62+ std::size_t Compressor::compressLines (Mesh& mesh) {
63+ std::size_t totalOriginal = 0 ;
64+ std::size_t totalCompressed = 0 ;
65+
66+ for (GroupId g = 0 ; g < mesh.groups .size (); g++) {
67+ std::vector<Element> lines;
68+
69+ for (ElementId e = 0 ; e < mesh.groups [g].elements .size (); e++) {
70+ const Element& elem = mesh.groups [g].elements [e];
71+ if (elem.type == Element::Type::Line) {
72+ lines.push_back (elem);
73+ }
74+ }
75+
76+ if (lines.empty ()) {
77+ continue ;
78+ }
79+
80+ totalOriginal += lines.size ();
81+ std::vector<Element> compressedLines = compressLines_ (mesh.coordinates , lines);
82+ totalCompressed += compressedLines.size ();
83+
84+ // Build new elements vector with compressed lines
85+ std::vector<Element> newElements;
86+ ElementId lineIdx = 0 ;
87+ for (ElementId e = 0 ; e < mesh.groups [g].elements .size (); e++) {
88+ if (mesh.groups [g].elements [e].type == Element::Type::Line) {
89+ if (lineIdx < compressedLines.size ()) {
90+ newElements.push_back (compressedLines[lineIdx]);
91+ lineIdx++;
92+ }
93+ } else {
94+ newElements.push_back (mesh.groups [g].elements [e]);
95+ }
96+ }
97+ mesh.groups [g].elements = std::move (newElements);
98+ }
99+
100+ return totalOriginal - totalCompressed;
101+ }
102+
103+ std::vector<Element> Compressor::compressLines_ (
104+ const std::vector<Coordinate>& coords,
105+ const std::vector<Element>& lines) {
106+ std::vector<Element> res;
107+ std::map<std::pair<std::array<CellDir, 2 >,
108+ std::pair<Sign, Axis>>,
109+ std::vector<ElementId>> signDirLines;
110+ for (std::size_t l = 0 ; l < lines.size (); l++) {
111+ std::array<Cell, 2 > auxCells;
112+ auxCells[0 ] = utils::GridTools::toCell (coords[lines[l].vertices [0 ]]);
113+ auxCells[1 ] = utils::GridTools::toCell (coords[lines[l].vertices [1 ]]);
114+ std::array<CellDir, 2 > gridLine;
115+ Sign sign = 1 ;
116+ Axis dir = 0 ;
117+ for (Axis d = 0 ; d < 3 ; d++) {
118+ if (auxCells[0 ](d) != auxCells[1 ](d)) {
119+ if (auxCells[0 ](d) > auxCells[1 ](d)) {
120+ sign = -1 ;
121+ }
122+ dir = d;
123+ Axis d1 = (d + 1 ) % 3 ;
124+ Axis d2 = (d + 2 ) % 3 ;
125+ gridLine[0 ] = auxCells[0 ](d1);
126+ gridLine[1 ] = auxCells[0 ](d2);
127+ break ;
128+ }
129+ }
130+ signDirLines[std::make_pair (gridLine,
131+ std::make_pair (sign, dir))].push_back (l);
132+ }
133+ for (std::map<std::pair<std::array<CellDir, 2 >,
134+ std::pair<Sign, Axis>>,
135+ std::vector<ElementId>>::const_iterator
136+ it = signDirLines.begin (); it != signDirLines.end (); ++it) {
137+ std::vector<Element> auxElems;
138+ for (std::size_t i = 0 ; i < it->second .size (); i++) {
139+ auxElems.push_back (lines[it->second [i]]);
140+ }
141+ std::vector<Element> auxRes =
142+ compressDirSignLines_ (coords,
143+ it->first .second ,
144+ auxElems);
145+ res.insert (res.end (), auxRes.begin (), auxRes.end ());
146+ }
147+ return res;
148+ }
149+
150+ std::vector<Element> Compressor::compressDirSignLines_ (
151+ const std::vector<Coordinate>& coords,
152+ const std::pair<Sign, Axis>& signDir,
153+ const std::vector<Element>& lines) {
154+ std::vector<Element> res;
155+ std::map<CoordinateId, std::set<ElementId>> coordLines;
156+ std::map<ElementId, std::set<CoordinateId>> lineCoords;
157+ for (std::size_t l = 0 ; l < lines.size (); l++) {
158+ for (std::size_t v = 0 ; v < 2 ; v++) {
159+ coordLines[lines[l].vertices [v]].insert (l);
160+ lineCoords[l].insert (lines[l].vertices [v]);
161+ }
162+ }
163+ std::set<ElementId> vis;
164+ for (std::map<ElementId, std::set<CoordinateId>>::const_iterator
165+ itExt = lineCoords.begin (); itExt != lineCoords.end (); ++itExt) {
166+ if (vis.count (itExt->first ) == 0 ) {
167+ CoordinateId minCell = lines[itExt->first ].vertices [0 ];
168+ CoordinateId maxCell = lines[itExt->first ].vertices [1 ];
169+ std::queue<ElementId> q;
170+ q.push (itExt->first );
171+ vis.insert (itExt->first );
172+ while (!q.empty ()) {
173+ ElementId elem = q.front ();
174+ q.pop ();
175+ for (std::size_t i = 0 ; i < 2 ; i++) {
176+ if (coords[minCell] > coords[lines[elem].vertices [i]]) {
177+ minCell = lines[elem].vertices [i];
178+ }
179+ if (coords[maxCell] < coords[lines[elem].vertices [i]]) {
180+ maxCell = lines[elem].vertices [i];
181+ }
182+ }
183+ for (std::set<CoordinateId>::const_iterator
184+ itCell = lineCoords[elem].begin ();
185+ itCell != lineCoords[elem].end (); ++itCell) {
186+ for (std::set<ElementId>::const_iterator
187+ itLine = coordLines[*itCell].begin ();
188+ itLine != coordLines[*itCell].end (); ++itLine) {
189+ if (vis.count (*itLine) == 0 ) {
190+ q.push (*itLine);
191+ vis.insert (*itLine);
192+ }
193+ }
194+ }
195+ }
196+ Element newElem;
197+ newElem.type = Element::Type::Line;
198+ newElem.vertices .push_back (minCell);
199+ newElem.vertices .push_back (maxCell);
200+ if (signDir.first < 0 ) {
201+ std::swap (newElem.vertices [0 ], newElem.vertices [1 ]);
202+ }
203+ res.push_back (newElem);
204+ }
205+ }
206+ return res;
207+ }
208+
62209std::vector<Element> Compressor::compressSurfs_ (
63210 std::vector<Coordinate>& coords,
64211 const std::vector<Element>& surfs) {
0 commit comments