FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

triSurfaceMesh.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "triSurfaceMesh.H"
00027 #include <OpenFOAM/Random.H>
00028 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00029 #include <OpenFOAM/EdgeMap.H>
00030 #include <triSurface/triSurfaceFields.H>
00031 #include <OpenFOAM/Time.H>
00032 #include <OpenFOAM/PackedBoolList.H>
00033 
00034 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00035 
00036 namespace Foam
00037 {
00038 
00039 defineTypeNameAndDebug(triSurfaceMesh, 0);
00040 addToRunTimeSelectionTable(searchableSurface, triSurfaceMesh, dict);
00041 
00042 }
00043 
00044 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00045 
00048 //Foam::word Foam::triSurfaceMesh::findRawInstance
00049 //(
00050 //    const Time& runTime,
00051 //    const fileName& dir,
00052 //    const word& name
00053 //)
00054 //{
00055 //    // Check current time first
00056 //    if (isFile(runTime.path()/runTime.timeName()/dir/name))
00057 //    {
00058 //        return runTime.timeName();
00059 //    }
00060 //    instantList ts = runTime.times();
00061 //    label instanceI;
00062 //
00063 //    for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
00064 //    {
00065 //        if (ts[instanceI].value() <= runTime.timeOutputValue())
00066 //        {
00067 //            break;
00068 //        }
00069 //    }
00070 //
00071 //    // continue searching from here
00072 //    for (; instanceI >= 0; --instanceI)
00073 //    {
00074 //        if (isFile(runTime.path()/ts[instanceI].name()/dir/name))
00075 //        {
00076 //            return ts[instanceI].name();
00077 //        }
00078 //    }
00079 //
00080 //
00081 //    // not in any of the time directories, try constant
00082 //
00083 //    // Note. This needs to be a hard-coded constant, rather than the
00084 //    // constant function of the time, because the latter points to
00085 //    // the case constant directory in parallel cases
00086 //
00087 //    if (isFile(runTime.path()/runTime.constant()/dir/name))
00088 //    {
00089 //        return runTime.constant();
00090 //    }
00091 //
00092 //    FatalErrorIn
00093 //    (
00094 //        "searchableSurfaces::findRawInstance"
00095 //        "(const Time&, const fileName&, const word&)"
00096 //    )   << "Cannot find file \"" << name << "\" in directory "
00097 //        << runTime.constant()/dir
00098 //        << exit(FatalError);
00099 //
00100 //    return runTime.constant();
00101 //}
00102 
00103 
00104 //- Check file existence
00105 const Foam::fileName& Foam::triSurfaceMesh::checkFile
00106 (
00107     const fileName& fName,
00108     const fileName& objectName
00109 )
00110 {
00111     if (fName.empty())
00112     {
00113         FatalErrorIn
00114         (
00115             "triSurfaceMesh::checkFile(const fileName&, const fileName&)"
00116         )   << "Cannot find triSurfaceMesh starting from "
00117             << objectName << exit(FatalError);
00118     }
00119     return fName;
00120 }
00121 
00122 
00123 bool Foam::triSurfaceMesh::addFaceToEdge
00124 (
00125     const edge& e,
00126     EdgeMap<label>& facesPerEdge
00127 )
00128 {
00129     EdgeMap<label>::iterator eFnd = facesPerEdge.find(e);
00130     if (eFnd != facesPerEdge.end())
00131     {
00132         if (eFnd() == 2)
00133         {
00134             return false;
00135         }
00136         eFnd()++;
00137     }
00138     else
00139     {
00140         facesPerEdge.insert(e, 1);
00141     }
00142     return true;
00143 }
00144 
00145 
00146 bool Foam::triSurfaceMesh::isSurfaceClosed() const
00147 {
00148     // Construct pointFaces. Let's hope surface has compact point
00149     // numbering ...
00150     labelListList pointFaces;
00151     invertManyToMany(points().size(), *this, pointFaces);
00152 
00153     // Loop over all faces surrounding point. Count edges emanating from point.
00154     // Every edge should be used by two faces exactly.
00155     // To prevent doing work twice per edge only look at edges to higher
00156     // point
00157     EdgeMap<label> facesPerEdge(100);
00158     forAll(pointFaces, pointI)
00159     {
00160         const labelList& pFaces = pointFaces[pointI];
00161 
00162         facesPerEdge.clear();
00163         forAll(pFaces, i)
00164         {
00165             const labelledTri& f = triSurface::operator[](pFaces[i]);
00166             label fp = findIndex(f, pointI);
00167 
00168             // Something weird: if I expand the code of addFaceToEdge in both
00169             // below instances it gives a segmentation violation on some
00170             // surfaces. Compiler (4.3.2) problem?
00171 
00172 
00173             // Forward edge
00174             label nextPointI = f[f.fcIndex(fp)];
00175 
00176             if (nextPointI > pointI)
00177             {
00178                 bool okFace = addFaceToEdge
00179                 (
00180                     edge(pointI, nextPointI),
00181                     facesPerEdge
00182                 );
00183 
00184                 if (!okFace)
00185                 {
00186                     return false;
00187                 }
00188             }
00189             // Reverse edge
00190             label prevPointI = f[f.rcIndex(fp)];
00191 
00192             if (prevPointI > pointI)
00193             {
00194                 bool okFace = addFaceToEdge
00195                 (
00196                     edge(pointI, prevPointI),
00197                     facesPerEdge
00198                 );
00199 
00200                 if (!okFace)
00201                 {
00202                     return false;
00203                 }
00204             }
00205         }
00206 
00207         // Check for any edges used only once.
00208         forAllConstIter(EdgeMap<label>, facesPerEdge, iter)
00209         {
00210             if (iter() != 2)
00211             {
00212                 return false;
00213             }
00214         }
00215     }
00216 
00217     return true;
00218 }
00219 
00220 
00221 // Gets all intersections after initial one. Adds smallVec and starts tracking
00222 // from there.
00223 void Foam::triSurfaceMesh::getNextIntersections
00224 (
00225     const indexedOctree<treeDataTriSurface>& octree,
00226     const point& start,
00227     const point& end,
00228     const vector& smallVec,
00229     DynamicList<pointIndexHit, 1, 1>& hits
00230 )
00231 {
00232     const vector dirVec(end-start);
00233     const scalar magSqrDirVec(magSqr(dirVec));
00234 
00235     // Initial perturbation amount
00236     vector perturbVec(smallVec);
00237 
00238     while (true)
00239     {
00240         // Start tracking from last hit.
00241         point pt = hits[hits.size()-1].hitPoint() + perturbVec;
00242 
00243         if (((pt-start)&dirVec) > magSqrDirVec)
00244         {
00245             return;
00246         }
00247 
00248         // See if any intersection between pt and end
00249         pointIndexHit inter = octree.findLine(pt, end);
00250 
00251         if (!inter.hit())
00252         {
00253             return;
00254         }
00255 
00256         // Check if already found this intersection
00257         bool duplicateHit = false;
00258         forAllReverse(hits, i)
00259         {
00260             if (hits[i].index() == inter.index())
00261             {
00262                 duplicateHit = true;
00263                 break;
00264             }
00265         }
00266 
00267 
00268         if (duplicateHit)
00269         {
00270             // Hit same triangle again. Increase perturbVec and try again.
00271             perturbVec *= 2;
00272         }
00273         else
00274         {
00275             // Proper hit
00276             hits.append(inter);
00277             // Restore perturbVec
00278             perturbVec = smallVec;
00279         }
00280     }
00281 }
00282 
00283 
00284 void Foam::triSurfaceMesh::calcBounds(boundBox& bb, label& nPoints) const
00285 {
00286     // Unfortunately nPoints constructs meshPoints() so do compact version
00287     // ourselves
00288 
00289     const triSurface& s = static_cast<const triSurface&>(*this);
00290 
00291     PackedBoolList pointIsUsed(points().size());
00292 
00293     nPoints = 0;
00294     bb = boundBox::invertedBox;
00295 
00296     forAll(s, triI)
00297     {
00298         const labelledTri& f = s[triI];
00299 
00300         forAll(f, fp)
00301         {
00302             label pointI = f[fp];
00303             if (pointIsUsed.set(pointI, 1u))
00304             {
00305                 bb.min() = ::Foam::min(bb.min(), points()[pointI]);
00306                 bb.max() = ::Foam::max(bb.max(), points()[pointI]);
00307                 nPoints++;
00308             }
00309         }
00310     }
00311 }
00312 
00313 
00314 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00315 
00316 Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io, const triSurface& s)
00317 :
00318     searchableSurface(io),
00319     objectRegistry
00320     (
00321         IOobject
00322         (
00323             io.name(),
00324             io.instance(),
00325             io.local(),
00326             io.db(),
00327             io.readOpt(),
00328             io.writeOpt(),
00329             false       // searchableSurface already registered under name
00330         )
00331     ),
00332     triSurface(s),
00333     tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()),
00334     maxTreeDepth_(10),
00335     surfaceClosed_(-1)
00336 {}
00337 
00338 
00339 Foam::triSurfaceMesh::triSurfaceMesh(const IOobject& io)
00340 :
00341     // Find instance for triSurfaceMesh
00342     searchableSurface(io),
00343     //(
00344     //    IOobject
00345     //    (
00346     //        io.name(),
00347     //        io.time().findInstance(io.local(), word::null),
00348     //        io.local(),
00349     //        io.db(),
00350     //        io.readOpt(),
00351     //        io.writeOpt(),
00352     //        io.registerObject()
00353     //    )
00354     //),
00355     // Reused found instance in objectRegistry
00356     objectRegistry
00357     (
00358         IOobject
00359         (
00360             io.name(),
00361             static_cast<const searchableSurface&>(*this).instance(),
00362             io.local(),
00363             io.db(),
00364             io.readOpt(),
00365             io.writeOpt(),
00366             false       // searchableSurface already registered under name
00367         )
00368     ),
00369     triSurface
00370     (
00371         checkFile
00372         (
00373             searchableSurface::filePath(),
00374             searchableSurface::objectPath()
00375         )
00376     ),
00377     tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()),
00378     maxTreeDepth_(10),
00379     surfaceClosed_(-1)
00380 {}
00381 
00382 
00383 Foam::triSurfaceMesh::triSurfaceMesh
00384 (
00385     const IOobject& io,
00386     const dictionary& dict
00387 )
00388 :
00389     searchableSurface(io),
00390     //(
00391     //    IOobject
00392     //    (
00393     //        io.name(),
00394     //        io.time().findInstance(io.local(), word::null),
00395     //        io.local(),
00396     //        io.db(),
00397     //        io.readOpt(),
00398     //        io.writeOpt(),
00399     //        io.registerObject()
00400     //    )
00401     //),
00402     // Reused found instance in objectRegistry
00403     objectRegistry
00404     (
00405         IOobject
00406         (
00407             io.name(),
00408             static_cast<const searchableSurface&>(*this).instance(),
00409             io.local(),
00410             io.db(),
00411             io.readOpt(),
00412             io.writeOpt(),
00413             false       // searchableSurface already registered under name
00414         )
00415     ),
00416     triSurface
00417     (
00418         checkFile
00419         (
00420             searchableSurface::filePath(),
00421             searchableSurface::objectPath()
00422         )
00423     ),
00424     tolerance_(indexedOctree<treeDataTriSurface>::perturbTol()),
00425     maxTreeDepth_(10),
00426     surfaceClosed_(-1)
00427 {
00428     scalar scaleFactor = 0;
00429 
00430     // allow rescaling of the surface points
00431     // eg, CAD geometries are often done in millimeters
00432     if (dict.readIfPresent("scale", scaleFactor) && scaleFactor > 0)
00433     {
00434         Info<< searchableSurface::name() << " : using scale " << scaleFactor
00435             << endl;
00436         triSurface::scalePoints(scaleFactor);
00437     }
00438 
00439 
00440     // Have optional non-standard search tolerance for gappy surfaces.
00441     if (dict.readIfPresent("tolerance", tolerance_) && tolerance_ > 0)
00442     {
00443         Info<< searchableSurface::name() << " : using intersection tolerance "
00444             << tolerance_ << endl;
00445     }
00446 
00447 
00448     // Have optional non-standard tree-depth to limit storage.
00449     if (dict.readIfPresent("maxTreeDepth", maxTreeDepth_) && maxTreeDepth_ > 0)
00450     {
00451         Info<< searchableSurface::name() << " : using maximum tree depth "
00452             << maxTreeDepth_ << endl;
00453     }
00454 }
00455 
00456 
00457 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00458 
00459 Foam::triSurfaceMesh::~triSurfaceMesh()
00460 {
00461     clearOut();
00462 }
00463 
00464 
00465 void Foam::triSurfaceMesh::clearOut()
00466 {
00467     tree_.clear();
00468     edgeTree_.clear();
00469     triSurface::clearOut();
00470 }
00471 
00472 
00473 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00474 
00475 Foam::pointField Foam::triSurfaceMesh::coordinates() const
00476 {
00477     // Use copy to calculate face centres so they don't get stored
00478     return PrimitivePatch<labelledTri, SubList, const pointField&>
00479     (
00480         SubList<labelledTri>(*this, triSurface::size()),
00481         triSurface::points()
00482     ).faceCentres();
00483 }
00484 
00485 
00486 void Foam::triSurfaceMesh::movePoints(const pointField& newPoints)
00487 {
00488     tree_.clear();
00489     edgeTree_.clear();
00490     triSurface::movePoints(newPoints);
00491 }
00492 
00493 
00494 const Foam::indexedOctree<Foam::treeDataTriSurface>&
00495     Foam::triSurfaceMesh::tree() const
00496 {
00497     if (tree_.empty())
00498     {
00499         // Calculate bb without constructing local point numbering.
00500         treeBoundBox bb;
00501         label nPoints;
00502         calcBounds(bb, nPoints);
00503 
00504         if (nPoints != points().size())
00505         {
00506             WarningIn("triSurfaceMesh::tree() const")
00507                 << "Surface " << searchableSurface::name()
00508                 << " does not have compact point numbering."
00509                 << " Of " << points().size() << " only " << nPoints
00510                 << " are used. This might give problems in some routines."
00511                 << endl;
00512         }
00513 
00514 
00515         // Random number generator. Bit dodgy since not exactly random ;-)
00516         Random rndGen(65431);
00517 
00518         // Slightly extended bb. Slightly off-centred just so on symmetric
00519         // geometry there are less face/edge aligned items.
00520         bb = bb.extend(rndGen, 1E-4);
00521         bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00522         bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00523 
00524         scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
00525         indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
00526 
00527         tree_.reset
00528         (
00529             new indexedOctree<treeDataTriSurface>
00530             (
00531                 treeDataTriSurface(*this),
00532                 bb,
00533                 maxTreeDepth_,  // maxLevel
00534                 10,             // leafsize
00535                 3.0             // duplicity
00536             )
00537         );
00538 
00539         indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
00540     }
00541 
00542     return tree_();
00543 }
00544 
00545 
00546 const Foam::indexedOctree<Foam::treeDataEdge>&
00547  Foam::triSurfaceMesh::edgeTree() const
00548 {
00549     if (edgeTree_.empty())
00550     {
00551         // Boundary edges
00552         labelList bEdges
00553         (
00554             identity
00555             (
00556                 nEdges()
00557                -nInternalEdges()
00558             )
00559           + nInternalEdges()
00560         );
00561 
00562         treeBoundBox bb;
00563         label nPoints;
00564         calcBounds(bb, nPoints);
00565 
00566         // Random number generator. Bit dodgy since not exactly random ;-)
00567         Random rndGen(65431);
00568 
00569         // Slightly extended bb. Slightly off-centred just so on symmetric
00570         // geometry there are less face/edge aligned items.
00571 
00572         bb = bb.extend(rndGen, 1E-4);
00573         bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00574         bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00575 
00576         edgeTree_.reset
00577         (
00578             new indexedOctree<treeDataEdge>
00579             (
00580                 treeDataEdge
00581                 (
00582                     false,          // cachebb
00583                     edges(),        // edges
00584                     localPoints(),  // points
00585                     bEdges          // selected edges
00586                 ),
00587                 bb,                 // bb
00588                 maxTreeDepth_,      // maxLevel
00589                 10,                 // leafsize
00590                 3.0                 // duplicity
00591             )
00592         );
00593     }
00594     return edgeTree_();
00595 }
00596 
00597 
00598 const Foam::wordList& Foam::triSurfaceMesh::regions() const
00599 {
00600     if (regions_.empty())
00601     {
00602         regions_.setSize(patches().size());
00603         forAll(regions_, regionI)
00604         {
00605             regions_[regionI] = patches()[regionI].name();
00606         }
00607     }
00608     return regions_;
00609 }
00610 
00611 
00612 // Find out if surface is closed.
00613 bool Foam::triSurfaceMesh::hasVolumeType() const
00614 {
00615     if (surfaceClosed_ == -1)
00616     {
00617         if (isSurfaceClosed())
00618         {
00619             surfaceClosed_ = 1;
00620         }
00621         else
00622         {
00623             surfaceClosed_ = 0;
00624         }
00625     }
00626 
00627     return surfaceClosed_ == 1;
00628 }
00629 
00630 
00631 void Foam::triSurfaceMesh::findNearest
00632 (
00633     const pointField& samples,
00634     const scalarField& nearestDistSqr,
00635     List<pointIndexHit>& info
00636 ) const
00637 {
00638     const indexedOctree<treeDataTriSurface>& octree = tree();
00639 
00640     info.setSize(samples.size());
00641 
00642     scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
00643     indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
00644 
00645     forAll(samples, i)
00646     {
00647         static_cast<pointIndexHit&>(info[i]) = octree.findNearest
00648         (
00649             samples[i],
00650             nearestDistSqr[i]
00651         );
00652     }
00653 
00654     indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
00655 }
00656 
00657 
00658 void Foam::triSurfaceMesh::findLine
00659 (
00660     const pointField& start,
00661     const pointField& end,
00662     List<pointIndexHit>& info
00663 ) const
00664 {
00665     const indexedOctree<treeDataTriSurface>& octree = tree();
00666 
00667     info.setSize(start.size());
00668 
00669     scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
00670     indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
00671 
00672     forAll(start, i)
00673     {
00674         static_cast<pointIndexHit&>(info[i]) = octree.findLine
00675         (
00676             start[i],
00677             end[i]
00678         );
00679     }
00680 
00681     indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
00682 }
00683 
00684 
00685 void Foam::triSurfaceMesh::findLineAny
00686 (
00687     const pointField& start,
00688     const pointField& end,
00689     List<pointIndexHit>& info
00690 ) const
00691 {
00692     const indexedOctree<treeDataTriSurface>& octree = tree();
00693 
00694     info.setSize(start.size());
00695 
00696     scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
00697     indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
00698 
00699     forAll(start, i)
00700     {
00701         static_cast<pointIndexHit&>(info[i]) = octree.findLineAny
00702         (
00703             start[i],
00704             end[i]
00705         );
00706     }
00707 
00708     indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
00709 }
00710 
00711 
00712 void Foam::triSurfaceMesh::findLineAll
00713 (
00714     const pointField& start,
00715     const pointField& end,
00716     List<List<pointIndexHit> >& info
00717 ) const
00718 {
00719     const indexedOctree<treeDataTriSurface>& octree = tree();
00720 
00721     info.setSize(start.size());
00722 
00723     scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
00724     indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
00725 
00726     // Work array
00727     DynamicList<pointIndexHit, 1, 1> hits;
00728 
00729     // Tolerances:
00730     // To find all intersections we add a small vector to the last intersection
00731     // This is chosen such that
00732     // - it is significant (SMALL is smallest representative relative tolerance;
00733     //   we need something bigger since we're doing calculations)
00734     // - if the start-end vector is zero we still progress
00735     const vectorField dirVec(end-start);
00736     const scalarField magSqrDirVec(magSqr(dirVec));
00737     const vectorField smallVec
00738     (
00739         indexedOctree<treeDataTriSurface>::perturbTol()*dirVec
00740       + vector(ROOTVSMALL,ROOTVSMALL,ROOTVSMALL)
00741     );
00742 
00743     forAll(start, pointI)
00744     {
00745         // See if any intersection between pt and end
00746         pointIndexHit inter = octree.findLine(start[pointI], end[pointI]);
00747 
00748         if (inter.hit())
00749         {
00750             hits.clear();
00751             hits.append(inter);
00752 
00753             getNextIntersections
00754             (
00755                 octree,
00756                 start[pointI],
00757                 end[pointI],
00758                 smallVec[pointI],
00759                 hits
00760             );
00761 
00762             info[pointI].transfer(hits);
00763         }
00764         else
00765         {
00766             info[pointI].clear();
00767         }
00768     }
00769 
00770     indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
00771 }
00772 
00773 
00774 void Foam::triSurfaceMesh::getRegion
00775 (
00776     const List<pointIndexHit>& info,
00777     labelList& region
00778 ) const
00779 {
00780     region.setSize(info.size());
00781     forAll(info, i)
00782     {
00783         if (info[i].hit())
00784         {
00785             region[i] = triSurface::operator[](info[i].index()).region();
00786         }
00787         else
00788         {
00789             region[i] = -1;
00790         }
00791     }
00792 }
00793 
00794 
00795 void Foam::triSurfaceMesh::getNormal
00796 (
00797     const List<pointIndexHit>& info,
00798     vectorField& normal
00799 ) const
00800 {
00801     normal.setSize(info.size());
00802 
00803     forAll(info, i)
00804     {
00805         if (info[i].hit())
00806         {
00807             label triI = info[i].index();
00808             //- Cached:
00809             //normal[i] = faceNormals()[triI];
00810 
00811             //- Uncached
00812             normal[i] = triSurface::operator[](triI).normal(points());
00813             normal[i] /= mag(normal[i]) + VSMALL;
00814         }
00815         else
00816         {
00817             // Set to what?
00818             normal[i] = vector::zero;
00819         }
00820     }
00821 }
00822 
00823 
00824 void Foam::triSurfaceMesh::setField(const labelList& values)
00825 {
00826     autoPtr<triSurfaceLabelField> fldPtr
00827     (
00828         new triSurfaceLabelField
00829         (
00830             IOobject
00831             (
00832                 "values",
00833                 objectRegistry::time().timeName(),  // instance
00834                 "triSurface",                       // local
00835                 *this,
00836                 IOobject::NO_READ,
00837                 IOobject::AUTO_WRITE
00838             ),
00839             *this,
00840             dimless,
00841             labelField(values)
00842         )
00843     );
00844 
00845     // Store field on triMesh
00846     fldPtr.ptr()->store();
00847 }
00848 
00849 
00850 void Foam::triSurfaceMesh::getField
00851 (
00852     const List<pointIndexHit>& info,
00853     labelList& values
00854 ) const
00855 {
00856     if (foundObject<triSurfaceLabelField>("values"))
00857     {
00858         values.setSize(info.size());
00859 
00860         const triSurfaceLabelField& fld = lookupObject<triSurfaceLabelField>
00861         (
00862             "values"
00863         );
00864 
00865         forAll(info, i)
00866         {
00867             if (info[i].hit())
00868             {
00869                 values[i] = fld[info[i].index()];
00870             }
00871         }
00872     }
00873 }
00874 
00875 
00876 void Foam::triSurfaceMesh::getVolumeType
00877 (
00878     const pointField& points,
00879     List<volumeType>& volType
00880 ) const
00881 {
00882     volType.setSize(points.size());
00883 
00884     scalar oldTol = indexedOctree<treeDataTriSurface>::perturbTol();
00885     indexedOctree<treeDataTriSurface>::perturbTol() = tolerance_;
00886 
00887     forAll(points, pointI)
00888     {
00889         const point& pt = points[pointI];
00890 
00891         // - use cached volume type per each tree node
00892         // - cheat conversion since same values
00893         volType[pointI] = static_cast<volumeType>(tree().getVolumeType(pt));
00894     }
00895 
00896     indexedOctree<treeDataTriSurface>::perturbTol() = oldTol;
00897 }
00898 
00899 
00900 //- Write using given format, version and compression
00901 bool Foam::triSurfaceMesh::writeObject
00902 (
00903     IOstream::streamFormat fmt,
00904     IOstream::versionNumber ver,
00905     IOstream::compressionType cmp
00906 ) const
00907 {
00908     fileName fullPath(searchableSurface::objectPath());
00909 
00910     if (!mkDir(fullPath.path()))
00911     {
00912         return false;
00913     }
00914 
00915     triSurface::write(fullPath);
00916 
00917     if (!isFile(fullPath))
00918     {
00919         return false;
00920     }
00921 
00922     //return objectRegistry::writeObject(fmt, ver, cmp);
00923     return true;
00924 }
00925 
00926 
00927 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines