Line data Source code
1 : /*
2 : * Copyright (c) 2009-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #include <cassert>
34 : #include <vector>
35 : #include <algorithm>
36 : #include "serialization.h"
37 : #include "common/serialization.h"
38 : #include "debug_util.h"
39 : #include "common/util/hash.h"
40 :
41 : // #include <sstream>
42 : // #include "lib_grid/refinement/projectors/projectors.h"
43 :
44 : // #include <boost/archive/text_oarchive.hpp>
45 : // #include <boost/archive/text_iarchive.hpp>
46 : // #include "common/boost_serialization_routines.h"
47 : // #include "common/util/archivar.h"
48 : // #include "common/util/factory.h"
49 :
50 : using namespace std;
51 :
52 : #define PROFILE_GRID_SERIALIZATION
53 : #ifdef PROFILE_GRID_SERIALIZATION
54 : #define SRLZ_PROFILE_FUNC() PROFILE_FUNC_GROUP("serialization")
55 : #define SRLZ_PROFILE(name) PROFILE_BEGIN_GROUP(name, "serialization")
56 : #define SRLZ_PROFILE_END() PROFILE_END()
57 : #else
58 : #define SRLZ_PROFILE_FUNC()
59 : #define SRLZ_PROFILE(name)
60 : #define SRLZ_PROFILE_END()
61 : #endif
62 :
63 :
64 : namespace ug
65 : {
66 :
67 : ////////////////////////////////////////////////////////////////////////
68 : // Implementation
69 0 : void GridDataSerializationHandler::add(SPVertexDataSerializer cb)
70 : {
71 0 : m_vrtSerializers.push_back(cb);
72 0 : }
73 :
74 0 : void GridDataSerializationHandler::add(SPEdgeDataSerializer cb)
75 : {
76 0 : m_edgeSerializers.push_back(cb);
77 0 : }
78 :
79 0 : void GridDataSerializationHandler::add(SPFaceDataSerializer cb)
80 : {
81 0 : m_faceSerializers.push_back(cb);
82 0 : }
83 :
84 0 : void GridDataSerializationHandler::add(SPVolumeDataSerializer cb)
85 : {
86 0 : m_volSerializers.push_back(cb);
87 0 : }
88 :
89 0 : void GridDataSerializationHandler::add(SPGridDataSerializer cb)
90 : {
91 0 : m_gridSerializers.push_back(cb);
92 0 : }
93 :
94 : template<class TSerializers>
95 : void GridDataSerializationHandler::
96 : write_info(BinaryBuffer& out, TSerializers& serializers) const
97 : {
98 0 : for(size_t i = 0; i < serializers.size(); ++i)
99 0 : serializers[i]->write_info(out);
100 : }
101 :
102 : template<class TSerializers>
103 : void GridDataSerializationHandler::
104 : read_info(BinaryBuffer& in, TSerializers& serializers)
105 : {
106 0 : for(size_t i = 0; i < serializers.size(); ++i)
107 0 : serializers[i]->read_info(in);
108 : }
109 :
110 0 : void GridDataSerializationHandler::write_infos(BinaryBuffer& out) const
111 : {
112 : write_info(out, m_vrtSerializers);
113 : write_info(out, m_edgeSerializers);
114 : write_info(out, m_faceSerializers);
115 : write_info(out, m_volSerializers);
116 : write_info(out, m_gridSerializers);
117 0 : }
118 :
119 0 : void GridDataSerializationHandler::read_infos(BinaryBuffer& in)
120 : {
121 : read_info(in, m_vrtSerializers);
122 : read_info(in, m_edgeSerializers);
123 : read_info(in, m_faceSerializers);
124 : read_info(in, m_volSerializers);
125 : read_info(in, m_gridSerializers);
126 0 : }
127 :
128 0 : void GridDataSerializationHandler::
129 : serialize(BinaryBuffer& out, GridObjectCollection goc) const
130 : {
131 0 : for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
132 0 : serialize(out, goc.begin<Vertex>(lvl), goc.end<Vertex>(lvl));
133 0 : for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
134 0 : serialize(out, goc.begin<Edge>(lvl), goc.end<Edge>(lvl));
135 0 : for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
136 0 : serialize(out, goc.begin<Face>(lvl), goc.end<Face>(lvl));
137 0 : for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
138 0 : serialize(out, goc.begin<Volume>(lvl), goc.end<Volume>(lvl));
139 0 : }
140 :
141 0 : void GridDataSerializationHandler::
142 : deserialize(BinaryBuffer& in, GridObjectCollection goc)
143 : {
144 0 : for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
145 0 : deserialize(in, goc.begin<Vertex>(lvl), goc.end<Vertex>(lvl));
146 0 : for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
147 0 : deserialize(in, goc.begin<Edge>(lvl), goc.end<Edge>(lvl));
148 0 : for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
149 0 : deserialize(in, goc.begin<Face>(lvl), goc.end<Face>(lvl));
150 0 : for(size_t lvl = 0; lvl < goc.num_levels(); ++lvl)
151 0 : deserialize(in, goc.begin<Volume>(lvl), goc.end<Volume>(lvl));
152 0 : }
153 :
154 : template<class TSerializers>
155 : void GridDataSerializationHandler::
156 : deserialization_starts(TSerializers& serializers)
157 : {
158 0 : for(size_t i = 0; i < serializers.size(); ++i)
159 0 : serializers[i]->deserialization_starts();
160 : }
161 :
162 0 : void GridDataSerializationHandler::
163 : deserialization_starts()
164 : {
165 : deserialization_starts(m_vrtSerializers);
166 : deserialization_starts(m_edgeSerializers);
167 : deserialization_starts(m_faceSerializers);
168 : deserialization_starts(m_volSerializers);
169 : deserialization_starts(m_gridSerializers);
170 0 : }
171 :
172 : template<class TSerializers>
173 : void GridDataSerializationHandler::
174 : deserialization_done(TSerializers& serializers)
175 : {
176 0 : for(size_t i = 0; i < serializers.size(); ++i)
177 0 : serializers[i]->deserialization_done();
178 : }
179 :
180 0 : void GridDataSerializationHandler::
181 : deserialization_done()
182 : {
183 : deserialization_done(m_vrtSerializers);
184 : deserialization_done(m_edgeSerializers);
185 : deserialization_done(m_faceSerializers);
186 : deserialization_done(m_volSerializers);
187 : deserialization_done(m_gridSerializers);
188 0 : }
189 :
190 : ////////////////////////////////////////////////////////////////////////
191 0 : SubsetHandlerSerializer::
192 0 : SubsetHandlerSerializer(ISubsetHandler& sh) :
193 0 : m_sh(sh)
194 : {
195 0 : }
196 :
197 0 : void SubsetHandlerSerializer::
198 : write_info(BinaryBuffer& out) const
199 : {
200 : // serialize the subset infos
201 0 : Serialize(out, m_sh.num_subsets());
202 0 : for(int i = 0; i < m_sh.num_subsets(); ++i){
203 0 : SubsetInfo& si = m_sh.subset_info(i);
204 0 : Serialize(out, si.name);
205 : Serialize(out, si.color);
206 0 : Serialize(out, si.m_propertyMap);
207 : }
208 0 : }
209 :
210 0 : void SubsetHandlerSerializer::
211 : read_info(BinaryBuffer& in)
212 : {
213 : // deserialize the subset infos
214 : int num;
215 : Deserialize(in, num);
216 :
217 0 : for(int i = 0; i < num; ++i){
218 0 : SubsetInfo& si = m_sh.subset_info(i);
219 0 : Deserialize(in, si.name);
220 : Deserialize(in, si.color);
221 0 : Deserialize(in, si.m_propertyMap);
222 : }
223 0 : }
224 :
225 0 : void SubsetHandlerSerializer::
226 : write_data(BinaryBuffer& out, Vertex* o) const
227 : {
228 0 : Serialize(out, m_sh.get_subset_index(o));
229 0 : }
230 :
231 0 : void SubsetHandlerSerializer::
232 : write_data(BinaryBuffer& out, Edge* o) const
233 : {
234 0 : Serialize(out, m_sh.get_subset_index(o));
235 0 : }
236 :
237 0 : void SubsetHandlerSerializer::
238 : write_data(BinaryBuffer& out, Face* o) const
239 : {
240 0 : Serialize(out, m_sh.get_subset_index(o));
241 0 : }
242 :
243 0 : void SubsetHandlerSerializer::
244 : write_data(BinaryBuffer& out, Volume* o) const
245 : {
246 0 : Serialize(out, m_sh.get_subset_index(o));
247 0 : }
248 :
249 0 : void SubsetHandlerSerializer::
250 : read_data(BinaryBuffer& in, Vertex* o)
251 : {
252 : int si;
253 : Deserialize(in, si);
254 0 : m_sh.assign_subset(o, si);
255 0 : }
256 :
257 0 : void SubsetHandlerSerializer::
258 : read_data(BinaryBuffer& in, Edge* o)
259 : {
260 : int si;
261 : Deserialize(in, si);
262 0 : m_sh.assign_subset(o, si);
263 0 : }
264 :
265 0 : void SubsetHandlerSerializer::
266 : read_data(BinaryBuffer& in, Face* o)
267 : {
268 : int si;
269 : Deserialize(in, si);
270 0 : m_sh.assign_subset(o, si);
271 0 : }
272 :
273 0 : void SubsetHandlerSerializer::
274 : read_data(BinaryBuffer& in, Volume* o)
275 : {
276 : int si;
277 : Deserialize(in, si);
278 0 : m_sh.assign_subset(o, si);
279 0 : }
280 :
281 :
282 :
283 : ////////////////////////////////////////////////////////////////////////
284 : // enumerations
285 :
286 : /**
287 : * Don't change the constants, since they are used i.e. in external files too.
288 : * If you want to add constants, do so at the end of the enumeration.
289 : */
290 : enum GridSerializationID
291 : {
292 : GSID_END_OF_GRID = -2,
293 : GSID_INVALID = -1,
294 :
295 : GSID_GEOMETRIC_OBJECT = 0,
296 : GSID_VERTEX_BASE = 10,
297 : GSID_VERTEX = 11,
298 : GSID_HANGING_VERTEX = 12,
299 : GSID_EDGE_BASE = 20,
300 : GSID_EDGE = 21,
301 : GSID_CONSTRAINED_EDGE = 22,
302 : GSID_CONSTRAINING_EDGE = 23,
303 : GSID_FACE = 30,
304 : GSID_TRIANGLE = 31,
305 : GSID_CONSTRAINED_TRIANGLE = 32,
306 : GSID_CONSTRAINING_TRIANGLE = 33,
307 : GSID_QUADRILATERAL = 40,
308 : GSID_CONSTRAINED_QUADRILATERAL = 41,
309 : GSID_CONSTRAINING_QUADRILATERAL = 42,
310 : GSID_VOLUME = 60,
311 : GSID_TETRAHEDRON = 61,
312 : GSID_HEXAHEDRON = 70,
313 : GSID_PRISM = 80,
314 : GSID_PYRAMID = 90,
315 : GSID_OCTAHEDRON = 100,
316 :
317 : GSID_NEW_LEVEL = 1000
318 : };
319 :
320 : ////////////////////////////////////////////////////////////////////////
321 : // GRID HEADER
322 : enum GridHeaderConstants{
323 : GHC_HEADER_BEGIN = 1,
324 : GHC_HEADER_END = 2,
325 : GHC_READ_OPTIONS = 3,
326 : };
327 :
328 : enum GridHeaderReadOptions{
329 : GHRO_READ_DEFAULT = 0,
330 : GHRO_READ_LEVELS = 1 << 0,
331 : GHRO_READ_PARENTS = 1 << 1
332 : };
333 :
334 : struct GridHeader{
335 0 : GridHeader() :
336 0 : m_readOptions(GHRO_READ_DEFAULT) {}
337 0 : GridHeader(uint readOptions) :
338 0 : m_readOptions(readOptions) {}
339 :
340 : bool contains_option(uint option){
341 0 : return (m_readOptions & option) == option;
342 : }
343 :
344 : uint m_readOptions;
345 : };
346 :
347 0 : static void WriteGridHeader(const GridHeader& gridHeader, BinaryBuffer& out)
348 : {
349 : // we use a temporary integer
350 : // the header begins
351 0 : int t = GHC_HEADER_BEGIN;
352 0 : out.write((char*)&t, sizeof(int));
353 :
354 : // we now write the read options
355 0 : t = GHC_READ_OPTIONS;
356 0 : out.write((char*)&t, sizeof(int));
357 0 : out.write((char*)&gridHeader.m_readOptions, sizeof(uint));
358 :
359 : // the header ends
360 0 : t = GHC_HEADER_END;
361 0 : out.write((char*)&t, sizeof(int));
362 0 : }
363 :
364 0 : static bool ReadGridHeader(GridHeader& gridHeader, BinaryBuffer& in)
365 : {
366 : // initialize the header to its defaults
367 0 : gridHeader = GridHeader();
368 :
369 : // make sure that the header begins properly
370 : int t;
371 0 : in.read((char*)&t, sizeof(int));
372 :
373 0 : if(t != GHC_HEADER_BEGIN)
374 : return false;
375 :
376 : bool bHeaderOpen = true;
377 0 : while(!in.eof() && bHeaderOpen){
378 : // read the next symbol
379 0 : in.read((char*)&t, sizeof(int));
380 :
381 0 : switch(t){
382 0 : case GHC_READ_OPTIONS:{
383 : int opt;
384 0 : in.read((char*)&opt, sizeof(uint));
385 0 : gridHeader.m_readOptions = opt;
386 0 : }break;
387 :
388 : case GHC_HEADER_END:
389 : bHeaderOpen = false;
390 : break;
391 : }
392 : }
393 :
394 0 : if(bHeaderOpen){
395 : // the header was not closed properly
396 : return false;
397 : }
398 :
399 : return true;
400 : }
401 :
402 :
403 : ////////////////////////////////////////////////////////////////////////
404 : // PARENT INFO
405 : /// Stores a tuple (type, index), identifying a parent.
406 : typedef std::pair<byte, int> ParentInfo;
407 :
408 : ////////////////////////////////////////////////////////////////////////
409 : ////////////////////////////////////////////////////////////////////////
410 : ////////////////////////////////////////////////////////////////////////
411 : // SerializeGridElements
412 0 : bool SerializeGridElements(Grid& grid, BinaryBuffer& out)
413 : {
414 : // call SerializeGridElements with the grids goc
415 0 : return SerializeGridElements(grid,
416 0 : grid.get_grid_objects(),
417 0 : out);
418 : }
419 :
420 : ////////////////////////////////////////////////////////////////////////
421 : // SerializeGridElements
422 0 : bool SerializeGridElements(Grid& grid, GridObjectCollection goc,
423 : BinaryBuffer& out)
424 : {
425 : // create the required int-attachment and call SerializeGridElements.
426 : AInt aInt;
427 : grid.attach_to_vertices(aInt);
428 0 : bool retVal = SerializeGridElements(grid, goc, aInt, out);
429 : grid.detach_from_vertices(aInt);
430 0 : return retVal;
431 : }
432 :
433 : ////////////////////////////////////////////////////////////////////////
434 : // SerializeGridElements
435 0 : bool SerializeGridElements(Grid& grid, GridObjectCollection goc,
436 : AInt& aIntVRT, BinaryBuffer& out)
437 : {
438 : //TODO: add volume support
439 : assert(grid.has_vertex_attachment(aIntVRT) && "aIntVRT is not attached to the grid");
440 0 : if(!grid.has_vertex_attachment(aIntVRT))
441 : return false;
442 :
443 : Grid::VertexAttachmentAccessor<AInt> aaIntVRT(grid, aIntVRT);
444 :
445 : int tInt;
446 : number tNumber;
447 :
448 : // first we'll write the grid header.
449 : // since we're writing a normal grid, we use the standard header.
450 0 : WriteGridHeader(GridHeader(), out);
451 :
452 : // prepare vertices and set num-vertices and num-hanging-vertices.
453 : {
454 : int vrtInd = 0;
455 :
456 : // init vertex-indices (only for Vertey type. Rest is done later on).
457 : for(RegularVertexIterator iter = goc.begin<RegularVertex>();
458 0 : iter != goc.end<RegularVertex>(); ++iter)
459 : {
460 0 : aaIntVRT[*iter] = vrtInd++;
461 : }
462 :
463 : // write vertices to the stream
464 0 : if(goc.num<RegularVertex>() > 0)
465 : {
466 0 : tInt = GSID_VERTEX;
467 0 : out.write((char*)&tInt, sizeof(int));
468 0 : tInt = (int)goc.num<RegularVertex>();
469 0 : out.write((char*)&tInt, sizeof(int));
470 : }
471 :
472 : // write hanging vertices
473 0 : if(goc.num<ConstrainedVertex>() > 0)
474 : {
475 0 : tInt = GSID_HANGING_VERTEX;
476 0 : out.write((char*)&tInt, sizeof(int));
477 0 : tInt = goc.num<ConstrainedVertex>();
478 0 : out.write((char*)&tInt, sizeof(int));
479 :
480 : // write local-coords and assign indices
481 : // we need a number stream for that
482 : for(ConstrainedVertexIterator iter = goc.begin<ConstrainedVertex>();
483 0 : iter != goc.end<ConstrainedVertex>(); ++iter)
484 : {
485 0 : tNumber = (*iter)->get_local_coordinate_1();
486 0 : out.write((char*)&tNumber, sizeof(number));
487 0 : tNumber = (*iter)->get_local_coordinate_2();
488 0 : out.write((char*)&tNumber, sizeof(number));
489 0 : aaIntVRT[*iter] = vrtInd++;
490 : }
491 : }
492 : }
493 :
494 : // iterate through the edges and set up the edgeStream.
495 : //int EDGE_GOID, int vrtInd1, int vrtInd2, [int numConstrainedVertices, {int constrainedVertexIndex}, int numConstrainedEdges, {int constrainedEdgeIndex}]
496 : {
497 : //int edgeInd = 0;
498 :
499 : // fill the stream
500 : // normal edges first.
501 0 : if(goc.num<RegularEdge>() > 0)
502 : {
503 0 : tInt = GSID_EDGE;
504 0 : out.write((char*)&tInt, sizeof(int));
505 0 : tInt = (int)goc.num<RegularEdge>();
506 0 : out.write((char*)&tInt, sizeof(int));
507 :
508 : for(RegularEdgeIterator iter = goc.begin<RegularEdge>();
509 0 : iter != goc.end<RegularEdge>(); ++iter)
510 : {
511 : RegularEdge* e = *iter;
512 : //edgeInd++;
513 0 : out.write((char*)&aaIntVRT[e->vertex(0)], sizeof(int));
514 0 : out.write((char*)&aaIntVRT[e->vertex(1)], sizeof(int));
515 : }
516 : }
517 :
518 : //TODO: add support for hanging edges.
519 :
520 : }
521 :
522 : // faces
523 : {
524 : //TODO: add support for constrained faces etc...
525 0 : if(goc.num<Triangle>() > 0)
526 : {
527 0 : tInt = GSID_TRIANGLE;
528 0 : out.write((char*)&tInt, sizeof(int));
529 0 : tInt = (int)goc.num<Triangle>();
530 0 : out.write((char*)&tInt, sizeof(int));
531 :
532 : for(TriangleIterator iter = goc.begin<Triangle>();
533 0 : iter != goc.end<Triangle>(); ++iter)
534 : {
535 : Triangle* t = *iter;
536 0 : out.write((char*)&aaIntVRT[t->vertex(0)], sizeof(int));
537 0 : out.write((char*)&aaIntVRT[t->vertex(1)], sizeof(int));
538 0 : out.write((char*)&aaIntVRT[t->vertex(2)], sizeof(int));
539 : }
540 : }
541 :
542 0 : if(goc.num<Quadrilateral>() > 0)
543 : {
544 0 : tInt = GSID_QUADRILATERAL;
545 0 : out.write((char*)&tInt, sizeof(int));
546 0 : tInt = (int)goc.num<Quadrilateral>();
547 0 : out.write((char*)&tInt, sizeof(int));
548 :
549 : for(QuadrilateralIterator iter = goc.begin<Quadrilateral>();
550 0 : iter != goc.end<Quadrilateral>(); ++iter)
551 : {
552 : Quadrilateral* q = *iter;
553 0 : out.write((char*)&aaIntVRT[q->vertex(0)], sizeof(int));
554 0 : out.write((char*)&aaIntVRT[q->vertex(1)], sizeof(int));
555 0 : out.write((char*)&aaIntVRT[q->vertex(2)], sizeof(int));
556 0 : out.write((char*)&aaIntVRT[q->vertex(3)], sizeof(int));
557 : }
558 : }
559 : }
560 :
561 : // volumes
562 : {
563 0 : if(goc.num<Tetrahedron>() > 0)
564 : {
565 0 : tInt = GSID_TETRAHEDRON;
566 0 : out.write((char*)&tInt, sizeof(int));
567 0 : tInt = (int)goc.num<Tetrahedron>();
568 0 : out.write((char*)&tInt, sizeof(int));
569 :
570 : for(TetrahedronIterator iter = goc.begin<Tetrahedron>();
571 0 : iter != goc.end<Tetrahedron>(); ++iter)
572 : {
573 : Tetrahedron* t = *iter;
574 0 : out.write((char*)&aaIntVRT[t->vertex(0)], sizeof(int));
575 0 : out.write((char*)&aaIntVRT[t->vertex(1)], sizeof(int));
576 0 : out.write((char*)&aaIntVRT[t->vertex(2)], sizeof(int));
577 0 : out.write((char*)&aaIntVRT[t->vertex(3)], sizeof(int));
578 : }
579 : }
580 :
581 0 : if(goc.num<Hexahedron>() > 0)
582 : {
583 0 : tInt = GSID_HEXAHEDRON;
584 0 : out.write((char*)&tInt, sizeof(int));
585 0 : tInt = (int)goc.num<Hexahedron>();
586 0 : out.write((char*)&tInt, sizeof(int));
587 :
588 : for(HexahedronIterator iter = goc.begin<Hexahedron>();
589 0 : iter != goc.end<Hexahedron>(); ++iter)
590 : {
591 : Hexahedron* h = *iter;
592 0 : out.write((char*)&aaIntVRT[h->vertex(0)], sizeof(int));
593 0 : out.write((char*)&aaIntVRT[h->vertex(1)], sizeof(int));
594 0 : out.write((char*)&aaIntVRT[h->vertex(2)], sizeof(int));
595 0 : out.write((char*)&aaIntVRT[h->vertex(3)], sizeof(int));
596 0 : out.write((char*)&aaIntVRT[h->vertex(4)], sizeof(int));
597 0 : out.write((char*)&aaIntVRT[h->vertex(5)], sizeof(int));
598 0 : out.write((char*)&aaIntVRT[h->vertex(6)], sizeof(int));
599 0 : out.write((char*)&aaIntVRT[h->vertex(7)], sizeof(int));
600 : }
601 : }
602 :
603 0 : if(goc.num<Prism>() > 0)
604 : {
605 0 : tInt = GSID_PRISM;
606 0 : out.write((char*)&tInt, sizeof(int));
607 0 : tInt = (int)goc.num<Prism>();
608 0 : out.write((char*)&tInt, sizeof(int));
609 :
610 : for(PrismIterator iter = goc.begin<Prism>();
611 0 : iter != goc.end<Prism>(); ++iter)
612 : {
613 : Prism* p = *iter;
614 0 : out.write((char*)&aaIntVRT[p->vertex(0)], sizeof(int));
615 0 : out.write((char*)&aaIntVRT[p->vertex(1)], sizeof(int));
616 0 : out.write((char*)&aaIntVRT[p->vertex(2)], sizeof(int));
617 0 : out.write((char*)&aaIntVRT[p->vertex(3)], sizeof(int));
618 0 : out.write((char*)&aaIntVRT[p->vertex(4)], sizeof(int));
619 0 : out.write((char*)&aaIntVRT[p->vertex(5)], sizeof(int));
620 : }
621 : }
622 :
623 0 : if(goc.num<Pyramid>() > 0)
624 : {
625 0 : tInt = GSID_PYRAMID;
626 0 : out.write((char*)&tInt, sizeof(int));
627 0 : tInt = (int)goc.num<Pyramid>();
628 0 : out.write((char*)&tInt, sizeof(int));
629 :
630 : for(PyramidIterator iter = goc.begin<Pyramid>();
631 0 : iter != goc.end<Pyramid>(); ++iter)
632 : {
633 : Pyramid* p = *iter;
634 0 : out.write((char*)&aaIntVRT[p->vertex(0)], sizeof(int));
635 0 : out.write((char*)&aaIntVRT[p->vertex(1)], sizeof(int));
636 0 : out.write((char*)&aaIntVRT[p->vertex(2)], sizeof(int));
637 0 : out.write((char*)&aaIntVRT[p->vertex(3)], sizeof(int));
638 0 : out.write((char*)&aaIntVRT[p->vertex(4)], sizeof(int));
639 : }
640 : }
641 : }
642 :
643 : // mark the end of the grid-section
644 0 : tInt = GSID_END_OF_GRID;
645 0 : out.write((char*)&tInt, sizeof(int));
646 :
647 : return true;
648 : }
649 :
650 : ////////////////////////////////////////////////////////////////////////
651 : // DeserializeGridElements
652 0 : bool DeserializeGridElements(Grid& grid, BinaryBuffer& in,
653 : bool readGridHeader)
654 : {
655 : //TODO: add volume support
656 : vector<Vertex*> vVrts;
657 : vector<Edge*> vEdges;
658 : vector<Face*> vFaces;
659 :
660 : GridHeader gridHeader;
661 0 : if(readGridHeader){
662 0 : if(!ReadGridHeader(gridHeader, in)){
663 : UG_LOG("Invalid GridHeader.");
664 : return false;
665 : }
666 : }
667 :
668 0 : if(gridHeader.contains_option(GHRO_READ_LEVELS)){
669 : UG_LOG("ERROR in DeserializeGridElements: READ_LEVELS not supported for flat grids.");
670 : return false;
671 : }
672 0 : if(gridHeader.contains_option(GHRO_READ_PARENTS)){
673 : UG_LOG("ERROR in DeserializeGridElements: READ_PARENTS not supported for flat grids.");
674 : return false;
675 : }
676 :
677 : // create the vertices and store them in vVrts for later indexing.
678 : {
679 : // iterate through the stream and create vertices
680 0 : while(!in.eof())
681 : {
682 : // read the goid
683 0 : int goid = 0;
684 0 : in.read((char*)&goid, sizeof(int));
685 :
686 : // check whether we reached the end of the grid-description.
687 0 : if(goid == GSID_END_OF_GRID)
688 : break;
689 :
690 : // we have to read more elements. check how many.
691 0 : int numElems = 0;
692 0 : in.read((char*)&numElems, sizeof(int));
693 :
694 : // depending on the goid we'll create new elements.
695 0 : switch(goid)
696 : {
697 : case GSID_VERTEX:
698 : {
699 0 : for(int i = 0; i < numElems; ++i)
700 0 : vVrts.push_back(*grid.create<RegularVertex>());
701 : }break;
702 :
703 : case GSID_HANGING_VERTEX:
704 : {
705 : // create the hanging vertices and assign the local coordinates
706 0 : for(int i = 0; i < numElems; ++i)
707 : {
708 0 : ConstrainedVertex* hv = *grid.create<ConstrainedVertex>();
709 : number coord1, coord2;
710 0 : in.read((char*)&coord1, sizeof(number));
711 0 : in.read((char*)&coord2, sizeof(number));
712 0 : hv->set_local_coordinate_1(coord1);
713 0 : hv->set_local_coordinate_2(coord2);
714 0 : vVrts.push_back(hv);
715 : }
716 : }break;
717 : case GSID_EDGE:
718 : {
719 0 : for(int i = 0; i < numElems; ++i)
720 : {
721 : int i1, i2;
722 0 : in.read((char*)&i1, sizeof(int));
723 0 : in.read((char*)&i2, sizeof(int));
724 :
725 0 : RegularEdge* e = *grid.create<RegularEdge>(EdgeDescriptor(vVrts[i1], vVrts[i2]));
726 0 : vEdges.push_back(e);
727 : }
728 : }break;
729 : case GSID_TRIANGLE:
730 : {
731 0 : for(int i = 0; i < numElems; ++i)
732 : {
733 : int i1, i2, i3;
734 0 : in.read((char*)&i1, sizeof(int));
735 0 : in.read((char*)&i2, sizeof(int));
736 0 : in.read((char*)&i3, sizeof(int));
737 :
738 0 : Triangle* t = *grid.create<Triangle>(TriangleDescriptor(
739 0 : vVrts[i1],
740 0 : vVrts[i2],
741 0 : vVrts[i3]));
742 0 : vFaces.push_back(t);
743 : }
744 : }break;
745 : case GSID_QUADRILATERAL:
746 : {
747 0 : for(int i = 0; i < numElems; ++i)
748 : {
749 : int i1, i2, i3, i4;
750 0 : in.read((char*)&i1, sizeof(int));
751 0 : in.read((char*)&i2, sizeof(int));
752 0 : in.read((char*)&i3, sizeof(int));
753 0 : in.read((char*)&i4, sizeof(int));
754 :
755 0 : Quadrilateral* q = *grid.create<Quadrilateral>(QuadrilateralDescriptor(
756 0 : vVrts[i1],
757 0 : vVrts[i2],
758 0 : vVrts[i3],
759 0 : vVrts[i4]));
760 0 : vFaces.push_back(q);
761 : }
762 : }break;
763 : case GSID_TETRAHEDRON:
764 : {
765 0 : for(int i = 0; i < numElems; ++i)
766 : {
767 : int i1, i2, i3, i4;
768 0 : in.read((char*)&i1, sizeof(int));
769 0 : in.read((char*)&i2, sizeof(int));
770 0 : in.read((char*)&i3, sizeof(int));
771 0 : in.read((char*)&i4, sizeof(int));
772 :
773 0 : grid.create<Tetrahedron>(TetrahedronDescriptor(
774 0 : vVrts[i1], vVrts[i2],
775 0 : vVrts[i3], vVrts[i4]));
776 : }
777 : }break;
778 : case GSID_HEXAHEDRON:
779 : {
780 0 : for(int i = 0; i < numElems; ++i)
781 : {
782 : int i1, i2, i3, i4, i5, i6, i7, i8;
783 0 : in.read((char*)&i1, sizeof(int));
784 0 : in.read((char*)&i2, sizeof(int));
785 0 : in.read((char*)&i3, sizeof(int));
786 0 : in.read((char*)&i4, sizeof(int));
787 0 : in.read((char*)&i5, sizeof(int));
788 0 : in.read((char*)&i6, sizeof(int));
789 0 : in.read((char*)&i7, sizeof(int));
790 0 : in.read((char*)&i8, sizeof(int));
791 :
792 0 : grid.create<Hexahedron>(HexahedronDescriptor(
793 0 : vVrts[i1], vVrts[i2],
794 0 : vVrts[i3], vVrts[i4],
795 0 : vVrts[i5], vVrts[i6],
796 0 : vVrts[i7], vVrts[i8]));
797 : }
798 : }break;
799 : case GSID_PRISM:
800 : {
801 0 : for(int i = 0; i < numElems; ++i)
802 : {
803 : int i1, i2, i3, i4, i5, i6;
804 0 : in.read((char*)&i1, sizeof(int));
805 0 : in.read((char*)&i2, sizeof(int));
806 0 : in.read((char*)&i3, sizeof(int));
807 0 : in.read((char*)&i4, sizeof(int));
808 0 : in.read((char*)&i5, sizeof(int));
809 0 : in.read((char*)&i6, sizeof(int));
810 :
811 0 : grid.create<Prism>(PrismDescriptor(
812 0 : vVrts[i1], vVrts[i2],
813 0 : vVrts[i3], vVrts[i4],
814 0 : vVrts[i5], vVrts[i6]));
815 : }
816 : }break;
817 : case GSID_PYRAMID:
818 : {
819 0 : for(int i = 0; i < numElems; ++i)
820 : {
821 : int i1, i2, i3, i4, i5;
822 0 : in.read((char*)&i1, sizeof(int));
823 0 : in.read((char*)&i2, sizeof(int));
824 0 : in.read((char*)&i3, sizeof(int));
825 0 : in.read((char*)&i4, sizeof(int));
826 0 : in.read((char*)&i5, sizeof(int));
827 :
828 0 : grid.create<Pyramid>(PyramidDescriptor(
829 0 : vVrts[i1], vVrts[i2],
830 0 : vVrts[i3], vVrts[i4],
831 0 : vVrts[i5]));
832 : }
833 : }break;
834 : default:
835 : LOG("Unknown geometric-object-id in grid-pack. Aborting reconstruction.\n");
836 0 : return false;
837 : }
838 : }
839 : }
840 :
841 : return true;
842 0 : }
843 :
844 :
845 :
846 : ////////////////////////////////////////////////////////////////////////
847 : // writes the parent of the given element - with type and index
848 : // This method relies on the fact, that mg is in marking mode and
849 : // that all and only parents which have already been written to
850 : // the stream are marked.
851 : template<class TElem>
852 0 : static void WriteParent(MultiGrid& mg, TElem* pElem,
853 : MultiElementAttachmentAccessor<AInt>& aaInt,
854 : BinaryBuffer& out)
855 : {
856 : GridObject* pParent = mg.get_parent(pElem);
857 0 : char type = mg.parent_type(pElem);
858 0 : int index = -1;
859 :
860 0 : if(pParent && mg.is_marked(pParent)){
861 : UG_ASSERT(pParent->base_object_id() == type,
862 : "parent->base_object_id() and MultiGrid::parent_type mismatch!");
863 0 : index = aaInt[pParent];
864 : }
865 :
866 0 : out.write((char*)&type, sizeof(char));
867 0 : out.write((char*)&index, sizeof(int));
868 :
869 0 : }
870 :
871 :
872 : ////////////////////////////////////////////////////////////////////////
873 0 : bool SerializeMultiGridElements(MultiGrid& mg,
874 : GridObjectCollection mgoc,
875 : MultiElementAttachmentAccessor<AInt>& aaInt,
876 : BinaryBuffer& out,
877 : MultiElementAttachmentAccessor<AGeomObjID>* paaID)
878 : {
879 : // NOTE: SERIALIZATION HAS TO MATCH THE ORDER OF CONTAINER SECTIONS AS DEFINED IN
880 : // grid_objects_0d.h, grid_objects_1d.h, grid_objects_2d.h, grid_objects_3d.h
881 :
882 : SRLZ_PROFILE_FUNC();
883 :
884 : int tInt;
885 : number tNumber;
886 :
887 : // first we'll write the header. we have to enable level- and parent-reads
888 0 : WriteGridHeader(GridHeader(GHRO_READ_LEVELS | GHRO_READ_PARENTS), out);
889 :
890 : // iterate through the different levels
891 0 : uint numLevels = mgoc.num_levels();
892 : int vrtInd = 0;
893 : int edgeInd = 0;
894 : int faceInd = 0;
895 : int volInd = 0;
896 :
897 : // we have to mark all elements which were already written
898 0 : mg.begin_marking();
899 :
900 : ////////////////////////////////
901 : // vertices
902 0 : for(uint iLevel = 0; iLevel < numLevels; ++iLevel)
903 : {
904 : // write the level
905 0 : tInt = GSID_NEW_LEVEL;
906 0 : out.write((char*)&tInt, sizeof(int));
907 0 : out.write((char*)&iLevel, sizeof(uint));
908 :
909 : // prepare vertices and set num-vertices and num-hanging-vertices.
910 : // write vertices
911 0 : if(mgoc.num<RegularVertex>(iLevel) > 0)
912 : {
913 0 : tInt = GSID_VERTEX;
914 0 : out.write((char*)&tInt, sizeof(int));
915 0 : tInt = (int)mgoc.num<RegularVertex>(iLevel);
916 0 : out.write((char*)&tInt, sizeof(int));
917 :
918 0 : for(RegularVertexIterator iter = mgoc.begin<RegularVertex>(iLevel);
919 0 : iter != mgoc.end<RegularVertex>(iLevel); ++iter)
920 : {
921 0 : aaInt[*iter] = vrtInd++;
922 : mg.mark(*iter);
923 0 : WriteParent(mg, *iter, aaInt, out);
924 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
925 : }
926 : }
927 :
928 : // write hanging vertices
929 0 : if(mgoc.num<ConstrainedVertex>(iLevel) > 0)
930 : {
931 0 : tInt = GSID_HANGING_VERTEX;
932 0 : out.write((char*)&tInt, sizeof(int));
933 0 : tInt = mgoc.num<ConstrainedVertex>(iLevel);
934 0 : out.write((char*)&tInt, sizeof(int));
935 :
936 : // write local-coords and assign indices
937 : // we need a number stream for that
938 0 : for(ConstrainedVertexIterator iter = mgoc.begin<ConstrainedVertex>(iLevel);
939 0 : iter != mgoc.end<ConstrainedVertex>(iLevel); ++iter)
940 : {
941 : ConstrainedVertex* v = *iter;
942 : mg.mark(v);
943 0 : tNumber = v->get_local_coordinate_1();
944 0 : out.write((char*)&tNumber, sizeof(number));
945 0 : tNumber = v->get_local_coordinate_2();
946 0 : out.write((char*)&tNumber, sizeof(number));
947 0 : aaInt[v] = vrtInd++;
948 :
949 : // write constraining object
950 0 : int type = -1;
951 0 : int ind = -1;
952 0 : if(GridObject* cobj = v->get_constraining_object()){
953 0 : type = cobj->base_object_id();
954 0 : if(mg.is_marked(cobj)){
955 0 : switch(type){
956 : case EDGE:
957 0 : ind = aaInt[static_cast<Edge*>(cobj)];
958 0 : break;
959 : case FACE:
960 0 : ind = aaInt[static_cast<Face*>(cobj)];
961 0 : break;
962 : }
963 : }
964 : }
965 :
966 0 : out.write((char*)&type, sizeof(int));
967 0 : out.write((char*)&ind, sizeof(int));
968 0 : tInt = v->get_parent_base_object_id();
969 0 : out.write((char*)&tInt, sizeof(int));
970 :
971 : UG_ASSERT(v->get_parent_base_object_id() != -1,
972 : "Bad constraining element id in constrained vertex encountered:"
973 : << ElementDebugInfo(mg, v));
974 :
975 0 : WriteParent(mg, v, aaInt, out);
976 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
977 : }
978 : }
979 :
980 : ////////////////////////////////
981 : // iterate through the edges and set up the edgeStream.
982 : //int EDGE_GOID, int vrtInd1, int vrtInd2, [int numConstrainedVertices, {int constrainedVertexIndex}, int numConstrainedEdges, {int constrainedEdgeIndex}]
983 :
984 : // fill the stream
985 : // normal edges first.
986 0 : if(mgoc.num<RegularEdge>(iLevel) > 0)
987 : {
988 0 : tInt = GSID_EDGE;
989 0 : out.write((char*)&tInt, sizeof(int));
990 0 : tInt = (int)mgoc.num<RegularEdge>(iLevel);
991 0 : out.write((char*)&tInt, sizeof(int));
992 :
993 0 : for(RegularEdgeIterator iter = mgoc.begin<RegularEdge>(iLevel);
994 0 : iter != mgoc.end<RegularEdge>(iLevel); ++iter)
995 : {
996 : RegularEdge* e = *iter;
997 : mg.mark(e);
998 0 : out.write((char*)&aaInt[e->vertex(0)], sizeof(int));
999 0 : out.write((char*)&aaInt[e->vertex(1)], sizeof(int));
1000 0 : aaInt[*iter] = edgeInd++;
1001 0 : WriteParent(mg, e, aaInt, out);
1002 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1003 : }
1004 : }
1005 :
1006 : // now constrained edges
1007 0 : if(mgoc.num<ConstrainedEdge>(iLevel) > 0)
1008 : {
1009 0 : tInt = GSID_CONSTRAINED_EDGE;
1010 0 : out.write((char*)&tInt, sizeof(int));
1011 0 : tInt = (int)mgoc.num<ConstrainedEdge>(iLevel);
1012 0 : out.write((char*)&tInt, sizeof(int));
1013 :
1014 0 : for(ConstrainedEdgeIterator iter = mgoc.begin<ConstrainedEdge>(iLevel);
1015 0 : iter != mgoc.end<ConstrainedEdge>(iLevel); ++iter)
1016 : {
1017 : ConstrainedEdge* e = *iter;
1018 : mg.mark(e);
1019 0 : out.write((char*)&aaInt[e->vertex(0)], sizeof(int));
1020 0 : out.write((char*)&aaInt[e->vertex(1)], sizeof(int));
1021 0 : aaInt[*iter] = edgeInd++;
1022 :
1023 : // write constraining object
1024 0 : int type = -1;
1025 0 : int ind = -1;
1026 0 : if(GridObject* cobj = e->get_constraining_object()){
1027 0 : if(mg.is_marked(cobj)){
1028 0 : type = cobj->base_object_id();
1029 0 : switch(type){
1030 : case EDGE:
1031 0 : ind = aaInt[static_cast<Edge*>(cobj)];
1032 0 : break;
1033 : case FACE:
1034 0 : ind = aaInt[static_cast<Face*>(cobj)];
1035 0 : break;
1036 : }
1037 : }
1038 : }
1039 :
1040 0 : out.write((char*)&type, sizeof(int));
1041 0 : out.write((char*)&ind, sizeof(int));
1042 0 : tInt = e->get_parent_base_object_id();
1043 0 : out.write((char*)&tInt, sizeof(int));
1044 :
1045 0 : WriteParent(mg, e, aaInt, out);
1046 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1047 : }
1048 : }
1049 :
1050 : // now constraining edges
1051 0 : if(mgoc.num<ConstrainingEdge>(iLevel) > 0)
1052 : {
1053 0 : tInt = GSID_CONSTRAINING_EDGE;
1054 0 : out.write((char*)&tInt, sizeof(int));
1055 0 : tInt = (int)mgoc.num<ConstrainingEdge>(iLevel);
1056 0 : out.write((char*)&tInt, sizeof(int));
1057 :
1058 0 : for(ConstrainingEdgeIterator iter = mgoc.begin<ConstrainingEdge>(iLevel);
1059 0 : iter != mgoc.end<ConstrainingEdge>(iLevel); ++iter)
1060 : {
1061 : ConstrainingEdge* e = *iter;
1062 : mg.mark(e);
1063 0 : out.write((char*)&aaInt[e->vertex(0)], sizeof(int));
1064 0 : out.write((char*)&aaInt[e->vertex(1)], sizeof(int));
1065 0 : aaInt[*iter] = edgeInd++;
1066 0 : WriteParent(mg, e, aaInt, out);
1067 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1068 : }
1069 : }
1070 :
1071 : ////////////////////////////////
1072 : // faces
1073 0 : if(mgoc.num<Triangle>(iLevel) > 0)
1074 : {
1075 0 : tInt = GSID_TRIANGLE;
1076 0 : out.write((char*)&tInt, sizeof(int));
1077 0 : tInt = (int)mgoc.num<Triangle>(iLevel);
1078 0 : out.write((char*)&tInt, sizeof(int));
1079 :
1080 0 : for(TriangleIterator iter = mgoc.begin<Triangle>(iLevel);
1081 0 : iter != mgoc.end<Triangle>(iLevel); ++iter)
1082 : {
1083 : Triangle* t = *iter;
1084 : mg.mark(t);
1085 0 : out.write((char*)&aaInt[t->vertex(0)], sizeof(int));
1086 0 : out.write((char*)&aaInt[t->vertex(1)], sizeof(int));
1087 0 : out.write((char*)&aaInt[t->vertex(2)], sizeof(int));
1088 0 : aaInt[*iter] = faceInd++;
1089 0 : WriteParent(mg, t, aaInt, out);
1090 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1091 : }
1092 : }
1093 :
1094 0 : if(mgoc.num<Quadrilateral>(iLevel) > 0)
1095 : {
1096 0 : tInt = GSID_QUADRILATERAL;
1097 0 : out.write((char*)&tInt, sizeof(int));
1098 0 : tInt = (int)mgoc.num<Quadrilateral>(iLevel);
1099 0 : out.write((char*)&tInt, sizeof(int));
1100 :
1101 0 : for(QuadrilateralIterator iter = mgoc.begin<Quadrilateral>(iLevel);
1102 0 : iter != mgoc.end<Quadrilateral>(iLevel); ++iter)
1103 : {
1104 : Quadrilateral* q = *iter;
1105 : mg.mark(q);
1106 0 : out.write((char*)&aaInt[q->vertex(0)], sizeof(int));
1107 0 : out.write((char*)&aaInt[q->vertex(1)], sizeof(int));
1108 0 : out.write((char*)&aaInt[q->vertex(2)], sizeof(int));
1109 0 : out.write((char*)&aaInt[q->vertex(3)], sizeof(int));
1110 0 : aaInt[*iter] = faceInd++;
1111 0 : WriteParent(mg, q, aaInt, out);
1112 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1113 : }
1114 : }
1115 :
1116 0 : if(mgoc.num<ConstrainedTriangle>(iLevel) > 0)
1117 : {
1118 0 : tInt = GSID_CONSTRAINED_TRIANGLE;
1119 0 : out.write((char*)&tInt, sizeof(int));
1120 0 : tInt = (int)mgoc.num<ConstrainedTriangle>(iLevel);
1121 0 : out.write((char*)&tInt, sizeof(int));
1122 :
1123 0 : for(ConstrainedTriangleIterator iter = mgoc.begin<ConstrainedTriangle>(iLevel);
1124 0 : iter != mgoc.end<ConstrainedTriangle>(iLevel); ++iter)
1125 : {
1126 : ConstrainedTriangle* e = *iter;
1127 : mg.mark(e);
1128 0 : out.write((char*)&aaInt[e->vertex(0)], sizeof(int));
1129 0 : out.write((char*)&aaInt[e->vertex(1)], sizeof(int));
1130 0 : out.write((char*)&aaInt[e->vertex(2)], sizeof(int));
1131 0 : aaInt[e] = faceInd++;
1132 :
1133 : // write constraining object
1134 0 : int ind = -1;
1135 0 : if(GridObject* cobj = e->get_constraining_object()){
1136 0 : if(mg.is_marked(cobj)){
1137 : UG_ASSERT(cobj->base_object_id() == FACE,
1138 : "A constrained face can only be constrained by "
1139 : "a constraining face!");
1140 0 : if(cobj->base_object_id() == FACE)
1141 0 : ind = aaInt[static_cast<Face*>(cobj)];
1142 : }
1143 : }
1144 :
1145 0 : out.write((char*)&ind, sizeof(int));
1146 0 : tInt = e->get_parent_base_object_id();
1147 0 : out.write((char*)&tInt, sizeof(int));
1148 :
1149 0 : WriteParent(mg, e, aaInt, out);
1150 0 : if(paaID) Serialize(out, (*paaID)[e]);
1151 : }
1152 : }
1153 :
1154 0 : if(mgoc.num<ConstrainedQuadrilateral>(iLevel) > 0)
1155 : {
1156 0 : tInt = GSID_CONSTRAINED_QUADRILATERAL;
1157 0 : out.write((char*)&tInt, sizeof(int));
1158 0 : tInt = (int)mgoc.num<ConstrainedQuadrilateral>(iLevel);
1159 0 : out.write((char*)&tInt, sizeof(int));
1160 :
1161 0 : for(ConstrainedQuadrilateralIterator iter = mgoc.begin<ConstrainedQuadrilateral>(iLevel);
1162 0 : iter != mgoc.end<ConstrainedQuadrilateral>(iLevel); ++iter)
1163 : {
1164 : ConstrainedQuadrilateral* e = *iter;
1165 : mg.mark(e);
1166 0 : out.write((char*)&aaInt[e->vertex(0)], sizeof(int));
1167 0 : out.write((char*)&aaInt[e->vertex(1)], sizeof(int));
1168 0 : out.write((char*)&aaInt[e->vertex(2)], sizeof(int));
1169 0 : out.write((char*)&aaInt[e->vertex(3)], sizeof(int));
1170 0 : aaInt[e] = faceInd++;
1171 :
1172 : // write constraining object
1173 0 : int ind = -1;
1174 0 : if(GridObject* cobj = e->get_constraining_object()){
1175 0 : if(mg.is_marked(cobj)){
1176 : UG_ASSERT(cobj->base_object_id() == FACE,
1177 : "A constrained face can only be constrained by "
1178 : "a constraining face!");
1179 0 : if(cobj->base_object_id() == FACE)
1180 0 : ind = aaInt[static_cast<Face*>(cobj)];
1181 : }
1182 : }
1183 :
1184 0 : out.write((char*)&ind, sizeof(int));
1185 0 : tInt = e->get_parent_base_object_id();
1186 0 : out.write((char*)&tInt, sizeof(int));
1187 :
1188 0 : WriteParent(mg, e, aaInt, out);
1189 0 : if(paaID) Serialize(out, (*paaID)[e]);
1190 : }
1191 : }
1192 :
1193 0 : if(mgoc.num<ConstrainingTriangle>(iLevel) > 0)
1194 : {
1195 0 : tInt = GSID_CONSTRAINING_TRIANGLE;
1196 0 : out.write((char*)&tInt, sizeof(int));
1197 0 : tInt = (int)mgoc.num<ConstrainingTriangle>(iLevel);
1198 0 : out.write((char*)&tInt, sizeof(int));
1199 :
1200 0 : for(ConstrainingTriangleIterator iter = mgoc.begin<ConstrainingTriangle>(iLevel);
1201 0 : iter != mgoc.end<ConstrainingTriangle>(iLevel); ++iter)
1202 : {
1203 : ConstrainingTriangle* e = *iter;
1204 : mg.mark(e);
1205 0 : out.write((char*)&aaInt[e->vertex(0)], sizeof(int));
1206 0 : out.write((char*)&aaInt[e->vertex(1)], sizeof(int));
1207 0 : out.write((char*)&aaInt[e->vertex(2)], sizeof(int));
1208 0 : aaInt[e] = faceInd++;
1209 0 : WriteParent(mg, e, aaInt, out);
1210 0 : if(paaID) Serialize(out, (*paaID)[e]);
1211 : }
1212 : }
1213 :
1214 0 : if(mgoc.num<ConstrainingQuadrilateral>(iLevel) > 0)
1215 : {
1216 0 : tInt = GSID_CONSTRAINING_QUADRILATERAL;
1217 0 : out.write((char*)&tInt, sizeof(int));
1218 0 : tInt = (int)mgoc.num<ConstrainingQuadrilateral>(iLevel);
1219 0 : out.write((char*)&tInt, sizeof(int));
1220 :
1221 0 : for(ConstrainingQuadrilateralIterator iter = mgoc.begin<ConstrainingQuadrilateral>(iLevel);
1222 0 : iter != mgoc.end<ConstrainingQuadrilateral>(iLevel); ++iter)
1223 : {
1224 : ConstrainingQuadrilateral* e = *iter;
1225 : mg.mark(e);
1226 0 : out.write((char*)&aaInt[e->vertex(0)], sizeof(int));
1227 0 : out.write((char*)&aaInt[e->vertex(1)], sizeof(int));
1228 0 : out.write((char*)&aaInt[e->vertex(2)], sizeof(int));
1229 0 : out.write((char*)&aaInt[e->vertex(3)], sizeof(int));
1230 0 : aaInt[e] = faceInd++;
1231 0 : WriteParent(mg, e, aaInt, out);
1232 0 : if(paaID) Serialize(out, (*paaID)[e]);
1233 : }
1234 : }
1235 :
1236 : ////////////////////////////////
1237 : // volumes
1238 0 : if(mgoc.num<Tetrahedron>(iLevel) > 0)
1239 : {
1240 0 : tInt = GSID_TETRAHEDRON;
1241 0 : out.write((char*)&tInt, sizeof(int));
1242 0 : tInt = (int)mgoc.num<Tetrahedron>(iLevel);
1243 0 : out.write((char*)&tInt, sizeof(int));
1244 :
1245 0 : for(TetrahedronIterator iter = mgoc.begin<Tetrahedron>(iLevel);
1246 0 : iter != mgoc.end<Tetrahedron>(iLevel); ++iter)
1247 : {
1248 : Tetrahedron* t = *iter;
1249 : mg.mark(t);
1250 0 : out.write((char*)&aaInt[t->vertex(0)], sizeof(int));
1251 0 : out.write((char*)&aaInt[t->vertex(1)], sizeof(int));
1252 0 : out.write((char*)&aaInt[t->vertex(2)], sizeof(int));
1253 0 : out.write((char*)&aaInt[t->vertex(3)], sizeof(int));
1254 0 : aaInt[*iter] = volInd++;
1255 0 : WriteParent(mg, t, aaInt, out);
1256 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1257 : }
1258 : }
1259 :
1260 0 : if(mgoc.num<Hexahedron>(iLevel) > 0)
1261 : {
1262 0 : tInt = GSID_HEXAHEDRON;
1263 0 : out.write((char*)&tInt, sizeof(int));
1264 0 : tInt = (int)mgoc.num<Hexahedron>(iLevel);
1265 0 : out.write((char*)&tInt, sizeof(int));
1266 :
1267 0 : for(HexahedronIterator iter = mgoc.begin<Hexahedron>(iLevel);
1268 0 : iter != mgoc.end<Hexahedron>(iLevel); ++iter)
1269 : {
1270 : Hexahedron* h = *iter;
1271 : mg.mark(h);
1272 0 : out.write((char*)&aaInt[h->vertex(0)], sizeof(int));
1273 0 : out.write((char*)&aaInt[h->vertex(1)], sizeof(int));
1274 0 : out.write((char*)&aaInt[h->vertex(2)], sizeof(int));
1275 0 : out.write((char*)&aaInt[h->vertex(3)], sizeof(int));
1276 0 : out.write((char*)&aaInt[h->vertex(4)], sizeof(int));
1277 0 : out.write((char*)&aaInt[h->vertex(5)], sizeof(int));
1278 0 : out.write((char*)&aaInt[h->vertex(6)], sizeof(int));
1279 0 : out.write((char*)&aaInt[h->vertex(7)], sizeof(int));
1280 0 : aaInt[*iter] = volInd++;
1281 0 : WriteParent(mg, h, aaInt, out);
1282 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1283 : }
1284 : }
1285 :
1286 0 : if(mgoc.num<Prism>(iLevel) > 0)
1287 : {
1288 0 : tInt = GSID_PRISM;
1289 0 : out.write((char*)&tInt, sizeof(int));
1290 0 : tInt = (int)mgoc.num<Prism>(iLevel);
1291 0 : out.write((char*)&tInt, sizeof(int));
1292 :
1293 0 : for(PrismIterator iter = mgoc.begin<Prism>(iLevel);
1294 0 : iter != mgoc.end<Prism>(iLevel); ++iter)
1295 : {
1296 : Prism* p = *iter;
1297 : mg.mark(p);
1298 0 : out.write((char*)&aaInt[p->vertex(0)], sizeof(int));
1299 0 : out.write((char*)&aaInt[p->vertex(1)], sizeof(int));
1300 0 : out.write((char*)&aaInt[p->vertex(2)], sizeof(int));
1301 0 : out.write((char*)&aaInt[p->vertex(3)], sizeof(int));
1302 0 : out.write((char*)&aaInt[p->vertex(4)], sizeof(int));
1303 0 : out.write((char*)&aaInt[p->vertex(5)], sizeof(int));
1304 0 : aaInt[*iter] = volInd++;
1305 0 : WriteParent(mg, p, aaInt, out);
1306 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1307 : }
1308 : }
1309 :
1310 0 : if(mgoc.num<Pyramid>(iLevel) > 0)
1311 : {
1312 0 : tInt = GSID_PYRAMID;
1313 0 : out.write((char*)&tInt, sizeof(int));
1314 0 : tInt = (int)mgoc.num<Pyramid>(iLevel);
1315 0 : out.write((char*)&tInt, sizeof(int));
1316 :
1317 0 : for(PyramidIterator iter = mgoc.begin<Pyramid>(iLevel);
1318 0 : iter != mgoc.end<Pyramid>(iLevel); ++iter)
1319 : {
1320 : Pyramid* p = *iter;
1321 : mg.mark(p);
1322 0 : out.write((char*)&aaInt[p->vertex(0)], sizeof(int));
1323 0 : out.write((char*)&aaInt[p->vertex(1)], sizeof(int));
1324 0 : out.write((char*)&aaInt[p->vertex(2)], sizeof(int));
1325 0 : out.write((char*)&aaInt[p->vertex(3)], sizeof(int));
1326 0 : out.write((char*)&aaInt[p->vertex(4)], sizeof(int));
1327 0 : aaInt[*iter] = volInd++;
1328 0 : WriteParent(mg, p, aaInt, out);
1329 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1330 : }
1331 : }
1332 :
1333 0 : if(mgoc.num<Octahedron>(iLevel) > 0)
1334 : {
1335 0 : tInt = GSID_OCTAHEDRON;
1336 0 : out.write((char*)&tInt, sizeof(int));
1337 0 : tInt = (int)mgoc.num<Octahedron>(iLevel);
1338 0 : out.write((char*)&tInt, sizeof(int));
1339 :
1340 0 : for(OctahedronIterator iter = mgoc.begin<Octahedron>(iLevel);
1341 0 : iter != mgoc.end<Octahedron>(iLevel); ++iter)
1342 : {
1343 : Octahedron* p = *iter;
1344 : mg.mark(p);
1345 0 : out.write((char*)&aaInt[p->vertex(0)], sizeof(int));
1346 0 : out.write((char*)&aaInt[p->vertex(1)], sizeof(int));
1347 0 : out.write((char*)&aaInt[p->vertex(2)], sizeof(int));
1348 0 : out.write((char*)&aaInt[p->vertex(3)], sizeof(int));
1349 0 : out.write((char*)&aaInt[p->vertex(4)], sizeof(int));
1350 0 : out.write((char*)&aaInt[p->vertex(5)], sizeof(int));
1351 0 : aaInt[*iter] = volInd++;
1352 0 : WriteParent(mg, p, aaInt, out);
1353 0 : if(paaID) Serialize(out, (*paaID)[*iter]);
1354 : }
1355 : }
1356 : }
1357 :
1358 0 : mg.end_marking();
1359 :
1360 : // mark the end of the grid-section
1361 0 : tInt = GSID_END_OF_GRID;
1362 0 : out.write((char*)&tInt, sizeof(int));
1363 :
1364 0 : return true;
1365 : }
1366 :
1367 : ////////////////////////////////////////////////////////////////////////
1368 : // SerializeMultiGridElements
1369 0 : bool SerializeMultiGridElements(MultiGrid& mg,
1370 : GridObjectCollection goc,
1371 : BinaryBuffer& out)
1372 : {
1373 : AInt aInt;
1374 0 : mg.attach_to_all(aInt);
1375 : MultiElementAttachmentAccessor<AInt> aaInt(mg, aInt);
1376 :
1377 0 : bool retVal = SerializeMultiGridElements(mg, goc, aaInt, out);
1378 :
1379 0 : mg.detach_from_all(aInt);
1380 0 : return retVal;
1381 : }
1382 :
1383 : ////////////////////////////////////////////////////////////////////////
1384 : // SerializeMultiGridElements
1385 0 : bool SerializeMultiGridElements(MultiGrid& mg,
1386 : BinaryBuffer& out)
1387 : {
1388 0 : return SerializeMultiGridElements(mg,
1389 0 : mg.get_grid_objects(),
1390 0 : out);
1391 : }
1392 :
1393 :
1394 : ////////////////////////////////////////////////////////////////////////
1395 : ////////////////////////////////////////////////////////////////////////
1396 : static pair<GridObject*, char>
1397 0 : GetParent(BinaryBuffer& in, const vector<Vertex*>& vVrts,
1398 : const vector<Edge*>& vEdges, const vector<Face*>& vFaces,
1399 : const vector<Volume*>& vVols)
1400 : {
1401 : char type;
1402 : int index;
1403 0 : in.read((char*)&type, sizeof(char));
1404 0 : in.read((char*)&index, sizeof(int));
1405 :
1406 0 : if(index >= 0){
1407 0 : switch(type){
1408 0 : case VERTEX:
1409 : assert(index < (int)vVrts.size() && "bad index!");
1410 0 : return make_pair(vVrts[index], type);
1411 0 : case EDGE:
1412 : assert(index < (int)vEdges.size() && "bad index!");
1413 0 : return make_pair(vEdges[index], type);
1414 0 : case FACE:
1415 : assert(index < (int)vFaces.size() && "bad index!");
1416 0 : return make_pair(vFaces[index], type);
1417 0 : case VOLUME:
1418 : assert(index < (int)vVols.size() && "bad index!");
1419 0 : return make_pair(vVols[index], type);
1420 : }
1421 : }
1422 :
1423 0 : return pair<GridObject*, char>(NULL, type);
1424 : }
1425 :
1426 : ////////////////////////////////////////////////////////////////////////
1427 : // DeserializeMultiGridElements
1428 0 : bool DeserializeMultiGridElements(MultiGrid& mg, BinaryBuffer& in,
1429 : std::vector<Vertex*>* pvVrts,
1430 : std::vector<Edge*>* pvEdges,
1431 : std::vector<Face*>* pvFaces,
1432 : std::vector<Volume*>* pvVols,
1433 : MultiElementAttachmentAccessor<AGeomObjID>* paaID)
1434 : {
1435 : SRLZ_PROFILE_FUNC();
1436 :
1437 : //todo A parents global id should be serialized and used to identify a parent
1438 : // if it was not sent along with an element but was already contained on
1439 : // the target process.
1440 :
1441 : // if the user specified element-vectors, we will use them.
1442 : // if not we'll use our own.
1443 : vector<Vertex*> vVrtsTMP;
1444 : vector<Edge*> vEdgesTMP;
1445 : vector<Face*> vFacesTMP;
1446 : vector<Volume*> vVolsTMP;
1447 :
1448 0 : if(!pvVrts)
1449 : pvVrts = &vVrtsTMP;
1450 0 : if(!pvEdges)
1451 : pvEdges = &vEdgesTMP;
1452 0 : if(!pvFaces)
1453 : pvFaces = &vFacesTMP;
1454 0 : if(!pvVols)
1455 : pvVols = &vVolsTMP;
1456 :
1457 : vector<Vertex*>& vVrts = *pvVrts;
1458 : vector<Edge*>& vEdges = *pvEdges;
1459 : vector<Face*>& vFaces = *pvFaces;
1460 : vector<Volume*>& vVols = *pvVols;
1461 :
1462 : vVrts.clear();
1463 : vEdges.clear();
1464 : vFaces.clear();
1465 : vVols.clear();
1466 :
1467 : // Read the header first
1468 : GridHeader gridHeader;
1469 0 : if(!ReadGridHeader(gridHeader, in)){
1470 : UG_LOG("Invalid GridHeader.");
1471 : return false;
1472 : }
1473 :
1474 0 : if(!gridHeader.contains_option(GHRO_READ_LEVELS)){
1475 : UG_LOG("ERROR in DeserializeMultiGridElements: READ_LEVELS required for MultiGrids.");
1476 : return false;
1477 : }
1478 0 : if(!gridHeader.contains_option(GHRO_READ_PARENTS)){
1479 : UG_LOG("ERROR in DeserializeMultiGridElements: READ_PARENTS required for MultiGrids.");
1480 : return false;
1481 : }
1482 :
1483 :
1484 0 : GeomObjID id;
1485 :
1486 : SRLZ_PROFILE(srlz_settingUpHashes);
1487 : // create hashes for existing geometric objects
1488 0 : Hash<GeomObjID, Vertex*> vrtHash((int)(1.1f * (float)mg.num<Vertex>()));
1489 0 : Hash<GeomObjID, Edge*> edgeHash((int)(1.1f * (float)mg.num<Edge>()));
1490 0 : Hash<GeomObjID, Face*> faceHash((int)(1.1f * (float)mg.num<Face>()));
1491 0 : Hash<GeomObjID, Volume*> volHash((int)(1.1f * (float)mg.num<Volume>()));
1492 :
1493 : vrtHash.reserve(mg.num<Vertex>());
1494 : edgeHash.reserve(mg.num<Edge>());
1495 : faceHash.reserve(mg.num<Face>());
1496 : volHash.reserve(mg.num<Volume>());
1497 :
1498 :
1499 0 : if(paaID){
1500 : // add existing elements to the hashes
1501 : for(VertexIterator iter = mg.begin<Vertex>();
1502 0 : iter != mg.end<Vertex>(); ++iter)
1503 0 : {vrtHash.insert((*paaID)[*iter], *iter);}
1504 :
1505 : for(EdgeIterator iter = mg.begin<Edge>();
1506 0 : iter != mg.end<Edge>(); ++iter)
1507 0 : {edgeHash.insert((*paaID)[*iter], *iter);}
1508 :
1509 : for(FaceIterator iter = mg.begin<Face>();
1510 0 : iter != mg.end<Face>(); ++iter)
1511 0 : {faceHash.insert((*paaID)[*iter], *iter);}
1512 :
1513 : for(VolumeIterator iter = mg.begin<Volume>();
1514 0 : iter != mg.end<Volume>(); ++iter)
1515 0 : {volHash.insert((*paaID)[*iter], *iter);}
1516 : }
1517 : SRLZ_PROFILE_END();
1518 :
1519 : // create the vertices and store them in vVrts for later indexing.
1520 : {
1521 : SRLZ_PROFILE(srlz_readingData);
1522 0 : uint currentLevel = 0;
1523 : // iterate through the stream and create vertices
1524 0 : while(!in.eof())
1525 : {
1526 : // read the goid
1527 0 : int goid = 0;
1528 0 : in.read((char*)&goid, sizeof(int));
1529 :
1530 : // check whether we reached the end of the grid-description.
1531 0 : if(goid == GSID_END_OF_GRID)
1532 : break;
1533 :
1534 0 : if(goid == GSID_NEW_LEVEL){
1535 : // read the current level and start at the beginning of the loop
1536 0 : in.read((char*)¤tLevel, sizeof(uint));
1537 0 : continue;
1538 : }
1539 :
1540 : // we have to read more elements. check how many.
1541 0 : int numElems = 0;
1542 0 : in.read((char*)&numElems, sizeof(int));
1543 :
1544 : // depending on the goid we'll create new elements.
1545 0 : switch(goid)
1546 : {
1547 : case GSID_VERTEX:
1548 : {
1549 : SRLZ_PROFILE(srlz_vertices);
1550 0 : for(int i = 0; i < numElems; ++i)
1551 : {
1552 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
1553 : vFaces, vVols);
1554 0 : GridObject* parent = pInfo.first;
1555 :
1556 0 : if(paaID){
1557 0 : Deserialize(in, id);
1558 : Vertex* oldVrt;
1559 0 : if(vrtHash.get_entry(oldVrt, id)){
1560 : assert(dynamic_cast<RegularVertex*>(oldVrt));
1561 0 : vVrts.push_back(oldVrt);
1562 : // make sure that its parent is registered
1563 0 : if(parent && (!mg.get_parent(oldVrt)))
1564 0 : mg.associate_parent(oldVrt, parent);
1565 0 : continue;
1566 : }
1567 : UG_ASSERT(!(parent && mg.num_children<Vertex>(parent)),
1568 : "Parent has a child vertex already. "
1569 : << "ID of parent: " << (*paaID)[parent]
1570 : << ", ID of existing child: "
1571 : << (*paaID)[mg.get_child<Vertex>(parent, 0)]
1572 : << ", ID of new element: " << id);
1573 : }
1574 :
1575 0 : if(parent)
1576 0 : vVrts.push_back(*mg.create<RegularVertex>(parent));
1577 : else{
1578 0 : vVrts.push_back(*mg.create<RegularVertex>(currentLevel));
1579 0 : mg.set_parent_type(vVrts.back(), pInfo.second);
1580 : }
1581 :
1582 0 : if(paaID)
1583 0 : (*paaID)[vVrts.back()] = id;
1584 : }
1585 : }break;
1586 :
1587 : case GSID_HANGING_VERTEX:
1588 : {
1589 : SRLZ_PROFILE(srlz_hangingVertices);
1590 : // create the hanging vertices and assign the local coordinates
1591 0 : for(int i = 0; i < numElems; ++i)
1592 : {
1593 : number coord1, coord2;
1594 0 : in.read((char*)&coord1, sizeof(number));
1595 0 : in.read((char*)&coord2, sizeof(number));
1596 : int cgType;
1597 : int cgInd;
1598 0 : in.read((char*)&cgType, sizeof(int));
1599 0 : in.read((char*)&cgInd, sizeof(int));
1600 : int parentBaseObjId;
1601 0 : in.read((char*)&parentBaseObjId, sizeof(int));
1602 :
1603 : UG_ASSERT(parentBaseObjId != -1,
1604 : "Bad constraining element id in constrained vertex encountered");
1605 :
1606 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
1607 : vFaces, vVols);
1608 0 : GridObject* parent = pInfo.first;
1609 :
1610 0 : if(paaID){
1611 0 : Deserialize(in, id);
1612 : Vertex* oldVrt;
1613 : if(vrtHash.get_entry(oldVrt, id)){
1614 : assert(dynamic_cast<ConstrainedVertex*>(oldVrt));
1615 0 : vVrts.push_back(oldVrt);
1616 : // make sure that its parent is registered
1617 0 : if(parent && (!mg.get_parent(oldVrt))){
1618 0 : mg.associate_parent(oldVrt, parent);
1619 : // make sure that constrained/constraining relations are fine
1620 0 : switch(parent->base_object_id()){
1621 : case EDGE:{
1622 0 : ConstrainingEdge* cge = dynamic_cast<ConstrainingEdge*>(parent);
1623 : UG_ASSERT(cge, "Constraining edge has to be of type ConstrainingEdge");
1624 0 : cge->add_constrained_object(oldVrt);
1625 : static_cast<ConstrainedVertex*>(oldVrt)->set_constraining_object(cge);
1626 : }break;
1627 :
1628 : case FACE:{
1629 0 : ConstrainingFace* cgf = dynamic_cast<ConstrainingFace*>(parent);
1630 : UG_ASSERT(cgf, "Constraining face has to be of type ConstrainingFace");
1631 0 : cgf->add_constrained_object(oldVrt);
1632 : static_cast<ConstrainedVertex*>(oldVrt)->set_constraining_object(cgf);
1633 : }break;
1634 :
1635 0 : default:
1636 0 : UG_THROW("Constraining object has to be an edge or a face");
1637 : break;
1638 : }
1639 : }
1640 0 : continue;
1641 0 : }
1642 : }
1643 :
1644 : ConstrainedVertex* hv;
1645 0 : if(parent)
1646 0 : hv = *mg.create<ConstrainedVertex>(parent);
1647 : else{
1648 0 : hv = *mg.create<ConstrainedVertex>(currentLevel);
1649 0 : mg.set_parent_type(hv, pInfo.second);
1650 : }
1651 0 : hv->set_local_coordinate_1(coord1);
1652 0 : hv->set_local_coordinate_2(coord2);
1653 0 : hv->set_parent_base_object_id(parentBaseObjId);
1654 0 : vVrts.push_back(hv);
1655 0 : if(paaID)
1656 : (*paaID)[hv] = id;
1657 :
1658 0 : if(cgInd != -1){
1659 0 : switch(cgType){
1660 0 : case EDGE:
1661 : assert(cgInd < (int)vEdges.size());
1662 : assert(dynamic_cast<ConstrainingEdge*>(vEdges[cgInd]));
1663 0 : hv->set_constraining_object(vEdges[cgInd]);
1664 0 : static_cast<ConstrainingEdge*>(vEdges[cgInd])
1665 0 : ->add_constrained_object(hv);
1666 : break;
1667 0 : case FACE:
1668 : assert(cgInd < (int)vFaces.size());
1669 : assert(dynamic_cast<ConstrainingFace*>(vFaces[cgInd]));
1670 0 : hv->set_constraining_object(vFaces[cgInd]);
1671 0 : static_cast<ConstrainingFace*>(vFaces[cgInd])
1672 0 : ->add_constrained_object(hv);
1673 : break;
1674 : }
1675 : }
1676 : }
1677 : }break;
1678 : case GSID_EDGE:
1679 : {
1680 : SRLZ_PROFILE(srlz_edges);
1681 0 : for(int i = 0; i < numElems; ++i)
1682 : {
1683 : int i1, i2;
1684 0 : in.read((char*)&i1, sizeof(int));
1685 0 : in.read((char*)&i2, sizeof(int));
1686 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
1687 : vFaces, vVols);
1688 0 : GridObject* parent = pInfo.first;
1689 :
1690 0 : if(paaID){
1691 0 : Deserialize(in, id);
1692 : Edge* oldEdge;
1693 0 : if(edgeHash.get_entry(oldEdge, id)){
1694 : assert(dynamic_cast<RegularEdge*>(oldEdge));
1695 0 : vEdges.push_back(oldEdge);
1696 : // make sure that its parent is registered
1697 0 : if(parent && (!mg.get_parent(oldEdge)))
1698 0 : mg.associate_parent(oldEdge, parent);
1699 0 : continue;
1700 : }
1701 : }
1702 : RegularEdge* e;
1703 0 : if(parent)
1704 0 : e = *mg.create<RegularEdge>(
1705 0 : EdgeDescriptor(vVrts[i1], vVrts[i2]), parent);
1706 : else{
1707 0 : e = *mg.create<RegularEdge>(
1708 0 : EdgeDescriptor(vVrts[i1], vVrts[i2]), currentLevel);
1709 0 : mg.set_parent_type(e, pInfo.second);
1710 : }
1711 0 : vEdges.push_back(e);
1712 0 : if(paaID)
1713 : (*paaID)[e] = id;
1714 : }
1715 : }break;
1716 : case GSID_CONSTRAINING_EDGE:
1717 : {
1718 : SRLZ_PROFILE(srlz_constrainingEdges);
1719 0 : for(int i = 0; i < numElems; ++i)
1720 : {
1721 : int i1, i2;
1722 0 : in.read((char*)&i1, sizeof(int));
1723 0 : in.read((char*)&i2, sizeof(int));
1724 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
1725 : vFaces, vVols);
1726 0 : GridObject* parent = pInfo.first;
1727 :
1728 0 : if(paaID){
1729 0 : Deserialize(in, id);
1730 : Edge* oldEdge;
1731 0 : if(edgeHash.get_entry(oldEdge, id)){
1732 : assert(dynamic_cast<ConstrainingEdge*>(oldEdge));
1733 0 : vEdges.push_back(oldEdge);
1734 : // make sure that its parent is registered
1735 0 : if(parent && (!mg.get_parent(oldEdge)))
1736 0 : mg.associate_parent(oldEdge, parent);
1737 0 : continue;
1738 : }
1739 : }
1740 :
1741 : ConstrainingEdge* e;
1742 0 : if(parent)
1743 0 : e = *mg.create<ConstrainingEdge>(
1744 0 : EdgeDescriptor(vVrts[i1], vVrts[i2]), parent);
1745 : else{
1746 0 : e = *mg.create<ConstrainingEdge>(
1747 0 : EdgeDescriptor(vVrts[i1], vVrts[i2]), currentLevel);
1748 0 : mg.set_parent_type(e, pInfo.second);
1749 : }
1750 0 : vEdges.push_back(e);
1751 0 : if(paaID)
1752 : (*paaID)[e] = id;
1753 : }
1754 : }break;
1755 : case GSID_CONSTRAINED_EDGE:
1756 : {
1757 : SRLZ_PROFILE(srlz_constrainedEdges);
1758 0 : for(int i = 0; i < numElems; ++i)
1759 : {
1760 : int i1, i2;
1761 0 : in.read((char*)&i1, sizeof(int));
1762 0 : in.read((char*)&i2, sizeof(int));
1763 : int cgType;
1764 : int cgInd;
1765 0 : in.read((char*)&cgType, sizeof(int));
1766 0 : in.read((char*)&cgInd, sizeof(int));
1767 : int parentBaseObjId;
1768 0 : in.read((char*)&parentBaseObjId, sizeof(int));
1769 :
1770 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
1771 : vFaces, vVols);
1772 0 : GridObject* parent = pInfo.first;
1773 :
1774 0 : if(paaID){
1775 0 : Deserialize(in, id);
1776 : Edge* oldEdge;
1777 : if(edgeHash.get_entry(oldEdge, id)){
1778 : assert(dynamic_cast<ConstrainedEdge*>(oldEdge));
1779 0 : vEdges.push_back(oldEdge);
1780 : // make sure that its parent is registered
1781 0 : if(parent && (!mg.get_parent(oldEdge))){
1782 0 : mg.associate_parent(oldEdge, parent);
1783 : // make sure that constrained/constraining relations are fine
1784 0 : switch(parent->base_object_id()){
1785 : case EDGE:{
1786 0 : ConstrainingEdge* cge = dynamic_cast<ConstrainingEdge*>(parent);
1787 : UG_ASSERT(cge, "Constraining edge has to be of type ConstrainingEdge");
1788 0 : cge->add_constrained_object(oldEdge);
1789 : static_cast<ConstrainedEdge*>(oldEdge)->set_constraining_object(cge);
1790 : }break;
1791 :
1792 : case FACE:{
1793 0 : ConstrainingFace* cgf = dynamic_cast<ConstrainingFace*>(parent);
1794 : UG_ASSERT(cgf, "Constraining face has to be of type ConstrainingFace");
1795 0 : cgf->add_constrained_object(oldEdge);
1796 : static_cast<ConstrainedEdge*>(oldEdge)->set_constraining_object(cgf);
1797 : }break;
1798 :
1799 0 : default:
1800 0 : UG_THROW("Constraining object has to be an edge or a face");
1801 : break;
1802 : }
1803 :
1804 : }
1805 0 : continue;
1806 0 : }
1807 : }
1808 :
1809 : ConstrainedEdge* e;
1810 0 : if(parent)
1811 0 : e = *mg.create<ConstrainedEdge>(
1812 0 : EdgeDescriptor(vVrts[i1], vVrts[i2]), parent);
1813 : else{
1814 0 : e = *mg.create<ConstrainedEdge>(
1815 0 : EdgeDescriptor(vVrts[i1], vVrts[i2]), currentLevel);
1816 0 : mg.set_parent_type(e, pInfo.second);
1817 : }
1818 :
1819 0 : e->set_parent_base_object_id(parentBaseObjId);
1820 :
1821 0 : vEdges.push_back(e);
1822 0 : if(paaID)
1823 : (*paaID)[e] = id;
1824 :
1825 0 : if(cgInd != -1){
1826 0 : switch(cgType){
1827 0 : case EDGE:
1828 : assert(cgInd < (int)vEdges.size());
1829 : assert(dynamic_cast<ConstrainingEdge*>(vEdges[cgInd]));
1830 0 : e->set_constraining_object(vEdges[cgInd]);
1831 0 : static_cast<ConstrainingEdge*>(vEdges[cgInd])
1832 0 : ->add_constrained_object(e);
1833 : break;
1834 0 : case FACE:
1835 : assert(cgInd < (int)vFaces.size());
1836 : assert(dynamic_cast<ConstrainingFace*>(vFaces[cgInd]));
1837 0 : e->set_constraining_object(vFaces[cgInd]);
1838 0 : static_cast<ConstrainingFace*>(vFaces[cgInd])
1839 0 : ->add_constrained_object(e);
1840 : break;
1841 : }
1842 : }
1843 : }
1844 : }break;
1845 : case GSID_TRIANGLE:
1846 : {
1847 : SRLZ_PROFILE(srlz_triangles);
1848 0 : for(int i = 0; i < numElems; ++i)
1849 : {
1850 : int i1, i2, i3;
1851 0 : in.read((char*)&i1, sizeof(int));
1852 0 : in.read((char*)&i2, sizeof(int));
1853 0 : in.read((char*)&i3, sizeof(int));
1854 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
1855 : vFaces, vVols);
1856 0 : GridObject* parent = pInfo.first;
1857 :
1858 0 : if(paaID){
1859 0 : Deserialize(in, id);
1860 : Face* oldFace;
1861 0 : if(faceHash.get_entry(oldFace, id)){
1862 : assert(dynamic_cast<Triangle*>(oldFace));
1863 0 : vFaces.push_back(oldFace);
1864 : // make sure that its parent is registered
1865 0 : if(parent && (!mg.get_parent(oldFace)))
1866 0 : mg.associate_parent(oldFace, parent);
1867 0 : continue;
1868 : }
1869 : }
1870 :
1871 : Triangle* t;
1872 0 : if(parent)
1873 0 : t = *mg.create<Triangle>(TriangleDescriptor(
1874 0 : vVrts[i1], vVrts[i2],
1875 0 : vVrts[i3]), parent);
1876 : else{
1877 0 : t = *mg.create<Triangle>(TriangleDescriptor(
1878 0 : vVrts[i1], vVrts[i2],
1879 0 : vVrts[i3]), currentLevel);
1880 0 : mg.set_parent_type(t, pInfo.second);
1881 : }
1882 0 : vFaces.push_back(t);
1883 0 : if(paaID)
1884 : (*paaID)[t] = id;
1885 : }
1886 : }break;
1887 : case GSID_QUADRILATERAL:
1888 : {
1889 : SRLZ_PROFILE(srlz_quadrilaterals);
1890 0 : for(int i = 0; i < numElems; ++i)
1891 : {
1892 : int i1, i2, i3, i4;
1893 0 : in.read((char*)&i1, sizeof(int));
1894 0 : in.read((char*)&i2, sizeof(int));
1895 0 : in.read((char*)&i3, sizeof(int));
1896 0 : in.read((char*)&i4, sizeof(int));
1897 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
1898 : vFaces, vVols);
1899 0 : GridObject* parent = pInfo.first;
1900 :
1901 0 : if(paaID){
1902 0 : Deserialize(in, id);
1903 : Face* oldFace;
1904 0 : if(faceHash.get_entry(oldFace, id)){
1905 : assert(dynamic_cast<Quadrilateral*>(oldFace));
1906 0 : vFaces.push_back(oldFace);
1907 : // make sure that its parent is registered
1908 0 : if(parent && (!mg.get_parent(oldFace)))
1909 0 : mg.associate_parent(oldFace, parent);
1910 0 : continue;
1911 : }
1912 : }
1913 :
1914 : Quadrilateral* q;
1915 0 : if(parent)
1916 0 : q = *mg.create<Quadrilateral>(QuadrilateralDescriptor(
1917 0 : vVrts[i1], vVrts[i2], vVrts[i3],
1918 0 : vVrts[i4]), parent);
1919 : else{
1920 0 : q = *mg.create<Quadrilateral>(QuadrilateralDescriptor(
1921 0 : vVrts[i1], vVrts[i2], vVrts[i3],
1922 0 : vVrts[i4]), currentLevel);
1923 0 : mg.set_parent_type(q, pInfo.second);
1924 : }
1925 0 : vFaces.push_back(q);
1926 0 : if(paaID)
1927 : (*paaID)[q] = id;
1928 : }
1929 : }break;
1930 :
1931 : case GSID_CONSTRAINING_TRIANGLE:
1932 : {
1933 : SRLZ_PROFILE(srlz_constrainingTriangles);
1934 0 : for(int i = 0; i < numElems; ++i)
1935 : {
1936 : int i1, i2, i3;
1937 0 : in.read((char*)&i1, sizeof(int));
1938 0 : in.read((char*)&i2, sizeof(int));
1939 0 : in.read((char*)&i3, sizeof(int));
1940 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
1941 : vFaces, vVols);
1942 0 : GridObject* parent = pInfo.first;
1943 :
1944 0 : if(paaID){
1945 0 : Deserialize(in, id);
1946 : Face* oldFace;
1947 0 : if(faceHash.get_entry(oldFace, id)){
1948 : assert(dynamic_cast<ConstrainingFace*>(oldFace));
1949 0 : vFaces.push_back(oldFace);
1950 : // make sure that its parent is registered
1951 0 : if(parent && (!mg.get_parent(oldFace)))
1952 0 : mg.associate_parent(oldFace, parent);
1953 0 : continue;
1954 : }
1955 : }
1956 :
1957 : ConstrainingFace* e;
1958 0 : if(parent)
1959 0 : e = *mg.create<ConstrainingTriangle>(
1960 0 : TriangleDescriptor(vVrts[i1], vVrts[i2], vVrts[i3]),
1961 : parent);
1962 : else{
1963 0 : e = *mg.create<ConstrainingTriangle>(
1964 0 : TriangleDescriptor(vVrts[i1], vVrts[i2], vVrts[i3]),
1965 : currentLevel);
1966 0 : mg.set_parent_type(e, pInfo.second);
1967 : }
1968 0 : vFaces.push_back(e);
1969 0 : if(paaID)
1970 : (*paaID)[e] = id;
1971 : }
1972 : }break;
1973 :
1974 : case GSID_CONSTRAINED_TRIANGLE:
1975 : {
1976 : SRLZ_PROFILE(srlz_constrainedTriangles);
1977 0 : for(int i = 0; i < numElems; ++i)
1978 : {
1979 : int i1, i2, i3;
1980 0 : in.read((char*)&i1, sizeof(int));
1981 0 : in.read((char*)&i2, sizeof(int));
1982 0 : in.read((char*)&i3, sizeof(int));
1983 : int cgInd;
1984 0 : in.read((char*)&cgInd, sizeof(int));
1985 : int parentBaseObjId;
1986 0 : in.read((char*)&parentBaseObjId, sizeof(int));
1987 :
1988 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
1989 : vFaces, vVols);
1990 0 : GridObject* parent = pInfo.first;
1991 :
1992 0 : if(paaID){
1993 0 : Deserialize(in, id);
1994 : Face* oldFace;
1995 : if(faceHash.get_entry(oldFace, id)){
1996 : assert(dynamic_cast<ConstrainedFace*>(oldFace));
1997 0 : vFaces.push_back(oldFace);
1998 : // make sure that its parent is registered
1999 0 : if(parent && (!mg.get_parent(oldFace))){
2000 0 : mg.associate_parent(oldFace, parent);
2001 : // make sure that constrained/constraining relations are fine
2002 : UG_ASSERT(parent->base_object_id() == FACE,
2003 : "Only faces may constrain faces");
2004 0 : ConstrainingFace* cgf = dynamic_cast<ConstrainingFace*>(parent);
2005 : UG_ASSERT(cgf, "Constraining face has to be of type ConstrainingFace");
2006 0 : cgf->add_constrained_object(oldFace);
2007 : static_cast<ConstrainedFace*>(oldFace)->set_constraining_object(cgf);
2008 : }
2009 0 : continue;
2010 0 : }
2011 : }
2012 :
2013 : ConstrainedFace* e;
2014 0 : if(parent)
2015 0 : e = *mg.create<ConstrainedTriangle>(
2016 0 : TriangleDescriptor(vVrts[i1], vVrts[i2], vVrts[i3]),
2017 : parent);
2018 : else{
2019 0 : e = *mg.create<ConstrainedTriangle>(
2020 0 : TriangleDescriptor(vVrts[i1], vVrts[i2], vVrts[i3]),
2021 : currentLevel);
2022 0 : mg.set_parent_type(e, pInfo.second);
2023 : }
2024 :
2025 0 : e->set_parent_base_object_id(parentBaseObjId);
2026 :
2027 0 : vFaces.push_back(e);
2028 0 : if(paaID)
2029 : (*paaID)[e] = id;
2030 :
2031 0 : if(cgInd != -1){
2032 : assert(cgInd < (int)vFaces.size());
2033 : assert(dynamic_cast<ConstrainingFace*>(vFaces[cgInd]));
2034 0 : e->set_constraining_object(vFaces[cgInd]);
2035 0 : static_cast<ConstrainingFace*>(vFaces[cgInd])
2036 0 : ->add_constrained_object(e);
2037 : }
2038 : }
2039 : }break;
2040 :
2041 : case GSID_CONSTRAINING_QUADRILATERAL:
2042 : {
2043 : SRLZ_PROFILE(srlz_constrainingQuadrilaterals);
2044 0 : for(int i = 0; i < numElems; ++i)
2045 : {
2046 : int i1, i2, i3, i4;
2047 0 : in.read((char*)&i1, sizeof(int));
2048 0 : in.read((char*)&i2, sizeof(int));
2049 0 : in.read((char*)&i3, sizeof(int));
2050 0 : in.read((char*)&i4, sizeof(int));
2051 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
2052 : vFaces, vVols);
2053 0 : GridObject* parent = pInfo.first;
2054 :
2055 0 : if(paaID){
2056 0 : Deserialize(in, id);
2057 : Face* oldFace;
2058 0 : if(faceHash.get_entry(oldFace, id)){
2059 : assert(dynamic_cast<ConstrainingFace*>(oldFace));
2060 0 : vFaces.push_back(oldFace);
2061 : // make sure that its parent is registered
2062 0 : if(parent && (!mg.get_parent(oldFace)))
2063 0 : mg.associate_parent(oldFace, parent);
2064 0 : continue;
2065 : }
2066 : }
2067 :
2068 : ConstrainingFace* e;
2069 0 : if(parent)
2070 0 : e = *mg.create<ConstrainingQuadrilateral>(
2071 0 : QuadrilateralDescriptor(vVrts[i1], vVrts[i2],
2072 0 : vVrts[i3], vVrts[i4]),
2073 : parent);
2074 : else{
2075 0 : e = *mg.create<ConstrainingQuadrilateral>(
2076 0 : QuadrilateralDescriptor(vVrts[i1], vVrts[i2],
2077 0 : vVrts[i3], vVrts[i4]),
2078 : currentLevel);
2079 0 : mg.set_parent_type(e, pInfo.second);
2080 : }
2081 :
2082 0 : vFaces.push_back(e);
2083 0 : if(paaID)
2084 : (*paaID)[e] = id;
2085 : }
2086 : }break;
2087 :
2088 : case GSID_CONSTRAINED_QUADRILATERAL:
2089 : {
2090 : SRLZ_PROFILE(srlz_constrainedQuadrilaterals);
2091 0 : for(int i = 0; i < numElems; ++i)
2092 : {
2093 : int i1, i2, i3, i4;
2094 0 : in.read((char*)&i1, sizeof(int));
2095 0 : in.read((char*)&i2, sizeof(int));
2096 0 : in.read((char*)&i3, sizeof(int));
2097 0 : in.read((char*)&i4, sizeof(int));
2098 : int cgInd;
2099 0 : in.read((char*)&cgInd, sizeof(int));
2100 : int parentBaseObjId;
2101 0 : in.read((char*)&parentBaseObjId, sizeof(int));
2102 :
2103 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
2104 : vFaces, vVols);
2105 0 : GridObject* parent = pInfo.first;
2106 :
2107 0 : if(paaID){
2108 0 : Deserialize(in, id);
2109 : Face* oldFace;
2110 : if(faceHash.get_entry(oldFace, id)){
2111 : UG_ASSERT(dynamic_cast<ConstrainedFace*>(oldFace),
2112 : "Face should be constrained! gid: " << id);
2113 0 : vFaces.push_back(oldFace);
2114 : // make sure that its parent is registered
2115 0 : if(parent && (!mg.get_parent(oldFace))){
2116 0 : mg.associate_parent(oldFace, parent);
2117 : // make sure that constrained/constraining relations are fine
2118 : UG_ASSERT(parent->base_object_id() == FACE,
2119 : "Only faces may constrain faces");
2120 0 : ConstrainingFace* cgf = dynamic_cast<ConstrainingFace*>(parent);
2121 : UG_ASSERT(cgf, "Constraining face has to be of type ConstrainingFace");
2122 0 : cgf->add_constrained_object(oldFace);
2123 : static_cast<ConstrainedFace*>(oldFace)->set_constraining_object(cgf);
2124 : }
2125 0 : continue;
2126 0 : }
2127 : }
2128 :
2129 : ConstrainedFace* e;
2130 0 : if(parent)
2131 0 : e = *mg.create<ConstrainedQuadrilateral>(
2132 0 : QuadrilateralDescriptor(vVrts[i1], vVrts[i2],
2133 0 : vVrts[i3], vVrts[i4]),
2134 : parent);
2135 : else{
2136 0 : e = *mg.create<ConstrainedQuadrilateral>(
2137 0 : QuadrilateralDescriptor(vVrts[i1], vVrts[i2],
2138 0 : vVrts[i3], vVrts[i4]),
2139 : currentLevel);
2140 0 : mg.set_parent_type(e, pInfo.second);
2141 : }
2142 :
2143 0 : e->set_parent_base_object_id(parentBaseObjId);
2144 :
2145 0 : vFaces.push_back(e);
2146 0 : if(paaID)
2147 : (*paaID)[e] = id;
2148 :
2149 0 : if(cgInd != -1){
2150 : assert(cgInd < (int)vFaces.size());
2151 : assert(dynamic_cast<ConstrainingFace*>(vFaces[cgInd]));
2152 0 : e->set_constraining_object(vFaces[cgInd]);
2153 0 : static_cast<ConstrainingFace*>(vFaces[cgInd])
2154 0 : ->add_constrained_object(e);
2155 : }
2156 : }
2157 : }break;
2158 :
2159 : case GSID_TETRAHEDRON:
2160 : {
2161 : SRLZ_PROFILE(srlz_tetrahedrons);
2162 0 : for(int i = 0; i < numElems; ++i)
2163 : {
2164 : int i1, i2, i3, i4;
2165 0 : in.read((char*)&i1, sizeof(int));
2166 0 : in.read((char*)&i2, sizeof(int));
2167 0 : in.read((char*)&i3, sizeof(int));
2168 0 : in.read((char*)&i4, sizeof(int));
2169 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
2170 : vFaces, vVols);
2171 0 : GridObject* parent = pInfo.first;
2172 :
2173 0 : if(paaID){
2174 0 : Deserialize(in, id);
2175 : Volume* oldVol;
2176 0 : if(volHash.get_entry(oldVol, id)){
2177 : assert(dynamic_cast<Tetrahedron*>(oldVol));
2178 0 : vVols.push_back(oldVol);
2179 : // make sure that its parent is registered
2180 0 : if(parent && (!mg.get_parent(oldVol)))
2181 0 : mg.associate_parent(oldVol, parent);
2182 0 : continue;
2183 : }
2184 : }
2185 :
2186 : Tetrahedron* t;
2187 0 : if(parent)
2188 0 : t = *mg.create<Tetrahedron>(TetrahedronDescriptor(
2189 0 : vVrts[i1], vVrts[i2],
2190 0 : vVrts[i3], vVrts[i4]),
2191 : parent);
2192 : else{
2193 0 : t = *mg.create<Tetrahedron>(TetrahedronDescriptor(
2194 0 : vVrts[i1], vVrts[i2],
2195 0 : vVrts[i3], vVrts[i4]),
2196 : currentLevel);
2197 0 : mg.set_parent_type(t, pInfo.second);
2198 : }
2199 0 : vVols.push_back(t);
2200 0 : if(paaID)
2201 : (*paaID)[t] = id;
2202 : }
2203 : }break;
2204 : case GSID_HEXAHEDRON:
2205 : {
2206 : SRLZ_PROFILE(srlz_hexahedrons);
2207 0 : for(int i = 0; i < numElems; ++i)
2208 : {
2209 : int i1, i2, i3, i4, i5, i6, i7, i8;
2210 0 : in.read((char*)&i1, sizeof(int));
2211 0 : in.read((char*)&i2, sizeof(int));
2212 0 : in.read((char*)&i3, sizeof(int));
2213 0 : in.read((char*)&i4, sizeof(int));
2214 0 : in.read((char*)&i5, sizeof(int));
2215 0 : in.read((char*)&i6, sizeof(int));
2216 0 : in.read((char*)&i7, sizeof(int));
2217 0 : in.read((char*)&i8, sizeof(int));
2218 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
2219 : vFaces, vVols);
2220 0 : GridObject* parent = pInfo.first;
2221 :
2222 0 : if(paaID){
2223 0 : Deserialize(in, id);
2224 : Volume* oldVol;
2225 0 : if(volHash.get_entry(oldVol, id)){
2226 : assert(dynamic_cast<Hexahedron*>(oldVol));
2227 0 : vVols.push_back(oldVol);
2228 : // make sure that its parent is registered
2229 0 : if(parent && (!mg.get_parent(oldVol)))
2230 0 : mg.associate_parent(oldVol, parent);
2231 0 : continue;
2232 : }
2233 : }
2234 :
2235 : Hexahedron* h;
2236 0 : if(parent)
2237 0 : h = *mg.create<Hexahedron>(HexahedronDescriptor(
2238 0 : vVrts[i1], vVrts[i2], vVrts[i3],
2239 0 : vVrts[i4], vVrts[i5], vVrts[i6],
2240 0 : vVrts[i7], vVrts[i8]), parent);
2241 : else{
2242 0 : h = *mg.create<Hexahedron>(HexahedronDescriptor(
2243 0 : vVrts[i1], vVrts[i2], vVrts[i3],
2244 0 : vVrts[i4], vVrts[i5], vVrts[i6],
2245 0 : vVrts[i7], vVrts[i8]), currentLevel);
2246 0 : mg.set_parent_type(h, pInfo.second);
2247 : }
2248 0 : vVols.push_back(h);
2249 0 : if(paaID)
2250 : (*paaID)[h] = id;
2251 : }
2252 : }break;
2253 : case GSID_PRISM:
2254 : {
2255 : SRLZ_PROFILE(srlz_prisms);
2256 0 : for(int i = 0; i < numElems; ++i)
2257 : {
2258 : int i1, i2, i3, i4, i5, i6;
2259 0 : in.read((char*)&i1, sizeof(int));
2260 0 : in.read((char*)&i2, sizeof(int));
2261 0 : in.read((char*)&i3, sizeof(int));
2262 0 : in.read((char*)&i4, sizeof(int));
2263 0 : in.read((char*)&i5, sizeof(int));
2264 0 : in.read((char*)&i6, sizeof(int));
2265 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
2266 : vFaces, vVols);
2267 0 : GridObject* parent = pInfo.first;
2268 :
2269 0 : if(paaID){
2270 0 : Deserialize(in, id);
2271 : Volume* oldVol;
2272 0 : if(volHash.get_entry(oldVol, id)){
2273 : assert(dynamic_cast<Prism*>(oldVol));
2274 0 : vVols.push_back(oldVol);
2275 : // make sure that its parent is registered
2276 0 : if(parent && (!mg.get_parent(oldVol)))
2277 0 : mg.associate_parent(oldVol, parent);
2278 0 : continue;
2279 : }
2280 : }
2281 :
2282 : Prism* p;
2283 0 : if(parent)
2284 0 : p = *mg.create<Prism>(PrismDescriptor(
2285 0 : vVrts[i1], vVrts[i2], vVrts[i3],
2286 0 : vVrts[i4], vVrts[i5], vVrts[i6]),
2287 : parent);
2288 : else{
2289 0 : p = *mg.create<Prism>(PrismDescriptor(
2290 0 : vVrts[i1], vVrts[i2], vVrts[i3],
2291 0 : vVrts[i4], vVrts[i5], vVrts[i6]),
2292 : currentLevel);
2293 0 : mg.set_parent_type(p, pInfo.second);
2294 : }
2295 0 : vVols.push_back(p);
2296 0 : if(paaID)
2297 : (*paaID)[p] = id;
2298 : }
2299 : }break;
2300 : case GSID_PYRAMID:
2301 : {
2302 : SRLZ_PROFILE(srlz_pyramids);
2303 0 : for(int i = 0; i < numElems; ++i)
2304 : {
2305 : int i1, i2, i3, i4, i5;
2306 0 : in.read((char*)&i1, sizeof(int));
2307 0 : in.read((char*)&i2, sizeof(int));
2308 0 : in.read((char*)&i3, sizeof(int));
2309 0 : in.read((char*)&i4, sizeof(int));
2310 0 : in.read((char*)&i5, sizeof(int));
2311 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
2312 : vFaces, vVols);
2313 0 : GridObject* parent = pInfo.first;
2314 :
2315 0 : if(paaID){
2316 0 : Deserialize(in, id);
2317 : Volume* oldVol;
2318 0 : if(volHash.get_entry(oldVol, id)){
2319 : assert(dynamic_cast<Pyramid*>(oldVol));
2320 0 : vVols.push_back(oldVol);
2321 : // make sure that its parent is registered
2322 0 : if(parent && (!mg.get_parent(oldVol)))
2323 0 : mg.associate_parent(oldVol, parent);
2324 0 : continue;
2325 : }
2326 : }
2327 :
2328 : Pyramid* p;
2329 0 : if(parent)
2330 0 : p = *mg.create<Pyramid>(PyramidDescriptor(
2331 0 : vVrts[i1], vVrts[i2], vVrts[i3],
2332 0 : vVrts[i4], vVrts[i5]), parent);
2333 : else{
2334 0 : p = *mg.create<Pyramid>(PyramidDescriptor(
2335 0 : vVrts[i1], vVrts[i2], vVrts[i3],
2336 0 : vVrts[i4], vVrts[i5]), currentLevel);
2337 0 : mg.set_parent_type(p, pInfo.second);
2338 : }
2339 0 : vVols.push_back(p);
2340 0 : if(paaID)
2341 : (*paaID)[p] = id;
2342 : }
2343 : }break;
2344 :
2345 : case GSID_OCTAHEDRON:
2346 : {
2347 : SRLZ_PROFILE(srlz_octahedra);
2348 0 : for(int i = 0; i < numElems; ++i)
2349 : {
2350 : int i1, i2, i3, i4, i5, i6;
2351 0 : in.read((char*)&i1, sizeof(int));
2352 0 : in.read((char*)&i2, sizeof(int));
2353 0 : in.read((char*)&i3, sizeof(int));
2354 0 : in.read((char*)&i4, sizeof(int));
2355 0 : in.read((char*)&i5, sizeof(int));
2356 0 : in.read((char*)&i6, sizeof(int));
2357 0 : pair<GridObject*, char> pInfo = GetParent(in, vVrts, vEdges,
2358 : vFaces, vVols);
2359 0 : GridObject* parent = pInfo.first;
2360 :
2361 0 : if(paaID){
2362 0 : Deserialize(in, id);
2363 : Volume* oldVol;
2364 0 : if(volHash.get_entry(oldVol, id)){
2365 : assert(dynamic_cast<Pyramid*>(oldVol));
2366 0 : vVols.push_back(oldVol);
2367 : // make sure that its parent is registered
2368 0 : if(parent && (!mg.get_parent(oldVol)))
2369 0 : mg.associate_parent(oldVol, parent);
2370 0 : continue;
2371 : }
2372 : }
2373 :
2374 : Octahedron* p;
2375 0 : if(parent)
2376 0 : p = *mg.create<Octahedron>(OctahedronDescriptor(
2377 0 : vVrts[i1], vVrts[i2], vVrts[i3],
2378 0 : vVrts[i4], vVrts[i5], vVrts[i6]), parent);
2379 : else{
2380 0 : p = *mg.create<Octahedron>(OctahedronDescriptor(
2381 0 : vVrts[i1], vVrts[i2], vVrts[i3],
2382 0 : vVrts[i4], vVrts[i5], vVrts[i6]), currentLevel);
2383 0 : mg.set_parent_type(p, pInfo.second);
2384 : }
2385 0 : vVols.push_back(p);
2386 0 : if(paaID)
2387 : (*paaID)[p] = id;
2388 : }
2389 : }break;
2390 : default:
2391 : LOG("Unknown geometric-object-id in grid-pack. Aborting reconstruction.\n");
2392 0 : return false;
2393 : }
2394 : }
2395 : }
2396 :
2397 0 : return true;
2398 0 : }
2399 :
2400 :
2401 : ////////////////////////////////////////////////////////////////////////
2402 : // WriteSubsetIndicesToStream
2403 : // helper method for SerializeSubsetHandler
2404 : template <class TElemIter>
2405 : static
2406 0 : void WriteSubsetIndicesToStream(TElemIter iterBegin, TElemIter iterEnd,
2407 : ISubsetHandler& sh, BinaryBuffer& out)
2408 : {
2409 0 : for(;iterBegin != iterEnd; ++iterBegin)
2410 : {
2411 0 : int si = sh.get_subset_index(*iterBegin);
2412 0 : out.write((char*)&si, sizeof(int));
2413 : }
2414 0 : }
2415 :
2416 : ////////////////////////////////////////////////////////////////////////
2417 0 : bool SerializeSubsetHandler(Grid& grid, ISubsetHandler& sh,
2418 : GridObjectCollection goc,
2419 : BinaryBuffer& out)
2420 : {
2421 : // write a magic number at the beginning and at the end.
2422 0 : int magicNumber = 654664;
2423 0 : out.write((char*)&magicNumber, sizeof(int));
2424 :
2425 : // serialize subset-infos
2426 0 : int numSubsets = (int)sh.num_subsets();
2427 0 : out.write((char*)&numSubsets, sizeof(int));
2428 :
2429 0 : for(int i = 0; i < numSubsets; ++i)
2430 : {
2431 0 : SubsetInfo& si = sh.subset_info(i);
2432 : // write the name (first the size, then the rest)
2433 0 : int nameSize = si.name.size() + 1;
2434 0 : out.write((char*)&nameSize, sizeof(int));
2435 0 : out.write(si.name.c_str(), nameSize);
2436 :
2437 : // write the material index
2438 0 : out.write((char*)&si.materialIndex, sizeof(int));
2439 : // write the color
2440 0 : out.write((char*)&si.color, sizeof(vector4));
2441 : // write the subset-state
2442 0 : out.write((char*)&si.subsetState, sizeof(uint));
2443 : // write the property map
2444 0 : Serialize(out, si.m_propertyMap);
2445 : }
2446 :
2447 0 : for(size_t i = 0; i < goc.num_levels(); ++i)
2448 : {
2449 : // serialize vertex-subsets
2450 0 : WriteSubsetIndicesToStream(goc.begin<Vertex>(i),
2451 0 : goc.end<Vertex>(i),
2452 : sh, out);
2453 :
2454 : // serialize edge-subsets
2455 0 : WriteSubsetIndicesToStream(goc.begin<Edge>(i),
2456 0 : goc.end<Edge>(i),
2457 : sh, out);
2458 :
2459 : // serialize face-subsets
2460 0 : WriteSubsetIndicesToStream(goc.begin<Face>(i),
2461 0 : goc.end<Face>(i),
2462 : sh, out);
2463 :
2464 : // serialize volume-subsets
2465 0 : WriteSubsetIndicesToStream(goc.begin<Volume>(i),
2466 0 : goc.end<Volume>(i),
2467 : sh, out);
2468 : }
2469 :
2470 0 : out.write((char*)&magicNumber, sizeof(int));
2471 :
2472 0 : return true;
2473 :
2474 : }
2475 :
2476 : ////////////////////////////////////////////////////////////////////////
2477 : // SerializeSubsetHandler
2478 0 : bool SerializeSubsetHandler(Grid& grid, ISubsetHandler& sh,
2479 : BinaryBuffer& out)
2480 : {
2481 0 : return SerializeSubsetHandler(grid, sh,
2482 0 : grid.get_grid_objects(),
2483 0 : out);
2484 : }
2485 :
2486 : ////////////////////////////////////////////////////////////////////////
2487 : // ReadSubsetIndicesFromStream
2488 : // helper method for DeserializeSubsetHandler
2489 : template <class TElemIter>
2490 : static
2491 0 : void ReadSubsetIndicesFromStream(TElemIter iterBegin, TElemIter iterEnd,
2492 : ISubsetHandler& sh, BinaryBuffer& in)
2493 : {
2494 0 : for(;iterBegin != iterEnd; ++iterBegin)
2495 : {
2496 : int si;
2497 0 : in.read((char*)&si, sizeof(int));
2498 0 : sh.assign_subset(*iterBegin, si);
2499 : }
2500 0 : }
2501 :
2502 : ////////////////////////////////////////////////////////////////////////
2503 : // DeserializeSubsetHandler
2504 0 : bool DeserializeSubsetHandler(Grid& grid, ISubsetHandler& sh,
2505 : GridObjectCollection goc,
2506 : BinaryBuffer& in, bool readPropertyMap)
2507 : {
2508 : // read a magic number at the beginning and at the end.
2509 : int magicNumber = 654664;
2510 : int tInd;
2511 : // make sure that the magic number matches
2512 0 : in.read((char*)&tInd, sizeof(int));
2513 0 : UG_COND_THROW(tInd != magicNumber,
2514 : " magic-number mismatch after read in DeserializeSubsetHandler (1).\n");
2515 :
2516 : // deserialize subset-infos
2517 : int numSubsets;
2518 0 : in.read((char*)&numSubsets, sizeof(int));
2519 :
2520 : // a buffer to read the name
2521 0 : vector<char> vBuff(256);
2522 0 : for(int i = 0; i < numSubsets; ++i)
2523 : {
2524 0 : SubsetInfo& si = sh.subset_info(i);
2525 : // read the name (first the size, then the rest)
2526 : int nameSize;
2527 0 : in.read((char*)&nameSize, sizeof(int));
2528 : // check whether the buffer has to be resized
2529 0 : if(nameSize > (int)vBuff.size())
2530 0 : vBuff.resize(nameSize);
2531 : // read the name
2532 0 : in.read(&vBuff.front(), nameSize);
2533 0 : si.name = &vBuff.front();
2534 :
2535 : // read the material index
2536 0 : in.read((char*)&si.materialIndex, sizeof(int));
2537 : // read the color
2538 0 : in.read((char*)&si.color, sizeof(vector4));
2539 : // read the subset-state
2540 0 : in.read((char*)&si.subsetState, sizeof(uint));
2541 : // read the property map
2542 0 : if(readPropertyMap)
2543 0 : Deserialize(in, si.m_propertyMap);
2544 : }
2545 :
2546 :
2547 0 : for(size_t i = 0; i < goc.num_levels(); ++i)
2548 : {
2549 : // serialize vertex-subsets
2550 0 : ReadSubsetIndicesFromStream(goc.begin<Vertex>(i),
2551 0 : goc.end<Vertex>(i),
2552 : sh, in);
2553 :
2554 : // serialize edge-subsets
2555 0 : ReadSubsetIndicesFromStream(goc.begin<Edge>(i),
2556 0 : goc.end<Edge>(i),
2557 : sh, in);
2558 :
2559 : // serialize face-subsets
2560 0 : ReadSubsetIndicesFromStream(goc.begin<Face>(i),
2561 0 : goc.end<Face>(i),
2562 : sh, in);
2563 :
2564 : // serialize volume-subsets
2565 0 : ReadSubsetIndicesFromStream(goc.begin<Volume>(i),
2566 0 : goc.end<Volume>(i),
2567 : sh, in);
2568 : }
2569 :
2570 : // make sure that the magic number matches
2571 0 : in.read((char*)&tInd, sizeof(int));
2572 0 : UG_COND_THROW(tInd != magicNumber,
2573 : " magic-number mismatch after read in DeserializeSubsetHandler (2).\n");
2574 :
2575 0 : return true;
2576 0 : }
2577 :
2578 : ////////////////////////////////////////////////////////////////////////
2579 : // DeserializeSubsetHandler
2580 0 : bool DeserializeSubsetHandler(Grid& grid, ISubsetHandler& sh,
2581 : BinaryBuffer& in, bool readPropertyMap)
2582 : {
2583 0 : return DeserializeSubsetHandler(grid, sh,
2584 0 : grid.get_grid_objects(),
2585 0 : in, readPropertyMap);
2586 : }
2587 :
2588 :
2589 :
2590 : template <class TElemIter>
2591 : static
2592 0 : void WriteSelectionStatesToStream(TElemIter iterBegin, TElemIter iterEnd,
2593 : ISelector& sel, BinaryBuffer& out)
2594 : {
2595 0 : for(;iterBegin != iterEnd; ++iterBegin)
2596 : {
2597 0 : int s = sel.get_selection_status(*iterBegin);
2598 0 : out.write((char*)&s, sizeof(byte));
2599 : }
2600 0 : }
2601 :
2602 : ////////////////////////////////////////////////////////////////////////
2603 0 : bool SerializeSelector(Grid& grid, ISelector& sel,
2604 : GridObjectCollection goc,
2605 : BinaryBuffer& out)
2606 : {
2607 : // write a magic number at the beginning and at the end.
2608 0 : int magicNumber = 654664;
2609 0 : out.write((char*)&magicNumber, sizeof(int));
2610 :
2611 0 : for(size_t i = 0; i < goc.num_levels(); ++i)
2612 : {
2613 : // serialize vertex-subsets
2614 0 : WriteSelectionStatesToStream(goc.begin<Vertex>(i),
2615 0 : goc.end<Vertex>(i),
2616 : sel, out);
2617 :
2618 : // serialize edge-subsets
2619 0 : WriteSelectionStatesToStream(goc.begin<Edge>(i),
2620 0 : goc.end<Edge>(i),
2621 : sel, out);
2622 :
2623 : // serialize face-subsets
2624 0 : WriteSelectionStatesToStream(goc.begin<Face>(i),
2625 0 : goc.end<Face>(i),
2626 : sel, out);
2627 :
2628 : // serialize volume-subsets
2629 0 : WriteSelectionStatesToStream(goc.begin<Volume>(i),
2630 0 : goc.end<Volume>(i),
2631 : sel, out);
2632 : }
2633 :
2634 0 : out.write((char*)&magicNumber, sizeof(int));
2635 :
2636 0 : return true;
2637 :
2638 : }
2639 :
2640 : ////////////////////////////////////////////////////////////////////////
2641 : // SerializeSelector
2642 0 : bool SerializeSelector(Grid& grid, ISelector& sel,
2643 : BinaryBuffer& out)
2644 : {
2645 0 : return SerializeSelector(grid, sel,
2646 0 : grid.get_grid_objects(),
2647 0 : out);
2648 : }
2649 :
2650 : ////////////////////////////////////////////////////////////////////////
2651 : template <class TElemIter>
2652 : static
2653 0 : void ReadSelectionStatesFromStream(TElemIter iterBegin, TElemIter iterEnd,
2654 : ISelector& sel, BinaryBuffer& in)
2655 : {
2656 0 : for(;iterBegin != iterEnd; ++iterBegin)
2657 : {
2658 : byte s;
2659 0 : in.read((char*)&s, sizeof(byte));
2660 0 : sel.select(*iterBegin, s);
2661 : }
2662 0 : }
2663 :
2664 : ////////////////////////////////////////////////////////////////////////
2665 : // DeserializeSelector
2666 0 : bool DeserializeSelector(Grid& grid, ISelector& sel,
2667 : GridObjectCollection goc,
2668 : BinaryBuffer& in)
2669 : {
2670 : // read a magic number at the beginning and at the end.
2671 : int magicNumber = 654664;
2672 : int tInd;
2673 : // make sure that the magic number matches
2674 0 : in.read((char*)&tInd, sizeof(int));
2675 0 : UG_COND_THROW(tInd != magicNumber,
2676 : " magic-number mismatch after read in DeserializeSelector (1).\n");
2677 :
2678 0 : for(size_t i = 0; i < goc.num_levels(); ++i)
2679 : {
2680 : // serialize vertex-subsets
2681 0 : ReadSelectionStatesFromStream(goc.begin<Vertex>(i),
2682 0 : goc.end<Vertex>(i),
2683 : sel, in);
2684 :
2685 : // serialize edge-subsets
2686 0 : ReadSelectionStatesFromStream(goc.begin<Edge>(i),
2687 0 : goc.end<Edge>(i),
2688 : sel, in);
2689 :
2690 : // serialize face-subsets
2691 0 : ReadSelectionStatesFromStream(goc.begin<Face>(i),
2692 0 : goc.end<Face>(i),
2693 : sel, in);
2694 :
2695 : // serialize volume-subsets
2696 0 : ReadSelectionStatesFromStream(goc.begin<Volume>(i),
2697 0 : goc.end<Volume>(i),
2698 : sel, in);
2699 : }
2700 :
2701 : // make sure that the magic number matches
2702 0 : in.read((char*)&tInd, sizeof(int));
2703 0 : UG_COND_THROW(tInd != magicNumber,
2704 : " magic-number mismatch after read in DeserializeSelector (2).\n");
2705 :
2706 0 : return true;
2707 : }
2708 :
2709 : ////////////////////////////////////////////////////////////////////////
2710 : // DeserializeSelector
2711 0 : bool DeserializeSelector(Grid& grid, ISelector& sel,
2712 : BinaryBuffer& in)
2713 : {
2714 0 : return DeserializeSelector(grid, sel,
2715 0 : grid.get_grid_objects(),
2716 0 : in);
2717 : }
2718 :
2719 :
2720 : // void SerializeProjector(BinaryBuffer& out, RefinementProjector& proj)
2721 : // {
2722 : // static Factory<RefinementProjector, ProjectorTypes> projFac;
2723 : // static Archivar<boost::archive::text_oarchive, RefinementProjector, ProjectorTypes> archivar;
2724 :
2725 : // const string& projName = projFac.class_name(proj);
2726 :
2727 : // Serialize(out, projName);
2728 :
2729 : // stringstream ss;
2730 : // boost::archive::text_oarchive ar(ss, boost::archive::no_header);
2731 : // archivar.archive(ar, proj);
2732 :
2733 : // Serialize(out, ss.str());
2734 : // }
2735 :
2736 :
2737 : // void SerializeProjectionHandler(BinaryBuffer& out, ProjectionHandler& ph)
2738 : // {
2739 : // const int magicNumber = 978523;
2740 : // out.write((char*)&magicNumber, sizeof(int));
2741 :
2742 : // if(ph.default_projector().valid()){
2743 : // byte b = 1;
2744 : // out.write((char*)&b, sizeof(b));
2745 : // SerializeProjector(out, *ph.default_projector());
2746 : // }
2747 : // else{
2748 : // byte b = 0;
2749 : // out.write((char*)&b, sizeof(b));
2750 : // }
2751 :
2752 : // int numProjectors = (int)ph.num_projectors();
2753 : // out.write((char*)&numProjectors, sizeof(int));
2754 :
2755 : // for(int i = -1; i < numProjectors; ++i){
2756 : // if(!ph.projector(i).valid()){
2757 : // const int invInd = -2;
2758 : // out.write((char*)& invInd, sizeof(int));
2759 : // continue;
2760 : // }
2761 :
2762 : // RefinementProjector& proj= *ph.projector(i);
2763 :
2764 : // out.write((char*)& i, sizeof(int));
2765 : // SerializeProjector(out, proj);
2766 : // }
2767 : // out.write((char*)&magicNumber, sizeof(int));
2768 : // }
2769 :
2770 :
2771 : // SPRefinementProjector DeserializeProjector(BinaryBuffer& in)
2772 : // {
2773 : // static Archivar<boost::archive::text_iarchive,
2774 : // RefinementProjector,
2775 : // ProjectorTypes>
2776 : // archivar;
2777 :
2778 : // static Factory<RefinementProjector, ProjectorTypes> projFac;
2779 :
2780 : // std::string name;
2781 : // Deserialize(in, name);
2782 :
2783 : // if(name.empty())
2784 : // return SPRefinementProjector();
2785 :
2786 : // SPRefinementProjector proj = projFac.create(name);
2787 :
2788 : // std::string data;
2789 : // Deserialize(in, data);
2790 : // std::stringstream ss(data, std::ios_base::in);
2791 : // boost::archive::text_iarchive ar(ss, boost::archive::no_header);
2792 : // archivar.archive(ar, *proj);
2793 : // return proj;
2794 : // }
2795 :
2796 :
2797 : // void DeserializeProjectionHandler(BinaryBuffer& in, ProjectionHandler& ph)
2798 : // {
2799 : // const int magicNumber = 978523;
2800 : // int tmpMagicNumber;
2801 : // in.read((char*)&tmpMagicNumber, sizeof(int));
2802 : // UG_COND_THROW(tmpMagicNumber != magicNumber,
2803 : // "Magic number mismatch in DeserializeProjectionHandler (1)!");
2804 :
2805 : // byte b;
2806 : // in.read((char*)&b, sizeof(b));
2807 : // if(b){
2808 : // ph.set_default_projector(DeserializeProjector(in));
2809 : // }
2810 : // else
2811 : // ph.set_default_projector(SPRefinementProjector());
2812 :
2813 : // int numProjectors;
2814 : // in.read((char*)&numProjectors, sizeof(int));
2815 :
2816 : // for(int i = -1; i < numProjectors; ++i){
2817 : // int index;
2818 : // in.read((char*)& index, sizeof(int));
2819 : // if(index == -2)
2820 : // continue;
2821 :
2822 : // ph.set_projector(index, DeserializeProjector(in));
2823 : // }
2824 :
2825 : // in.read((char*)&tmpMagicNumber, sizeof(int));
2826 : // UG_COND_THROW(tmpMagicNumber != magicNumber,
2827 : // "Magic number mismatch in DeserializeProjectionHandler (2)!");
2828 : // }
2829 :
2830 : }// end of namespace
|