vtkPV3Foam.C 20.3 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
Mark Olesen's avatar
Mark Olesen committed
5
    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM; if not, write to the Free Software Foundation,
    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

\*---------------------------------------------------------------------------*/

#include "vtkPV3Foam.H"
Mark Olesen's avatar
Mark Olesen committed
28
#include "vtkPV3FoamReader.h"
29
30
31

// Foam includes
#include "fvMesh.H"
Mark Olesen's avatar
Mark Olesen committed
32
#include "Time.H"
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "patchZones.H"

// VTK includes
#include "vtkDataArraySelection.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkRenderer.h"
#include "vtkTextActor.h"
#include "vtkTextProperty.h"

// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

defineTypeNameAndDebug(Foam::vtkPV3Foam, 0);

// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //

48
#include "vtkPV3FoamAddToSelection.H"
Mark Olesen's avatar
Mark Olesen committed
49
#include "vtkPV3FoamUpdateInfoFields.H"
50

Mark Olesen's avatar
Mark Olesen committed
51
void Foam::vtkPV3Foam::resetCounters()
52
{
Mark Olesen's avatar
Mark Olesen committed
53
54
55
56
57
58
59
60
61
62
    // Reset mesh part ids and sizes
    partInfoVolume_.reset();
    partInfoPatches_.reset();
    partInfoLagrangian_.reset();
    partInfoCellZones_.reset();
    partInfoFaceZones_.reset();
    partInfoPointZones_.reset();
    partInfoCellSets_.reset();
    partInfoFaceSets_.reset();
    partInfoPointSets_.reset();
63
64
65
}


Mark Olesen's avatar
Mark Olesen committed
66
void Foam::vtkPV3Foam::reduceMemory()
67
{
Mark Olesen's avatar
Mark Olesen committed
68
    forAll(regionPolyDecomp_, i)
69
    {
Mark Olesen's avatar
Mark Olesen committed
70
        regionPolyDecomp_[i].clear();
71
72
    }

Mark Olesen's avatar
Mark Olesen committed
73
    forAll(zonePolyDecomp_, i)
74
    {
Mark Olesen's avatar
Mark Olesen committed
75
        zonePolyDecomp_[i].clear();
76
77
    }

Mark Olesen's avatar
Mark Olesen committed
78
79
80
81
    forAll(csetPolyDecomp_, i)
    {
        csetPolyDecomp_[i].clear();
    }
82
83
84
85
86
87

    if (!reader_->GetCacheMesh())
    {
        delete meshPtr_;
        meshPtr_ = NULL;
    }
88
89
90
91
92
}




Mark Olesen's avatar
Mark Olesen committed
93
int Foam::vtkPV3Foam::setTime(int nRequest, const double requestTimes[])
94
95
96
{
    if (debug)
    {
Mark Olesen's avatar
Mark Olesen committed
97
98
99
100
101
102
103
104
105
106
107
        Info<< "<beg> Foam::vtkPV3Foam::setTime(";
        for (int requestI = 0; requestI < nRequest; ++requestI)
        {
            if (requestI)
            {
                Info<< ", ";
            }

            Info<< requestTimes[requestI];
        }
        Info << ") - previousIndex = " << timeIndex_ << endl;
108
109
110
111
112
    }

    Time& runTime = dbPtr_();

    // Get times list
113
    instantList Times = runTime.times();
114

Mark Olesen's avatar
Mark Olesen committed
115
116
117
118
119
120
121
122
123
124
125
    int nearestIndex = timeIndex_;
    for (int requestI = 0; requestI < nRequest; ++requestI)
    {
        int index = Time::findClosestTimeIndex(Times, requestTimes[requestI]);
        if (index >= 0 && index != timeIndex_)
        {
            nearestIndex = index;
            break;
        }
    }

Mark Olesen's avatar
Mark Olesen committed
126
    if (nearestIndex < 0)
127
128
129
130
    {
        nearestIndex = 0;
    }

Mark Olesen's avatar
Mark Olesen committed
131

Mark Olesen's avatar
Mark Olesen committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    // see what has changed
    if (timeIndex_ != nearestIndex)
    {
        timeIndex_ = nearestIndex;
        runTime.setTime(Times[nearestIndex], nearestIndex);

        // the fields change each time
        fieldsChanged_ = true;

        if (meshPtr_)
        {
            if (meshPtr_->readUpdate() != polyMesh::UNCHANGED)
            {
                meshChanged_ = true;
            }
        }
        else
        {
            meshChanged_ = true;
        }
Mark Olesen's avatar
Mark Olesen committed
152
153
154
155
156

        reader_->UpdateProgress(0.05);

        // this seems to be needed for catching Lagrangian fields
        updateInfo();
Mark Olesen's avatar
Mark Olesen committed
157
    }
158

159
160
    if (debug)
    {
Mark Olesen's avatar
Mark Olesen committed
161
162
163
164
165
        Info<< "<end> Foam::vtkPV3Foam::setTime() - selectedTime="
            << Times[nearestIndex].name() << " index=" << timeIndex_
            << "/" << Times.size()
            << " meshChanged=" << Switch(meshChanged_)
            << " fieldsChanged=" << Switch(fieldsChanged_) << endl;
166
167
    }

Mark Olesen's avatar
Mark Olesen committed
168
    return nearestIndex;
169
170
171
}


Mark Olesen's avatar
Mark Olesen committed
172
void Foam::vtkPV3Foam::updateMeshPartsStatus()
173
174
175
{
    if (debug)
    {
Mark Olesen's avatar
Mark Olesen committed
176
        Info<< "<beg> Foam::vtkPV3Foam::updateMeshPartsStatus" << endl;
177
178
    }

Mark Olesen's avatar
Mark Olesen committed
179
180
181
182
    vtkDataArraySelection* selection = reader_->GetPartSelection();
    label nElem = selection->GetNumberOfArrays();

    if (partStatus_.size() != nElem)
Mark Olesen's avatar
Mark Olesen committed
183
    {
Mark Olesen's avatar
Mark Olesen committed
184
185
        partStatus_.setSize(nElem);
        partStatus_ = false;
Mark Olesen's avatar
Mark Olesen committed
186
187
188
        meshChanged_ = true;
    }

Mark Olesen's avatar
Mark Olesen committed
189
    // this needs fixing if we wish to re-use the datasets
Mark Olesen's avatar
Mark Olesen committed
190
191
    partDataset_.setSize(nElem);
    partDataset_ = -1;
192

Mark Olesen's avatar
Mark Olesen committed
193
194
    // Read the selected mesh parts (zones, patches ...) and add to list
    forAll(partStatus_, partId)
195
    {
Mark Olesen's avatar
Mark Olesen committed
196
        const int setting = selection->GetArraySetting(partId);
Mark Olesen's avatar
Mark Olesen committed
197

Mark Olesen's avatar
Mark Olesen committed
198
        if (partStatus_[partId] != setting)
Mark Olesen's avatar
Mark Olesen committed
199
        {
Mark Olesen's avatar
Mark Olesen committed
200
            partStatus_[partId] = setting;
Mark Olesen's avatar
Mark Olesen committed
201
202
203
            meshChanged_ = true;
        }

204
205
        if (debug)
        {
Mark Olesen's avatar
Mark Olesen committed
206
207
208
            Info<< "  part[" << partId << "] = "
                << partStatus_[partId]
                << " : " << selection->GetArrayName(partId) << endl;
209
210
211
212
        }
    }
    if (debug)
    {
Mark Olesen's avatar
Mark Olesen committed
213
        Info<< "<end> Foam::vtkPV3Foam::updateMeshPartsStatus" << endl;
214
215
216
217
218
219
220
221
    }
}

// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

Foam::vtkPV3Foam::vtkPV3Foam
(
    const char* const FileName,
Mark Olesen's avatar
Mark Olesen committed
222
    vtkPV3FoamReader* reader
223
224
225
226
227
)
:
    reader_(reader),
    dbPtr_(NULL),
    meshPtr_(NULL),
228
229
    meshRegion_(polyMesh::defaultRegion),
    meshDir_(polyMesh::meshSubDir),
Mark Olesen's avatar
Mark Olesen committed
230
231
    timeIndex_(-1),
    meshChanged_(true),
Mark Olesen's avatar
Mark Olesen committed
232
    fieldsChanged_(true),
Mark Olesen's avatar
Mark Olesen committed
233
234
235
236
237
238
239
240
241
    partInfoVolume_("unzoned"),
    partInfoPatches_("patches"),
    partInfoLagrangian_("lagrangian"),
    partInfoCellZones_("cellZone"),
    partInfoFaceZones_("faceZone"),
    partInfoPointZones_("pointZone"),
    partInfoCellSets_("cellSet"),
    partInfoFaceSets_("faceSet"),
    partInfoPointSets_("pointSet")
242
243
244
{
    if (debug)
    {
245
        Info<< "Foam::vtkPV3Foam::vtkPV3Foam - " << FileName << endl;
Mark Olesen's avatar
Mark Olesen committed
246
        printMemory();
247
248
249
250
251
    }

    // avoid argList and get rootPath/caseName directly from the file
    fileName fullCasePath(fileName(FileName).path());

252
    if (!isDir(fullCasePath))
253
254
255
256
257
258
259
260
    {
        return;
    }
    if (fullCasePath == ".")
    {
        fullCasePath = cwd();
    }

261
    // Set the case as an environment variable - some BCs might use this
262
263
    if (fullCasePath.name().find("processor", 0) == 0)
    {
264
265
266
267
        const fileName globalCase = fullCasePath.path();

        setEnv("FOAM_CASE", globalCase, true);
        setEnv("FOAM_CASENAME", globalCase.name(), true);
268
269
270
271
    }
    else
    {
        setEnv("FOAM_CASE", fullCasePath, true);
272
        setEnv("FOAM_CASENAME", fullCasePath.name(), true);
273
274
    }

275
276
277
278
279
280
281
282
283
284
285
286
    // look for 'case{region}.OpenFOAM'
    // could be stringent and insist the prefix match the directory name...
    // Note: cannot use fileName::name() due to the embedded '{}'
    string caseName(fileName(FileName).lessExt());
    string::size_type beg = caseName.find_last_of("/{");
    string::size_type end = caseName.find('}', beg);

    if
    (
        beg != string::npos && caseName[beg] == '{'
     && end != string::npos && end == caseName.size()-1
    )
287
    {
288
        meshRegion_ = caseName.substr(beg+1, end-beg-1);
289
290
291
292
293
294
295
296
297
298
299
300
301

        // some safety
        if (!meshRegion_.size())
        {
            meshRegion_ = polyMesh::defaultRegion;
        }

        if (meshRegion_ != polyMesh::defaultRegion)
        {
            meshDir_ = meshRegion_/polyMesh::meshSubDir;
        }
    }

302
303
304
    if (debug)
    {
        Info<< "fullCasePath=" << fullCasePath << nl
305
            << "FOAM_CASE=" << getEnv("FOAM_CASE") << nl
306
            << "FOAM_CASENAME=" << getEnv("FOAM_CASENAME") << nl
307
            << "region=" << meshRegion_ << endl;
308
    }
309

310
311
312
313
314
315
316
317
318
319
320
321
322
    // Create time object
    dbPtr_.reset
    (
        new Time
        (
            Time::controlDictName,
            fileName(fullCasePath.path()),
            fileName(fullCasePath.name())
        )
    );

    dbPtr_().functionObjects().off();

Mark Olesen's avatar
Mark Olesen committed
323
    updateInfo();
324
325
326
327
328
329
330
331
332
}


// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //

Foam::vtkPV3Foam::~vtkPV3Foam()
{
    if (debug)
    {
333
        Info<< "<end> Foam::vtkPV3Foam::~vtkPV3Foam" << endl;
334
335
    }

336
    delete meshPtr_;
337
338
339
340
341
}


// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //

Mark Olesen's avatar
Mark Olesen committed
342
void Foam::vtkPV3Foam::updateInfo()
343
344
345
{
    if (debug)
    {
Mark Olesen's avatar
Mark Olesen committed
346
347
348
        Info<< "<beg> Foam::vtkPV3Foam::updateInfo"
            << " [meshPtr=" << (meshPtr_ ? "set" : "NULL") << "] timeIndex="
            << timeIndex_ << endl;
349
350
351
352
    }

    resetCounters();

Mark Olesen's avatar
Mark Olesen committed
353
    vtkDataArraySelection* partSelection = reader_->GetPartSelection();
354
355

    // enable 'internalMesh' on the first call
Mark Olesen's avatar
Mark Olesen committed
356
357
358
    // or preserve the enabled selections
    stringList enabledEntries;
    if (!partSelection->GetNumberOfArrays() && !meshPtr_)
359
    {
Mark Olesen's avatar
Mark Olesen committed
360
361
        enabledEntries.setSize(1);
        enabledEntries[0] = "internalMesh";
362
363
364
    }
    else
    {
Mark Olesen's avatar
Mark Olesen committed
365
        enabledEntries = getSelectedArrayEntries(partSelection);
366
367
    }

Mark Olesen's avatar
Mark Olesen committed
368
369
    // Clear current mesh parts list
    partSelection->RemoveAllArrays();
370

Mark Olesen's avatar
Mark Olesen committed
371
    // Update mesh parts list - add Lagrangian at the bottom
Mark Olesen's avatar
Mark Olesen committed
372
373
374
375
376
    updateInfoInternalMesh();
    updateInfoPatches();
    updateInfoSets();
    updateInfoZones();
    updateInfoLagrangian();
377

378
    // restore the enabled selections
Mark Olesen's avatar
Mark Olesen committed
379
    setSelectedArrayEntries(partSelection, enabledEntries);
380

Mark Olesen's avatar
Mark Olesen committed
381
382
383
384
385
    if (meshChanged_)
    {
        fieldsChanged_ = true;
    }

Mark Olesen's avatar
Mark Olesen committed
386
387
    // Update volume, point and lagrangian fields
    updateInfoFields<fvPatchField, volMesh>
388
389
390
    (
        reader_->GetVolFieldSelection()
    );
Mark Olesen's avatar
Mark Olesen committed
391
    updateInfoFields<pointPatchField, pointMesh>
392
393
394
    (
        reader_->GetPointFieldSelection()
    );
Mark Olesen's avatar
Mark Olesen committed
395
    updateInfoLagrangianFields();
396
397
398

    if (debug)
    {
Mark Olesen's avatar
Mark Olesen committed
399
        Info<< "<end> Foam::vtkPV3Foam::updateInfo" << endl;
400
401
    }

402
403
404
}


405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
void Foam::vtkPV3Foam::updateFoamMesh()
{
    if (debug)
    {
        Info<< "<beg> Foam::vtkPV3Foam::updateFoamMesh" << endl;
        printMemory();
    }

    if (!reader_->GetCacheMesh())
    {
        delete meshPtr_;
        meshPtr_ = NULL;
    }

    // Check to see if the FOAM mesh has been created
    if (!meshPtr_)
    {
        if (debug)
        {
424
425
426
427
            Info<< "Creating Foam mesh for region " << meshRegion_
                << " at time=" << dbPtr_().timeName()
                << endl;

428
        }
429

430
431
432
433
        meshPtr_ = new fvMesh
        (
            IOobject
            (
434
                meshRegion_,
435
                dbPtr_().timeName(),
436
437
                dbPtr_(),
                IOobject::MUST_READ
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
            )
        );

        meshChanged_ = true;
    }
    else
    {
        if (debug)
        {
            Info<< "Using existing Foam mesh" << endl;
        }
    }

    if (debug)
    {
        Info<< "<end> Foam::vtkPV3Foam::updateFoamMesh" << endl;
        printMemory();
    }
}


459
460
void Foam::vtkPV3Foam::Update
(
461
462
    vtkMultiBlockDataSet* output,
    vtkMultiBlockDataSet* lagrangianOutput
463
464
465
466
)
{
    if (debug)
    {
467
468
469
        cout<< "<beg> Foam::vtkPV3Foam::Update - output with "
            << output->GetNumberOfBlocks() << " and "
            << lagrangianOutput->GetNumberOfBlocks() << " blocks\n";
Mark Olesen's avatar
Mark Olesen committed
470
        output->Print(cout);
471
        lagrangianOutput->Print(cout);
Mark Olesen's avatar
Mark Olesen committed
472
        printMemory();
473
    }
474
    reader_->UpdateProgress(0.1);
475

Mark Olesen's avatar
Mark Olesen committed
476
477
    // Set up mesh parts selection(s)
    updateMeshPartsStatus();
478

479
480
    reader_->UpdateProgress(0.15);

481
482
    // Update the Foam mesh
    updateFoamMesh();
483
    reader_->UpdateProgress(0.4);
484

Mark Olesen's avatar
Mark Olesen committed
485
    // Convert meshes - start port0 at block=0
486
487
488
489
    int blockNo = 0;

    convertMeshVolume(output, blockNo);
    convertMeshPatches(output, blockNo);
490
    reader_->UpdateProgress(0.6);
491
492
493

    if (reader_->GetIncludeZones())
    {
494
495
496
        convertMeshCellZones(output, blockNo);
        convertMeshFaceZones(output, blockNo);
        convertMeshPointZones(output, blockNo);
497
        reader_->UpdateProgress(0.65);
498
499
500
501
    }

    if (reader_->GetIncludeSets())
    {
502
503
504
        convertMeshCellSets(output, blockNo);
        convertMeshFaceSets(output, blockNo);
        convertMeshPointSets(output, blockNo);
505
        reader_->UpdateProgress(0.7);
506
    }
507

508
#ifdef VTKPV3FOAM_DUALPORT
Mark Olesen's avatar
Mark Olesen committed
509
    // restart port1 at block=0
510
    blockNo = 0;
511
#endif
512
513
    convertMeshLagrangian(lagrangianOutput, blockNo);

Mark Olesen's avatar
Mark Olesen committed
514
    reader_->UpdateProgress(0.8);
515
516

    // Update fields
517
518
519
    convertVolFields(output);
    convertPointFields(output);
    convertLagrangianFields(lagrangianOutput);
Mark Olesen's avatar
Mark Olesen committed
520
521
    reader_->UpdateProgress(0.95);

mattijs's avatar
mattijs committed
522
523
524
525
526
527
    meshChanged_ = fieldsChanged_ = false;
}


void Foam::vtkPV3Foam::CleanUp()
{
Mark Olesen's avatar
Mark Olesen committed
528
529
    // reclaim some memory
    reduceMemory();
Mark Olesen's avatar
Mark Olesen committed
530
    reader_->UpdateProgress(1.0);
531
532
533
}


Mark Olesen's avatar
Mark Olesen committed
534
double* Foam::vtkPV3Foam::findTimes(int& nTimeSteps)
535
536
{
    int nTimes = 0;
537
    double* tsteps = NULL;
538
539
540
541

    if (dbPtr_.valid())
    {
        Time& runTime = dbPtr_();
Mark Olesen's avatar
Mark Olesen committed
542
        instantList timeLst = runTime.times();
543

544
        // find the first time for which this mesh appears to exist
545
        label timeI = 0;
546
547
548
549
550
551
        for (; timeI < timeLst.size(); ++timeI)
        {
            const word& timeName = timeLst[timeI].name();

            if
            (
552
                isFile(runTime.path()/timeName/meshDir_/"points")
553
554
555
556
557
558
             && IOobject("points", timeName, meshDir_, runTime).headerOk()
            )
            {
                break;
            }
        }
559

560
561
562
563
        nTimes = timeLst.size() - timeI;

        // always skip "constant" time if possible
        if (timeI == 0 && nTimes > 1)
564
565
566
567
568
569
570
        {
            timeI = 1;
            --nTimes;
        }

        if (nTimes)
        {
571
            tsteps = new double[nTimes];
572
573
            for (label stepI = 0; stepI < nTimes; ++stepI, ++timeI)
            {
Mark Olesen's avatar
Mark Olesen committed
574
                tsteps[stepI] = timeLst[timeI].value();
575
576
            }
        }
577
578
579
580
581
    }
    else
    {
        if (debug)
        {
582
            cout<< "no valid dbPtr:\n";
583
584
585
        }
    }

586
    // vector length returned via the parameter
587
588
    nTimeSteps = nTimes;

589
    return tsteps;
590
591
592
}


Mark Olesen's avatar
Mark Olesen committed
593
void Foam::vtkPV3Foam::renderPatchNames(vtkRenderer* renderer, const bool show)
594
{
Mark Olesen's avatar
Mark Olesen committed
595
    // always remove old actors first
596

Mark Olesen's avatar
Mark Olesen committed
597
    forAll(patchTextActorsPtrs_, patchI)
598
    {
Mark Olesen's avatar
Mark Olesen committed
599
600
        renderer->RemoveViewProp(patchTextActorsPtrs_[patchI]);
        patchTextActorsPtrs_[patchI]->Delete();
601
    }
Mark Olesen's avatar
Mark Olesen committed
602
    patchTextActorsPtrs_.clear();
603

Mark Olesen's avatar
Mark Olesen committed
604
    if (show)
605
    {
Mark Olesen's avatar
Mark Olesen committed
606
607
608
609
610
611
        // get the display patches, strip off any suffix
        wordHashSet selectedPatches = getSelected
        (
            reader_->GetPartSelection(),
            partInfoPatches_
        );
612

Mark Olesen's avatar
Mark Olesen committed
613
614
615
616
        if (!selectedPatches.size())
        {
            return;
        }
617

Mark Olesen's avatar
Mark Olesen committed
618
        const polyBoundaryMesh& pbMesh = meshPtr_->boundaryMesh();
619

Mark Olesen's avatar
Mark Olesen committed
620
621
622
623
        // Find the total number of zones
        // Each zone will take the patch name
        // Number of zones per patch ... zero zones should be skipped
        labelList nZones(pbMesh.size(), 0);
624

Mark Olesen's avatar
Mark Olesen committed
625
626
        // Per global zone number the average face centre position
        DynamicList<point> zoneCentre(pbMesh.size());
627
628


Mark Olesen's avatar
Mark Olesen committed
629
630
        // Loop through all patches to determine zones, and centre of each zone
        forAll(pbMesh, patchI)
631
        {
Mark Olesen's avatar
Mark Olesen committed
632
            const polyPatch& pp = pbMesh[patchI];
633

Mark Olesen's avatar
Mark Olesen committed
634
635
636
637
638
            // Only include the patch if it is selected
            if (!selectedPatches.found(pp.name()))
            {
                continue;
            }
Mark Olesen's avatar
Mark Olesen committed
639

Mark Olesen's avatar
Mark Olesen committed
640
641
            const labelListList& edgeFaces = pp.edgeFaces();
            const vectorField& n = pp.faceNormals();
642

Mark Olesen's avatar
Mark Olesen committed
643
            boolList featEdge(pp.nEdges(), false);
644

Mark Olesen's avatar
Mark Olesen committed
645
            forAll(edgeFaces, edgeI)
646
            {
Mark Olesen's avatar
Mark Olesen committed
647
648
649
650
651
652
653
654
655
656
657
658
                const labelList& eFaces = edgeFaces[edgeI];

                if (eFaces.size() == 1)
                {
                    // Note: could also do ones with > 2 faces but this gives
                    // too many zones for baffles
                    featEdge[edgeI] = true;
                }
                else if (mag(n[eFaces[0]] & n[eFaces[1]]) < 0.5)
                {
                    featEdge[edgeI] = true;
                }
659
660
            }

Mark Olesen's avatar
Mark Olesen committed
661
662
            // Do topological analysis of patch, find disconnected regions
            patchZones pZones(pp, featEdge);
663

Mark Olesen's avatar
Mark Olesen committed
664
            nZones[patchI] = pZones.nZones();
665

Mark Olesen's avatar
Mark Olesen committed
666
            labelList zoneNFaces(pZones.nZones(), 0);
667

Mark Olesen's avatar
Mark Olesen committed
668
669
            // Save start of information for current patch
            label patchStart = zoneCentre.size();
670

Mark Olesen's avatar
Mark Olesen committed
671
672
673
674
675
            // Create storage for additional zone centres
            forAll(zoneNFaces, zoneI)
            {
                zoneCentre.append(vector::zero);
            }
676

Mark Olesen's avatar
Mark Olesen committed
677
678
679
680
681
682
683
            // Do averaging per individual zone
            forAll(pp, faceI)
            {
                label zoneI = pZones[faceI];
                zoneCentre[patchStart+zoneI] += pp[faceI].centre(pp.points());
                zoneNFaces[zoneI]++;
            }
684

Mark Olesen's avatar
Mark Olesen committed
685
686
687
688
            for (label i=0; i<nZones[patchI]; i++)
            {
                zoneCentre[patchStart + i] /= zoneNFaces[i];
            }
689
        }
690

Mark Olesen's avatar
Mark Olesen committed
691
692
        // Count number of zones we're actually going to display. This is truncated
        // to a max per patch
693

Mark Olesen's avatar
Mark Olesen committed
694
        const label MAXPATCHZONES = 20;
695

Mark Olesen's avatar
Mark Olesen committed
696
        label displayZoneI = 0;
697

Mark Olesen's avatar
Mark Olesen committed
698
699
700
701
        forAll(pbMesh, patchI)
        {
            displayZoneI += min(MAXPATCHZONES, nZones[patchI]);
        }
702

703

Mark Olesen's avatar
Mark Olesen committed
704
        zoneCentre.shrink();
705

Mark Olesen's avatar
Mark Olesen committed
706
707
708
709
710
711
        if (debug)
        {
            Info<< "patch zone centres = " << zoneCentre << nl
                << "displayed zone centres = " << displayZoneI << nl
                << "zones per patch = " << nZones << endl;
        }
712

Mark Olesen's avatar
Mark Olesen committed
713
714
        // Set the size of the patch labels to max number of zones
        patchTextActorsPtrs_.setSize(displayZoneI);
715

Mark Olesen's avatar
Mark Olesen committed
716
717
718
719
        if (debug)
        {
            Info<< "constructing patch labels" << endl;
        }
720

Mark Olesen's avatar
Mark Olesen committed
721
722
        // Actor index
        displayZoneI = 0;
723

Mark Olesen's avatar
Mark Olesen committed
724
725
        // Index in zone centres
        label globalZoneI = 0;
726

Mark Olesen's avatar
Mark Olesen committed
727
        forAll(pbMesh, patchI)
728
        {
Mark Olesen's avatar
Mark Olesen committed
729
            const polyPatch& pp = pbMesh[patchI];
730

Mark Olesen's avatar
Mark Olesen committed
731
732
733
734
            // Only selected patches will have a non-zero number of zones
            label nDisplayZones = min(MAXPATCHZONES, nZones[patchI]);
            label increment = 1;
            if (nZones[patchI] >= MAXPATCHZONES)
735
            {
Mark Olesen's avatar
Mark Olesen committed
736
                increment = nZones[patchI]/MAXPATCHZONES;
737
738
            }

Mark Olesen's avatar
Mark Olesen committed
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
            for (label i = 0; i < nDisplayZones; i++)
            {
                if (debug)
                {
                    Info<< "patch name = " << pp.name() << nl
                        << "anchor = " << zoneCentre[globalZoneI] << nl
                        << "globalZoneI = " << globalZoneI << endl;
                }

                vtkTextActor* txt = vtkTextActor::New();

                txt->SetInput(pp.name().c_str());

                // Set text properties
                vtkTextProperty* tprop = txt->GetTextProperty();
                tprop->SetFontFamilyToArial();
                tprop->BoldOff();
                tprop->ShadowOff();
                tprop->SetLineSpacing(1.0);
                tprop->SetFontSize(12);
                tprop->SetColor(1.0, 0.0, 0.0);
                tprop->SetJustificationToCentered();

                // Set text to use 3-D world co-ordinates
                txt->GetPositionCoordinate()->SetCoordinateSystemToWorld();

                txt->GetPositionCoordinate()->SetValue
                (
                    zoneCentre[globalZoneI].x(),
                    zoneCentre[globalZoneI].y(),
                    zoneCentre[globalZoneI].z()
                );

                // Add text to each renderer
                renderer->AddViewProp(txt);

                // Maintain a list of text labels added so that they can be
                // removed later
                patchTextActorsPtrs_[displayZoneI] = txt;

                globalZoneI += increment;
                displayZoneI++;
            }
782
783
        }

Mark Olesen's avatar
Mark Olesen committed
784
785
        // Resize the patch names list to the actual number of patch names added
        patchTextActorsPtrs_.setSize(displayZoneI);
786
    }
787
788
789
790
}



Mark Olesen's avatar
Mark Olesen committed
791
void Foam::vtkPV3Foam::PrintSelf(ostream& os, vtkIndent indent) const
792
{
Mark Olesen's avatar
Mark Olesen committed
793
    os  << indent << "Number of nodes: "
Mark Olesen's avatar
Mark Olesen committed
794
        << (meshPtr_ ? meshPtr_->nPoints() : 0) << "\n";
Mark Olesen's avatar
Mark Olesen committed
795
796

    os  << indent << "Number of cells: "
Mark Olesen's avatar
Mark Olesen committed
797
798
799
800
        << (meshPtr_ ? meshPtr_->nCells() : 0) << "\n";

    os  << indent << "Number of available time steps: "
        << (dbPtr_.valid() ? dbPtr_().times().size() : 0) << endl;
801
802

    os  << indent << "mesh region: " << meshRegion_ << "\n";
803
804
805
}

// ************************************************************************* //