Skip to content
Snippets Groups Projects
meshOctreeCubeRecursiveFunctions.C 7.33 KiB
Newer Older
  • Learn to ignore specific revisions
  • franjo's avatar
    franjo committed
    /*---------------------------------------------------------------------------*\
      =========                 |
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
      \\      /  F ield         | cfMesh: A library for mesh generation
    
    franjo's avatar
    franjo committed
       \\    /   O peration     |
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        \\  /    A nd           | Author: Franjo Juretic (franjo.juretic@c-fields.com)
         \\/     M anipulation  | Copyright (C) Creative Fields, Ltd.
    
    franjo's avatar
    franjo committed
    -------------------------------------------------------------------------------
    License
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        This file is part of cfMesh.
    
    franjo's avatar
    franjo committed
    
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        cfMesh is free software; you can redistribute it and/or modify it
    
    franjo's avatar
    franjo committed
        under the terms of the GNU General Public License as published by the
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        Free Software Foundation; either version 3 of the License, or (at your
    
    franjo's avatar
    franjo committed
        option) any later version.
    
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        cfMesh is distributed in the hope that it will be useful, but WITHOUT
    
    franjo's avatar
    franjo committed
        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
    
    Tomislav Lugaric's avatar
    Tomislav Lugaric committed
        along with cfMesh.  If not, see <http://www.gnu.org/licenses/>.
    
    franjo's avatar
    franjo committed
    
    Description
    
    \*---------------------------------------------------------------------------*/
    
    #include "meshOctreeCube.H"
    #include "demandDrivenData.H"
    #include "Ostream.H"
    
    #include "meshOctree.H"
    
    franjo's avatar
    franjo committed
    
    //#define DEBUGSearch
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    namespace Foam
    {
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    void meshOctreeCube::leavesInBox
    (
        const boundBox& rootBox,
        const boundBox& searchingBox,
        DynList<const meshOctreeCube*, 256>& leaves
    ) const
    {
    
    Franjo's avatar
    Franjo committed
        boundBox cubeBox;
        this->cubeBox(rootBox, cubeBox.min(), cubeBox.max());
    
    franjo's avatar
    franjo committed
    
        if( cubeBox.overlaps(searchingBox) )
        {
            if( this->isLeaf() )
            {
                leaves.append(this);
            }
            else
            {
                for(label scI=0;scI<8;++scI)
                {
                    meshOctreeCube* scPtr = subCubesPtr_[scI];
    
                    if( scPtr )
                    {
                        scPtr->leavesInBox
                        (
                            rootBox,
                            searchingBox,
                            leaves
                        );
                    }
    
    franjo's avatar
    franjo committed
                    {
                        meshOctreeCubeCoordinates cc = refineForPosition(scI);
    
    Franjo's avatar
    Franjo committed
                        boundBox bb;
                        cc.cubeBox(rootBox, bb.min(), bb.max());
    
    franjo's avatar
    franjo committed
                        if( bb.overlaps(searchingBox) )
                            leaves.append(this);
                    }
                }
            }
        }
    }
    
    
    void meshOctreeCube::leavesInSphere
    (
        const boundBox& rootBox,
        const point& c,
        const scalar r,
        DynList<label>& containedLeaves
    ) const
    {
        const point cubeCentre = this->centre(rootBox);
        const scalar size = 1.732 * this->size(rootBox);
    
        if( magSqr(cubeCentre - c) < sqr(r+size) )
        {
            if( this->isLeaf() )
            {
                containedLeaves.append(this->cubeLabel());
            }
            else
            {
                for(label scI=0;scI<8;++scI)
                {
                    meshOctreeCube* scPtr = subCubesPtr_[scI];
    
                    if( scPtr )
                    {
                        scPtr->leavesInSphere
                        (
                            rootBox,
                            c,
                            r,
                            containedLeaves
                        );
                    }
                    else if( Pstream::parRun() )
                    {
                        meshOctreeCubeCoordinates cc = refineForPosition(scI);
                        const point sc = cc.centre(rootBox);
    
                        if( magSqr(sc - c) < sqr(r+size) )
                            containedLeaves.append(meshOctreeCube::OTHERPROC);
                    }
                }
            }
        }
    }
    
    void meshOctreeCube::markLeavesInSphere
    (
        const boundBox& rootBox,
        const point& c,
        const scalar r,
        labelList& markedLeaves,
        bool& atProcessorBnd
    ) const
    {
        const point cubeCentre = this->centre(rootBox);
        const scalar size = 1.732 * this->size(rootBox);
    
        if( magSqr(cubeCentre - c) < sqr(r+size) )
        {
            if( this->isLeaf() )
            {
                markedLeaves[this->cubeLabel()] |= 2;
            }
            else
            {
                for(label scI=0;scI<8;++scI)
                {
                    meshOctreeCube* scPtr = subCubesPtr_[scI];
    
                    if( scPtr )
                    {
                        scPtr->markLeavesInSphere
                        (
                            rootBox,
                            c,
                            r,
                            markedLeaves,
                            atProcessorBnd
                        );
                    }
                    else if( Pstream::parRun() )
                    {
                        meshOctreeCubeCoordinates cc = refineForPosition(scI);
                        const point sc = cc.centre(rootBox);
    
                        if( magSqr(sc - c) < sqr(r+size) )
                        {
                            atProcessorBnd = true;
                        }
                    }
                }
            }
        }
    }
    
    
    franjo's avatar
    franjo committed
    void meshOctreeCube::findLeaves(LongList<meshOctreeCube*>& leaves) const
    {
        if( this->isLeaf() )
        {
            meshOctreeCube* oc = const_cast<meshOctreeCube*>(this);
            cubeLabel_ = leaves.size();
            leaves.append(oc);
        }
        else
        {
            cubeLabel_ = -1;
    
            for(label scI=0;scI<8;++scI)
            {
                const meshOctreeCube* scPtr = subCubesPtr_[scI];
    
                if( scPtr )
                    scPtr->findLeaves(leaves);
            }
        }
    }
    
    void meshOctreeCube::findCoordinatesOfMissingCubes
    (
        LongList<meshOctreeCubeCoordinates>& coordinates
    ) const
    {
        if( this->isLeaf() )
            return;
    
        for(label scI=0;scI<8;++scI)
        {
            meshOctreeCube* scPtr = subCubesPtr_[scI];
    
            if( scPtr )
            {
                scPtr->findCoordinatesOfMissingCubes(coordinates);
            }
            else
            {
                coordinates.append(this->refineForPosition(scI));
            }
        }
    }
    
    void meshOctreeCube::countChildCubes(label& counter) const
    {
        ++counter;
    
        if( !this->isLeaf() )
        {
            for(label scI=0;scI<8;++scI)
            {
                meshOctreeCube* scPtr = subCubesPtr_[scI];
    
                if( scPtr )
                {
                    scPtr->countChildCubes(counter);
                }
            }
        }
    }
    
    bool meshOctreeCube::purgeProcessorCubes(const short procNo)
    {
        if( this->procNo() == ALLPROCS )
        {
            this->setProcNo(procNo);
        }
    
        if( this->isLeaf() )
        {
            if( this->procNo() != procNo )
            {
                return true;
            }
    
            return false;
        }
        else
        {
            label mergedSubcubes = 0;
            for(label scI=0;scI<8;++scI)
            {
                if( !subCubesPtr_[scI] )
                {
                    mergedSubcubes |= 1 << scI;
                    continue;
                }
    
                if( subCubesPtr_[scI]->purgeProcessorCubes(procNo) )
                {
                    subCubesPtr_[scI] = NULL;
                    mergedSubcubes |= 1 << scI;
                }
            }
    
            if( mergedSubcubes == 255 )
            {
                subCubesPtr_ = NULL;
    
                return true;
            }
            else
            {
                return false;
            }
        }
    
        return false;
    }
    
    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    
    } // End namespace Foam
    
    // ************************************************************************* //