1 #include "SequenceManager.hpp"
2 #include "VertexSequence.hpp"
3 #include "UnstructuredElemSeq.hpp"
4 #include "ScdVertexData.hpp"
5 #include "MeshSetSequence.hpp"
6 #include "SweptElementSeq.hpp"
7 #include "StructuredElementSeq.hpp"
8 #include "moab/HomXform.hpp"
9 #include "PolyElementSeq.hpp"
10 #include "SysUtil.hpp"
11 #include "moab/Error.hpp"
12
13 #include <assert.h>
14 #include <new>
15 #include <algorithm>
16
17 #ifndef NDEBUG
18 #include <iostream>
19 #endif
20
21 namespace moab {
22
23 const EntityID SequenceManager::DEFAULT_VERTEX_SEQUENCE_SIZE = 512 * 1024;
24 const EntityID SequenceManager::DEFAULT_ELEMENT_SEQUENCE_SIZE = DEFAULT_VERTEX_SEQUENCE_SIZE;
25 const EntityID SequenceManager::DEFAULT_POLY_SEQUENCE_SIZE = 16 * 1024;
26 const EntityID SequenceManager::DEFAULT_MESHSET_SEQUENCE_SIZE = DEFAULT_VERTEX_SEQUENCE_SIZE;
27
28 const int UNUSED_SIZE = 0;
29
default_poly_sequence_size(int conn_len)30 EntityID SequenceManager::default_poly_sequence_size(int conn_len)
31 {
32 return std::max(DEFAULT_POLY_SEQUENCE_SIZE / conn_len, (EntityID)1);
33 }
34
~SequenceManager()35 SequenceManager::~SequenceManager()
36 {
37 // Release variable-length tag data
38 for (unsigned i = 0; i < tagSizes.size(); ++i)
39 if (tagSizes[i] == MB_VARIABLE_LENGTH)
40 release_tag_array(0, i, false);
41 }
42
clear()43 void SequenceManager::clear()
44 {
45 // reset sequence multiplier
46 sequence_multiplier = 1.0;
47
48 // Destroy all TypeSequenceManager instances
49 for (EntityType t = MBVERTEX; t < MBMAXTYPE; ++t)
50 typeData[t].~TypeSequenceManager();
51
52 // Now re-create TypeSequenceManager instances
53 for (EntityType t = MBVERTEX; t < MBMAXTYPE; ++t)
54 new (typeData + t)TypeSequenceManager();
55 }
56
get_entities(Range & entities_out) const57 void SequenceManager::get_entities(Range& entities_out) const
58 {
59 for (EntityType t = MBENTITYSET; t >= MBVERTEX; --t)
60 typeData[t].get_entities(entities_out);
61 }
62
get_entities(std::vector<EntityHandle> & entities_out) const63 void SequenceManager::get_entities(std::vector<EntityHandle>& entities_out) const
64 {
65 for (EntityType t = MBVERTEX; t != MBMAXTYPE; ++t)
66 typeData[t].get_entities(entities_out);
67 }
68
get_number_entities() const69 EntityID SequenceManager::get_number_entities() const
70 {
71 EntityID sum = 0;
72 for (EntityType t = MBVERTEX; t != MBMAXTYPE; ++t)
73 sum += typeData[t].get_number_entities();
74
75 return sum;
76 }
77
check_valid_entities(Error *,const Range & entities) const78 ErrorCode SequenceManager::check_valid_entities(Error* /* error */,
79 const Range& entities) const
80 {
81 ErrorCode rval;
82 Range::const_pair_iterator i;
83 for (i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i) {
84 const EntityType type1 = TYPE_FROM_HANDLE(i->first);
85 const EntityType type2 = TYPE_FROM_HANDLE(i->second);
86 if (type1 == type2) {
87 rval = typeData[type1].check_valid_handles(NULL, i->first, i->second);
88 if (MB_SUCCESS != rval)
89 return rval;
90 }
91 else {
92 int junk;
93 EntityHandle split = CREATE_HANDLE(type2, 0, junk);
94 rval = typeData[type1].check_valid_handles(NULL, i->first, split - 1);
95 if (MB_SUCCESS != rval)
96 return rval;
97 rval = typeData[type2].check_valid_handles(NULL, split, i->second);
98 if (MB_SUCCESS != rval)
99 return rval;
100 }
101 }
102
103 return MB_SUCCESS;
104 }
105
check_valid_entities(Error *,const EntityHandle * entities,size_t num_entities,bool root_set_okay) const106 ErrorCode SequenceManager::check_valid_entities(Error* /* error_handler */,
107 const EntityHandle* entities,
108 size_t num_entities,
109 bool root_set_okay) const
110 {
111 ErrorCode rval;
112 const EntitySequence* ptr = 0;
113
114 const EntityHandle* const end = entities + num_entities;
115 for (; entities < end; ++entities) {
116 rval = find(*entities, ptr);
117 if (MB_SUCCESS != rval && !(root_set_okay && !*entities)) {
118 if (MB_ENTITY_NOT_FOUND == rval) {
119 // MB_ENTITY_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
120 # if 0
121 fprintf(stderr, "[Warning]: Invalid entity handle: 0x%lx\n", (unsigned long)*entities);
122 # endif
123 }
124 return rval;
125 }
126 }
127
128 return MB_SUCCESS;
129 }
130
delete_entity(Error *,EntityHandle entity)131 ErrorCode SequenceManager::delete_entity(Error* /* error */, EntityHandle entity)
132 {
133 return typeData[TYPE_FROM_HANDLE(entity)].erase(NULL, entity);
134 }
135
delete_entities(Error *,const Range & entities)136 ErrorCode SequenceManager::delete_entities(Error* /* error */, const Range& entities)
137 {
138 ErrorCode rval = check_valid_entities(NULL, entities);
139 if (MB_SUCCESS != rval)
140 return rval;
141
142 ErrorCode result = MB_SUCCESS;
143 Range::const_pair_iterator i;
144 for (i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i) {
145 const EntityType type1 = TYPE_FROM_HANDLE(i->first);
146 const EntityType type2 = TYPE_FROM_HANDLE(i->second);
147 if (type1 == type2) {
148 rval = typeData[type1].erase(NULL, i->first, i->second);
149 if (MB_SUCCESS != rval)
150 return result = rval;
151 }
152 else {
153 int junk;
154 EntityHandle split = CREATE_HANDLE(type2, 0, junk);
155 rval = typeData[type1].erase(NULL, i->first, split - 1);
156 if (MB_SUCCESS != rval)
157 return result = rval;
158 rval = typeData[type2].erase(NULL, split, i->second);
159 if (MB_SUCCESS != rval)
160 return result = rval;
161 }
162 }
163
164 return result;
165 }
166
create_vertex(const double coords[3],EntityHandle & handle)167 ErrorCode SequenceManager::create_vertex(const double coords[3],
168 EntityHandle& handle)
169 {
170 const EntityHandle start = CREATE_HANDLE(MBVERTEX, MB_START_ID);
171 const EntityHandle end = CREATE_HANDLE(MBVERTEX, MB_END_ID);
172 bool append;
173 TypeSequenceManager::iterator seq = typeData[MBVERTEX].find_free_handle(start, end, append);
174 VertexSequence* vseq;
175
176 if (seq == typeData[MBVERTEX].end()) {
177 SequenceData* seq_data = 0;
178 EntityID seq_data_size = 0;
179 handle = typeData[MBVERTEX].find_free_sequence(DEFAULT_VERTEX_SEQUENCE_SIZE, start, end, seq_data, seq_data_size);
180 if (!handle)
181 return MB_FAILURE;
182
183 if (seq_data)
184 vseq = new VertexSequence(handle, 1, seq_data);
185 else
186 vseq = new VertexSequence(handle, 1, DEFAULT_VERTEX_SEQUENCE_SIZE);
187
188 ErrorCode rval = typeData[MBVERTEX].insert_sequence(vseq);
189 if (MB_SUCCESS != rval) {
190 SequenceData* vdata = vseq->data();
191 delete vseq;
192 if (!seq_data)
193 delete vdata;
194
195 return rval;
196 }
197 }
198 else {
199 vseq = reinterpret_cast<VertexSequence*>(*seq);
200 if (append) {
201 vseq->push_back(1);
202 handle = vseq->end_handle();
203 typeData[MBVERTEX].notify_appended(seq);
204 }
205 else {
206 vseq->push_front(1);
207 handle = vseq->start_handle();
208 typeData[MBVERTEX].notify_prepended(seq);
209 }
210 }
211
212 return vseq->set_coordinates(handle, coords);
213 }
214
create_element(EntityType type,const EntityHandle * conn,unsigned conn_len,EntityHandle & handle)215 ErrorCode SequenceManager::create_element(EntityType type,
216 const EntityHandle* conn,
217 unsigned conn_len,
218 EntityHandle& handle)
219 {
220 if (type <= MBVERTEX || type >= MBENTITYSET)
221 return MB_TYPE_OUT_OF_RANGE;
222
223 const EntityHandle start = CREATE_HANDLE(type, MB_START_ID);
224 const EntityHandle end = CREATE_HANDLE(type, MB_END_ID);
225 bool append;
226 TypeSequenceManager::iterator seq = typeData[type].find_free_handle(start, end, append, conn_len);
227 UnstructuredElemSeq* eseq;
228
229 if (seq == typeData[type].end()) {
230 SequenceData* seq_data = 0;
231 unsigned size = DEFAULT_ELEMENT_SEQUENCE_SIZE;
232 if (type == MBPOLYGON || type == MBPOLYHEDRON) {
233 size = default_poly_sequence_size(conn_len);
234 }
235 EntityID seq_data_size = 0;
236 handle = typeData[type].find_free_sequence(size, start, end, seq_data, seq_data_size, conn_len);
237 if (!handle)
238 return MB_FAILURE;
239
240 if (MBPOLYGON == type || MBPOLYHEDRON == type) {
241 if (seq_data)
242 eseq = new PolyElementSeq(handle, 1, conn_len, seq_data);
243 else
244 eseq = new PolyElementSeq(handle, 1, conn_len, size);
245 }
246 else {
247 if (seq_data)
248 eseq = new UnstructuredElemSeq(handle, 1, conn_len, seq_data);
249 else
250 eseq = new UnstructuredElemSeq(handle, 1, conn_len, size);
251 }
252
253 ErrorCode rval = typeData[type].insert_sequence(eseq);
254 if (MB_SUCCESS != rval) {
255 SequenceData* vdata = eseq->data();
256 delete eseq;
257 if (!seq_data)
258 delete vdata;
259
260 return rval;
261 }
262 }
263 else {
264 eseq = reinterpret_cast<UnstructuredElemSeq*>(*seq);
265 if (append) {
266 eseq->push_back(1);
267 handle = eseq->end_handle();
268 typeData[type].notify_appended(seq);
269 }
270 else {
271 eseq->push_front(1);
272 handle = eseq->start_handle();
273 typeData[type].notify_prepended(seq);
274 }
275 }
276
277 return eseq->set_connectivity(handle, conn, conn_len);
278 }
279
create_mesh_set(unsigned flags,EntityHandle & handle)280 ErrorCode SequenceManager::create_mesh_set(unsigned flags,
281 EntityHandle& handle)
282 {
283 const EntityHandle start = CREATE_HANDLE(MBENTITYSET, MB_START_ID);
284 const EntityHandle end = CREATE_HANDLE(MBENTITYSET, MB_END_ID);
285 bool append;
286 TypeSequenceManager::iterator seq = typeData[MBENTITYSET].find_free_handle(start, end, append);
287 MeshSetSequence* msseq;
288
289 if (seq == typeData[MBENTITYSET].end()) {
290 SequenceData* seq_data = 0;
291 EntityID seq_data_size = 0;
292 handle = typeData[MBENTITYSET].find_free_sequence(DEFAULT_MESHSET_SEQUENCE_SIZE, start, end, seq_data, seq_data_size);
293 if (!handle)
294 return MB_FAILURE;
295
296 if (seq_data)
297 msseq = new MeshSetSequence(handle, 1, flags, seq_data);
298 else
299 msseq = new MeshSetSequence(handle, 1, flags, DEFAULT_MESHSET_SEQUENCE_SIZE);
300
301 ErrorCode rval = typeData[MBENTITYSET].insert_sequence(msseq);
302 if (MB_SUCCESS != rval) {
303 SequenceData* vdata = msseq->data();
304 delete msseq;
305 if (!seq_data)
306 delete vdata;
307
308 return rval;
309 }
310 }
311 else {
312 msseq = reinterpret_cast<MeshSetSequence*>(*seq);
313 if (append) {
314 msseq->push_back(1, &flags);
315 handle = msseq->end_handle();
316 typeData[MBENTITYSET].notify_appended(seq);
317 }
318 else {
319 msseq->push_front(1, &flags);
320 handle = msseq->start_handle();
321 typeData[MBENTITYSET].notify_prepended(seq);
322 }
323 }
324
325 return MB_SUCCESS;
326 }
327
allocate_mesh_set(EntityHandle handle,unsigned flags)328 ErrorCode SequenceManager::allocate_mesh_set(EntityHandle handle,
329 unsigned flags)
330 {
331 SequenceData* data = 0;
332 TypeSequenceManager::iterator seqptr;
333 EntityHandle block_start = 1, block_end = 0;
334 ErrorCode rval = typeData[MBENTITYSET].is_free_handle(handle, seqptr, data, block_start, block_end);
335 if (MB_SUCCESS != rval)
336 return rval;
337
338 MeshSetSequence* seq;
339 if (seqptr != typeData[MBENTITYSET].end()) {
340 seq = static_cast<MeshSetSequence*>(*seqptr);
341 if (seq->start_handle() - 1 == handle) {
342 rval = seq->push_front(1, &flags);
343 if (MB_SUCCESS == rval) {
344 rval = typeData[MBENTITYSET].notify_prepended(seqptr);
345 if (MB_SUCCESS != rval)
346 seq->pop_front(1);
347 }
348 return rval;
349 }
350 else if (seq->end_handle() + 1 == handle) {
351 rval = seq->push_back(1, &flags);
352 if (MB_SUCCESS == rval) {
353 rval = typeData[MBENTITYSET].notify_appended(seqptr);
354 if (MB_SUCCESS != rval)
355 seq->pop_back(1);
356 }
357 return rval;
358 }
359 else
360 return MB_FAILURE; // Should be unreachable
361 }
362 else {
363 if (data) {
364 seq = new MeshSetSequence(handle, 1, flags, data);
365 }
366 else {
367 assert(handle >= block_start && handle <= block_end);
368 trim_sequence_block(handle, block_end, DEFAULT_MESHSET_SEQUENCE_SIZE);
369 seq = new MeshSetSequence(handle, 1, flags, block_end - handle + 1);
370 }
371
372 rval = typeData[MBENTITYSET].insert_sequence(seq);
373 if (MB_SUCCESS != rval) {
374 SequenceData* vdata = seq->data();
375 delete seq;
376 if (!data)
377 delete vdata;
378 return rval;
379 }
380
381 return MB_SUCCESS;
382 }
383 }
384
trim_sequence_block(EntityHandle start_handle,EntityHandle & end_handle,unsigned max_size)385 void SequenceManager::trim_sequence_block(EntityHandle start_handle,
386 EntityHandle& end_handle,
387 unsigned max_size)
388 {
389 assert(end_handle >= start_handle);
390 assert((int)max_size > 0); // Cast to int also prohibits some ridiculously large values
391
392 // If input range is larger than preferred size, trim it
393 if (end_handle - start_handle >= max_size)
394 end_handle = start_handle + max_size - 1;
395 }
396
sequence_start_handle(EntityType type,EntityID count,int size,EntityID start,SequenceData * & data,EntityID & data_size)397 EntityHandle SequenceManager::sequence_start_handle(EntityType type,
398 EntityID count,
399 int size,
400 EntityID start,
401 SequenceData*& data,
402 EntityID &data_size)
403 {
404 TypeSequenceManager &tsm = typeData[type];
405 data = 0;
406 EntityHandle handle = CREATE_HANDLE(type, start);
407 if (start < MB_START_ID ||
408 !tsm.is_free_sequence(handle, count, data, size)) {
409 EntityHandle pstart = CREATE_HANDLE(type, MB_START_ID);
410 EntityHandle pend = CREATE_HANDLE(type, MB_END_ID);
411 handle = tsm.find_free_sequence(count, pstart, pend, data, data_size, size);
412 }
413
414 return handle;
415 }
416
new_sequence_size(EntityHandle start,EntityID requested_size,int sequence_size) const417 EntityID SequenceManager::new_sequence_size(EntityHandle start,
418 EntityID requested_size,
419 int sequence_size) const
420 {
421
422 requested_size = (EntityID) (this->sequence_multiplier*requested_size);
423
424 if (sequence_size < (int)requested_size)
425 return requested_size;
426
427 EntityHandle last = typeData[TYPE_FROM_HANDLE(start)].last_free_handle(start);
428 if (!last) {
429 assert(false);
430 return 0;
431 }
432
433 EntityID available_size = last - start + 1;
434 if (sequence_size < available_size)
435 return sequence_size;
436 else
437 return available_size;
438 }
439
create_entity_sequence(EntityType type,EntityID count,int size,EntityID start,EntityHandle & handle,EntitySequence * & sequence,int sequence_size)440 ErrorCode SequenceManager::create_entity_sequence(EntityType type,
441 EntityID count,
442 int size,
443 EntityID start,
444 EntityHandle& handle,
445 EntitySequence*& sequence,
446 int sequence_size)
447 {
448 SequenceData* data = NULL;
449 EntityID data_size = 0;
450 handle = sequence_start_handle(type, count, size, start, data, data_size);
451
452 if (!handle)
453 return MB_MEMORY_ALLOCATION_FAILED;
454
455 switch (type) {
456 case MBENTITYSET:
457 case MBMAXTYPE:
458 return MB_TYPE_OUT_OF_RANGE;
459
460 case MBVERTEX:
461 if (size != 0)
462 return MB_INDEX_OUT_OF_RANGE;
463
464 if (data)
465 sequence = new VertexSequence(handle, count, data);
466 else {
467 if (!data_size)
468 data_size = new_sequence_size(handle, count, sequence_size);
469 sequence = new VertexSequence(handle, count, data_size);
470 }
471 break;
472
473 case MBPOLYGON:
474 case MBPOLYHEDRON:
475 if (size == 0)
476 return MB_INDEX_OUT_OF_RANGE;
477
478 if (data)
479 sequence = new PolyElementSeq(handle, count, size, data);
480 else {
481 if (!data_size)
482 data_size = new_sequence_size(handle, count,
483 (-1 == sequence_size ? default_poly_sequence_size(size) :
484 sequence_size));
485 sequence = new PolyElementSeq(handle, count, size, data_size);
486 }
487 break;
488
489 default:
490 if (size == 0)
491 return MB_INDEX_OUT_OF_RANGE;
492
493 if (data)
494 sequence = new UnstructuredElemSeq(handle, count, size, data);
495 else {
496 if (!data_size)
497 data_size = new_sequence_size(handle, count, sequence_size);
498 sequence = new UnstructuredElemSeq(handle, count, size, data_size);
499 }
500 // tjt calling new_sequence_size 'cuz don't have a sequence data;
501 // start 41467, count 246
502 break;
503 }
504
505 ErrorCode result = typeData[type].insert_sequence(sequence);
506 if (MB_SUCCESS != result) {
507 // Change to NULL if had an existing data or if no existing data,
508 // change to the new data created
509 data = data ? 0 : sequence->data();
510 delete sequence;
511 delete data;
512 return result;
513 }
514
515 return MB_SUCCESS;
516 }
517
create_meshset_sequence(EntityID count,EntityID start,const unsigned * flags,EntityHandle & handle,EntitySequence * & sequence)518 ErrorCode SequenceManager::create_meshset_sequence(EntityID count,
519 EntityID start,
520 const unsigned* flags,
521 EntityHandle& handle,
522 EntitySequence*& sequence)
523 {
524 SequenceData* data = 0;
525 EntityID data_size = 0;
526 handle = sequence_start_handle(MBENTITYSET, count, 0, start, data, data_size);
527
528 if (!handle)
529 return MB_MEMORY_ALLOCATION_FAILED;
530
531 if (data)
532 sequence = new MeshSetSequence(handle, count, flags, data);
533 else
534 sequence = new MeshSetSequence(handle, count, flags, count);
535
536 ErrorCode result = typeData[MBENTITYSET].insert_sequence(sequence);
537 if (MB_SUCCESS != result) {
538 // Change to NULL if had an existing data or if no existing data,
539 // change to the new data created
540 data = data ? 0 : sequence->data();
541 delete sequence;
542 delete data;
543 return result;
544 }
545
546 return MB_SUCCESS;
547 }
548
create_meshset_sequence(EntityID count,EntityID start,unsigned flags,EntityHandle & handle,EntitySequence * & sequence)549 ErrorCode SequenceManager::create_meshset_sequence(EntityID count,
550 EntityID start,
551 unsigned flags,
552 EntityHandle& handle,
553 EntitySequence*& sequence)
554 {
555 SequenceData* data = 0;
556 EntityID data_size = 0;
557 handle = sequence_start_handle(MBENTITYSET, count, 0, start, data, data_size);
558 if (!handle)
559 return MB_MEMORY_ALLOCATION_FAILED;
560
561 if (data)
562 sequence = new MeshSetSequence(handle, count, flags, data);
563 else
564 sequence = new MeshSetSequence(handle, count, flags, count);
565
566 ErrorCode result = typeData[MBENTITYSET].insert_sequence(sequence);
567 if (MB_SUCCESS != result) {
568 // Change to NULL if had an existing data or if no existing data,
569 // change to the new data created
570 data = data ? 0 : sequence->data();
571 delete sequence;
572 delete data;
573 return result;
574 }
575
576 return MB_SUCCESS;
577 }
578
create_scd_sequence(int imin,int jmin,int kmin,int imax,int jmax,int kmax,EntityType type,EntityID start_id_hint,EntityHandle & handle,EntitySequence * & sequence,int * is_periodic)579 ErrorCode SequenceManager::create_scd_sequence(int imin, int jmin, int kmin,
580 int imax, int jmax, int kmax,
581 EntityType type,
582 EntityID start_id_hint,
583 EntityHandle& handle,
584 EntitySequence*& sequence,
585 int *is_periodic)
586 {
587 int this_dim = CN::Dimension(type);
588
589 // Use > instead of != in the following assert to also catch cases where imin > imax, etc.
590 assert((this_dim < 3 || kmax > kmin) &&
591 (this_dim < 2 || jmax > jmin) &&
592 (this_dim < 1 || imax > imin));
593
594 // Compute # entities; not as easy as it would appear...
595 EntityID num_ent;
596 if (MBVERTEX == type)
597 num_ent = (EntityID)(imax - imin + 1) * (EntityID)(jmax - jmin + 1) * (EntityID)(kmax - kmin + 1);
598 else {
599 num_ent = (imax-imin + (is_periodic && is_periodic[0] ? 1 : 0)) *
600 (this_dim >= 2 ? (jmax - jmin + (is_periodic && is_periodic[1] ? 1 : 0)) : 1) *
601 (this_dim >= 3 ? (kmax - kmin) : 1);
602 }
603
604 if (MBVERTEX == type && (is_periodic && (is_periodic[0] || is_periodic[1])))
605 return MB_FAILURE;
606
607 // Get a start handle
608 SequenceData* data = 0;
609 EntityID data_size = 0;
610 handle = sequence_start_handle(type, num_ent, -1, start_id_hint, data, data_size);
611
612 if (!handle)
613 return MB_MEMORY_ALLOCATION_FAILED;
614 assert(!data);
615
616 switch (type) {
617 case MBVERTEX:
618 data = new ScdVertexData(handle, imin, jmin, kmin, imax, jmax, kmax);
619 sequence = new VertexSequence(handle, data->size(), data);
620 break;
621 case MBEDGE:
622 case MBQUAD:
623 case MBHEX:
624 sequence = new StructuredElementSeq(handle, imin, jmin, kmin, imax, jmax, kmax,
625 is_periodic);
626 break;
627 default:
628 return MB_TYPE_OUT_OF_RANGE;
629 }
630
631 ErrorCode result = typeData[type].insert_sequence(sequence);
632 if (MB_SUCCESS != result) {
633 data = sequence->data();
634 delete sequence;
635 delete data;
636 return result;
637 }
638
639 return MB_SUCCESS;
640 }
641
create_scd_sequence(const HomCoord & coord_min,const HomCoord & coord_max,EntityType type,EntityID start_id_hint,EntityHandle & first_handle_out,EntitySequence * & sequence_out,int * is_periodic)642 ErrorCode SequenceManager::create_scd_sequence(const HomCoord& coord_min,
643 const HomCoord& coord_max,
644 EntityType type,
645 EntityID start_id_hint,
646 EntityHandle& first_handle_out,
647 EntitySequence*& sequence_out,
648 int *is_periodic)
649 {
650 return create_scd_sequence(coord_min.i(), coord_min.j(), coord_min.k(),
651 coord_max.i(), coord_max.j(), coord_max.k(),
652 type, start_id_hint,
653 first_handle_out, sequence_out, is_periodic);
654 }
655
create_sweep_sequence(int imin,int jmin,int kmin,int imax,int jmax,int kmax,int * Cq,EntityType type,EntityID start_id_hint,EntityHandle & handle,EntitySequence * & sequence)656 ErrorCode SequenceManager::create_sweep_sequence(int imin, int jmin, int kmin,
657 int imax, int jmax, int kmax,
658 int* Cq,
659 EntityType type,
660 EntityID start_id_hint,
661 EntityHandle& handle,
662 EntitySequence*& sequence)
663 {
664 int this_dim = CN::Dimension(type);
665
666 assert((this_dim < 3 || kmax > kmin) &&
667 (this_dim < 2 || jmax > jmin) &&
668 (this_dim < 1 || imax > imin));
669
670 EntityID num_ent;
671 if (MBVERTEX == type)
672 num_ent = (EntityID)(imax - imin + 1) * (EntityID)(jmax - jmin + 1) * (EntityID)(kmax - kmin + 1);
673 else {
674 num_ent = (imax-imin) *
675 (this_dim >= 2 ? (jmax - jmin) : 1) *
676 (this_dim >= 3 ? (kmax - kmin) : 1);
677 }
678
679 // Get a start handle
680 SequenceData* data = 0;
681 EntityID data_size = 0;
682 handle = sequence_start_handle(type, num_ent, -1, start_id_hint, data, data_size);
683
684 if (!handle)
685 return MB_MEMORY_ALLOCATION_FAILED;
686 assert(!data);
687
688 switch (type) {
689 case MBVERTEX:
690 data = new ScdVertexData(handle, imin, jmin, kmin, imax, jmax, kmax);
691 sequence = new VertexSequence(handle, data->size(), data);
692 break;
693 case MBEDGE:
694 case MBQUAD:
695 case MBHEX:
696 sequence = new SweptElementSeq(handle, imin, jmin, kmin, imax, jmax, kmax, Cq);
697 break;
698 default:
699 return MB_TYPE_OUT_OF_RANGE;
700 }
701
702 ErrorCode result = typeData[type].insert_sequence(sequence);
703 if (MB_SUCCESS != result) {
704 data = sequence->data();
705 delete sequence;
706 delete data;
707 return result;
708 }
709
710 return MB_SUCCESS;
711 }
712
create_sweep_sequence(const HomCoord & coord_min,const HomCoord & coord_max,int * Cq,EntityType type,EntityID start_id_hint,EntityHandle & first_handle_out,EntitySequence * & sequence_out)713 ErrorCode SequenceManager::create_sweep_sequence(const HomCoord& coord_min,
714 const HomCoord& coord_max,
715 int* Cq,
716 EntityType type,
717 EntityID start_id_hint,
718 EntityHandle& first_handle_out,
719 EntitySequence*& sequence_out)
720 {
721 return create_sweep_sequence(coord_min.i(), coord_min.j(), coord_min.k(),
722 coord_max.i(), coord_max.j(), coord_max.k(),
723 Cq,
724 type, start_id_hint,
725 first_handle_out, sequence_out);
726 }
727
add_vsequence(EntitySequence * vert_seq,EntitySequence * elem_seq,const HomCoord & p1,const HomCoord & q1,const HomCoord & p2,const HomCoord & q2,const HomCoord & p3,const HomCoord & q3,bool bb_input,const HomCoord * bb_min,const HomCoord * bb_max)728 ErrorCode SequenceManager::add_vsequence(EntitySequence *vert_seq,
729 EntitySequence *elem_seq,
730 const HomCoord &p1, const HomCoord &q1,
731 const HomCoord &p2, const HomCoord &q2,
732 const HomCoord &p3, const HomCoord &q3,
733 bool bb_input,
734 const HomCoord *bb_min,
735 const HomCoord *bb_max)
736 {
737 // Check first that they're structured vtx/elem sequences
738 ScdVertexData *scd_vd = dynamic_cast<ScdVertexData*>(vert_seq->data());
739 if (!scd_vd)
740 return MB_FAILURE;
741
742 ScdElementData *scd_ed = dynamic_cast<ScdElementData*>(elem_seq->data());
743 if (!scd_ed)
744 return MB_FAILURE;
745
746 if (bb_min && bb_max)
747 return scd_ed->add_vsequence(scd_vd, p1, q1, p2, q2, p3, q3,
748 bb_input, *bb_min, *bb_max);
749 else
750 return scd_ed->add_vsequence(scd_vd, p1, q1, p2, q2, p3, q3,
751 bb_input, HomCoord::unitv[0], HomCoord::unitv[0]);
752 }
753
replace_subsequence(EntitySequence * new_seq)754 ErrorCode SequenceManager::replace_subsequence(EntitySequence* new_seq)
755 {
756 const EntityType type = TYPE_FROM_HANDLE(new_seq->start_handle());
757 return typeData[type].replace_subsequence(new_seq, &tagSizes[0], tagSizes.size());
758 }
759
get_memory_use(unsigned long long & total_entity_storage,unsigned long long & total_storage) const760 void SequenceManager::get_memory_use(unsigned long long& total_entity_storage,
761 unsigned long long& total_storage) const
762
763 {
764 total_entity_storage = 0;
765 total_storage = 0;
766 unsigned long long temp_entity, temp_total;
767 for (EntityType i = MBVERTEX; i < MBMAXTYPE; ++i) {
768 temp_entity = temp_total = 0;
769 get_memory_use(i, temp_entity, temp_total);
770 total_entity_storage += temp_entity;
771 total_storage += temp_total;
772 }
773 }
774
get_memory_use(EntityType type,unsigned long long & total_entity_storage,unsigned long long & total_storage) const775 void SequenceManager::get_memory_use(EntityType type,
776 unsigned long long& total_entity_storage,
777 unsigned long long& total_storage) const
778 {
779 typeData[type].get_memory_use(total_entity_storage, total_storage);
780 }
781
get_memory_use(const Range & entities,unsigned long long & total_entity_storage,unsigned long long & total_amortized_storage) const782 void SequenceManager::get_memory_use(const Range& entities,
783 unsigned long long& total_entity_storage,
784 unsigned long long& total_amortized_storage) const
785 {
786 total_entity_storage = 0;
787 total_amortized_storage = 0;
788 unsigned long long temp_entity, temp_total;
789 Range::const_pair_iterator i;
790 for (i = entities.const_pair_begin(); i != entities.const_pair_end(); ++i) {
791 const EntityType t1 = TYPE_FROM_HANDLE(i->first);
792 const EntityType t2 = TYPE_FROM_HANDLE(i->second);
793 if (t1 == t2) {
794 temp_entity = temp_total = 0;
795 typeData[t1].get_memory_use(i->first, i->second, temp_entity, temp_total);
796 total_entity_storage += temp_entity;
797 total_amortized_storage += temp_total;
798 }
799 else {
800 int junk;
801
802 temp_entity = temp_total = 0;
803 typeData[t1].get_memory_use(i->first, CREATE_HANDLE(t1, MB_END_ID, junk), temp_entity, temp_total);
804 total_entity_storage += temp_entity;
805 total_amortized_storage += temp_total;
806
807 temp_entity = temp_total = 0;
808 typeData[t2].get_memory_use(CREATE_HANDLE(t2, MB_START_ID, junk), i->second, temp_entity, temp_total);
809 total_entity_storage += temp_entity;
810 total_amortized_storage += temp_total;
811 }
812 }
813 }
814
reserve_tag_array(Error *,int size,int & index)815 ErrorCode SequenceManager::reserve_tag_array(Error* /* error_handler */,
816 int size, int& index)
817 {
818 if (size < 1 && size != MB_VARIABLE_LENGTH) {
819 MB_SET_ERR(MB_INVALID_SIZE, "Invalid tag size: " << size);
820 }
821
822 std::vector<int>::iterator i = std::find(tagSizes.begin(), tagSizes.end(), UNUSED_SIZE);
823 if (i == tagSizes.end()) {
824 index = tagSizes.size();
825 tagSizes.push_back(size);
826 }
827 else {
828 index = i - tagSizes.begin();
829 *i = size;
830 }
831
832 return MB_SUCCESS;
833 }
834
release_tag_array(Error *,int index,bool release_id)835 ErrorCode SequenceManager::release_tag_array(Error* /* error_handler */,
836 int index, bool release_id)
837 {
838 if ((unsigned)index >= tagSizes.size() || UNUSED_SIZE == tagSizes[index]) {
839 // MB_TAG_NOT_FOUND could be a non-error condition, do not call MB_SET_ERR on it
840 #if 0
841 fprintf(stderr, "[Warning]: Invalid dense tag index: %d\n", index);
842 #endif
843 return MB_TAG_NOT_FOUND;
844 }
845
846 for (EntityType t = MBVERTEX; t <= MBENTITYSET; ++t) {
847 TypeSequenceManager& seqs = entity_map(t);
848 for (TypeSequenceManager::iterator i = seqs.begin(); i != seqs.end(); ++i)
849 (*i)->data()->release_tag_data(index, tagSizes[index]);
850 }
851
852 if (release_id)
853 tagSizes[index] = UNUSED_SIZE;
854
855 return MB_SUCCESS;
856 }
857
858 // These are meant to be called from the debugger (not declared in any header)
859 // so leave them out of release builds (-DNDEBUG).
860 #ifndef NDEBUG
861
operator <<(std::ostream & s,const TypeSequenceManager & seq_man)862 std::ostream& operator<<(std::ostream& s, const TypeSequenceManager& seq_man)
863 {
864 const SequenceData* prev_data = 0;
865 for (TypeSequenceManager::const_iterator i = seq_man.begin(); i != seq_man.end(); ++i) {
866 const EntitySequence* seq = *i;
867 if (seq->data() != prev_data) {
868 prev_data = seq->data();
869 s << "SequenceData ["
870 << ID_FROM_HANDLE(seq->data()->start_handle())
871 << ","
872 << ID_FROM_HANDLE(seq->data()->end_handle())
873 << "]"
874 << std::endl;
875 }
876 s << " Sequence ["
877 << ID_FROM_HANDLE(seq->start_handle())
878 << ","
879 << ID_FROM_HANDLE(seq->end_handle())
880 << "]"
881 << std::endl;
882 }
883
884 return s;
885 }
886
operator <<(std::ostream & s,const SequenceManager & seq_man)887 std::ostream& operator<<(std::ostream& s, const SequenceManager& seq_man)
888 {
889 for (EntityType t = MBVERTEX; t < MBMAXTYPE; ++t) {
890 if (!seq_man.entity_map(t).empty())
891 s << std::endl
892 << "****************** " << CN::EntityTypeName(t) << " ******************"
893 << std::endl << seq_man.entity_map(t) << std::endl;
894 }
895
896 return s;
897 }
898
print_sequences(const SequenceManager & seqman)899 void print_sequences(const SequenceManager& seqman)
900 {
901 std::cout << seqman << std::endl;
902 }
903
print_sequences(const TypeSequenceManager & seqman)904 void print_sequences(const TypeSequenceManager& seqman)
905 {
906 std::cout << seqman << std::endl;
907 }
908
909 #endif
910
911 } // namespace moab
912