mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: surface: various updates to the surface utilities
surfaceBooleanFeatures: use CGAL for intersection surfaceCheck: write surface zoning as vtk file surfaceInflate: new utility to offset surface surfacePatch: replacement for surfaceAutoPatch. Also does cutting of surfaces.
This commit is contained in:
@ -1,3 +0,0 @@
|
|||||||
surfaceAutoPatch.C
|
|
||||||
|
|
||||||
EXE = $(FOAM_APPBIN)/surfaceAutoPatch
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
EXE_INC = \
|
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
|
||||||
-I$(LIB_SRC)/triSurface/lnInclude
|
|
||||||
|
|
||||||
EXE_LIBS = \
|
|
||||||
-lmeshTools \
|
|
||||||
-ltriSurface
|
|
||||||
@ -1,125 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
|
||||||
\\/ 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Application
|
|
||||||
surfaceAutoPatch
|
|
||||||
|
|
||||||
Description
|
|
||||||
Patches surface according to feature angle. Like autoPatch.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "triangle.H"
|
|
||||||
#include "triSurface.H"
|
|
||||||
#include "argList.H"
|
|
||||||
#include "surfaceFeatures.H"
|
|
||||||
#include "treeBoundBox.H"
|
|
||||||
#include "meshTools.H"
|
|
||||||
#include "OFstream.H"
|
|
||||||
|
|
||||||
using namespace Foam;
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
argList::noParallel();
|
|
||||||
argList::validArgs.append("input surfaceFile");
|
|
||||||
argList::validArgs.append("output surfaceFile");
|
|
||||||
argList::validArgs.append("includedAngle [0..180]");
|
|
||||||
argList args(argc, argv);
|
|
||||||
|
|
||||||
const fileName inFileName = args[1];
|
|
||||||
const fileName outFileName = args[2];
|
|
||||||
const scalar includedAngle = args.argRead<scalar>(3);
|
|
||||||
|
|
||||||
Info<< "Surface : " << inFileName << nl << endl;
|
|
||||||
|
|
||||||
|
|
||||||
// Read
|
|
||||||
// ~~~~
|
|
||||||
|
|
||||||
Info<< "Reading : " << inFileName << endl;
|
|
||||||
triSurface surf(inFileName);
|
|
||||||
|
|
||||||
Info<< "Read surface:" << endl;
|
|
||||||
surf.writeStats(Info);
|
|
||||||
Info<< endl;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Construct features from surface&featureangle
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Info<< "Constructing feature set from included angle " << includedAngle
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
surfaceFeatures set(surf, includedAngle);
|
|
||||||
|
|
||||||
Info<< nl
|
|
||||||
<< "Feature set:" << nl
|
|
||||||
<< " feature points : " << set.featurePoints().size() << nl
|
|
||||||
<< " feature edges : " << set.featureEdges().size() << nl
|
|
||||||
<< " of which" << nl
|
|
||||||
<< " region edges : " << set.nRegionEdges() << nl
|
|
||||||
<< " external edges : " << set.nExternalEdges() << nl
|
|
||||||
<< " internal edges : " << set.nInternalEdges() << nl
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
// Get per-edge status.
|
|
||||||
boolList borderEdge(surf.nEdges(), false);
|
|
||||||
forAll(set.featureEdges(), i)
|
|
||||||
{
|
|
||||||
borderEdge[set.featureEdges()[i]] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
labelList faceRegion(surf.size());
|
|
||||||
label nRegions = surf.markZones(borderEdge, faceRegion);
|
|
||||||
|
|
||||||
// Reregion triangles.
|
|
||||||
forAll(surf, i)
|
|
||||||
{
|
|
||||||
surf[i].region() = faceRegion[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create some patches
|
|
||||||
surf.patches().setSize(nRegions);
|
|
||||||
|
|
||||||
forAll(surf.patches(), patchI)
|
|
||||||
{
|
|
||||||
surf.patches()[patchI].name() = "patch" + Foam::name(patchI);
|
|
||||||
surf.patches()[patchI].geometricType() = "empty";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Info<< "Writing : " << outFileName << endl;
|
|
||||||
surf.write(outFileName, true);
|
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
15
applications/utilities/surface/surfaceBooleanFeatures/Allwmake
Executable file
15
applications/utilities/surface/surfaceBooleanFeatures/Allwmake
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd ${0%/*} || exit 1 # Run from this directory
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [ -z "$CGAL_ARCH_PATH" ]
|
||||||
|
then
|
||||||
|
export COMPILE_FLAGS="-DNO_CGAL"
|
||||||
|
else
|
||||||
|
wmake PolyhedronReader
|
||||||
|
export COMPILE_FLAGS='-IPolyhedronReader'
|
||||||
|
export LINK_FLAGS='${CGAL_LIBS} -lPolyhedronReader'
|
||||||
|
fi
|
||||||
|
wmake
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------- end-of-file
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Typedefs
|
||||||
|
CGAL3DKernel
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef CGAL3DKernel_H
|
||||||
|
#define CGAL3DKernel_H
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef CGAL_INEXACT
|
||||||
|
|
||||||
|
// Fast kernel using a double as the storage type
|
||||||
|
#include "CGAL/Exact_predicates_inexact_constructions_kernel.h"
|
||||||
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Very robust but expensive kernel
|
||||||
|
#include "CGAL/Exact_predicates_exact_constructions_kernel.h"
|
||||||
|
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Typedefs
|
||||||
|
IndexedPolyhedron
|
||||||
|
|
||||||
|
Description
|
||||||
|
CGAL data structures used for triSurface handling
|
||||||
|
|
||||||
|
Define CGAL_INEXACT to use Exact_predicates_inexact_constructions kernel
|
||||||
|
otherwise the more robust but much less efficient
|
||||||
|
Exact_predicates_exact_constructions will be used.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef IndexedPolyhedron_H
|
||||||
|
#define IndexedPolyhedron_H
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Include uint.H before CGAL headers to define __STDC_LIMIT_MACROS
|
||||||
|
#include "uint.H"
|
||||||
|
|
||||||
|
#include "CGAL3DKernel.H"
|
||||||
|
#include <CGAL/Polyhedron_3.h>
|
||||||
|
#include <CGAL/Nef_polyhedron_3.h>
|
||||||
|
|
||||||
|
#include "label.H"
|
||||||
|
|
||||||
|
|
||||||
|
typedef CGAL::Point_3<K> Point;
|
||||||
|
typedef CGAL::Segment_3<K> Segment;
|
||||||
|
typedef CGAL::Direction_3<K> Direction;
|
||||||
|
typedef CGAL::Plane_3<K> Plane;
|
||||||
|
typedef CGAL::Triangle_3<K> Triangle;
|
||||||
|
|
||||||
|
// Define new class with color and define the polyhedron types
|
||||||
|
template<class Refs>
|
||||||
|
struct IndexedFace
|
||||||
|
:
|
||||||
|
public CGAL::HalfedgeDS_face_base<Refs>
|
||||||
|
{
|
||||||
|
Foam::label index;
|
||||||
|
Foam::label region;
|
||||||
|
};
|
||||||
|
struct My_items
|
||||||
|
:
|
||||||
|
public CGAL::Polyhedron_items_3
|
||||||
|
{
|
||||||
|
template<class Refs, class Traits>
|
||||||
|
struct Face_wrapper
|
||||||
|
{
|
||||||
|
typedef IndexedFace<Refs> Face;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//typedef CGAL::Polyhedron_3<K> Polyhedron;
|
||||||
|
typedef CGAL::Polyhedron_3<K, My_items> Polyhedron;
|
||||||
|
|
||||||
|
typedef Polyhedron::HalfedgeDS HalfedgeDS;
|
||||||
|
typedef Polyhedron::Edge_iterator Edge_iterator;
|
||||||
|
typedef Polyhedron::Vertex Vertex;
|
||||||
|
typedef Polyhedron::Vertex_iterator Vertex_iterator;
|
||||||
|
typedef Polyhedron::Halfedge_handle Halfedge_handle;
|
||||||
|
typedef Polyhedron::Edge_iterator Edge_iterator;
|
||||||
|
typedef Polyhedron::Facet_iterator Facet_iterator;
|
||||||
|
typedef Polyhedron::Halfedge_around_facet_const_circulator HFCC;
|
||||||
|
typedef Polyhedron::Vertex_const_iterator VCI;
|
||||||
|
|
||||||
|
typedef CGAL::Nef_polyhedron_3<K> Nef_polyhedron;
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,9 +1,29 @@
|
|||||||
|
EXE_NDEBUG = -DNDEBUG
|
||||||
|
/* EXE_NDEBUG = -g -O0 -DFULLDEBUG */
|
||||||
|
|
||||||
|
|
||||||
|
c++CGALWARN = -Wno-old-style-cast
|
||||||
|
|
||||||
|
/*-- Define NO_CGAL to avoid using CGAL altogether */
|
||||||
|
/*-- Define CGAL_INEXACT to use inexact CGAL constructions */
|
||||||
|
|
||||||
|
include $(GENERAL_RULES)/CGAL
|
||||||
|
|
||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
${ROUNDING_MATH} \
|
||||||
|
${EXE_NDEBUG} \
|
||||||
|
${CGAL_INC} \
|
||||||
|
${c++CGALWARN} \
|
||||||
|
$(COMPILE_FLAGS) \
|
||||||
|
-IPolyhedronReader \
|
||||||
|
-I$(FOAM_SRC)/surfMesh/lnInclude \
|
||||||
|
-I$(FOAM_SRC)/triSurface/lnInclude \
|
||||||
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude
|
-I$(LIB_SRC)/meshTools/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
EXE_LIBS = \
|
||||||
|
-lsurfMesh \
|
||||||
-ltriSurface \
|
-ltriSurface \
|
||||||
-ledgeMesh \
|
-ledgeMesh \
|
||||||
-lmeshTools
|
-lmeshTools \
|
||||||
|
$(LINK_FLAGS)
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
PolyhedronReader.C
|
||||||
|
|
||||||
|
LIB = $(FOAM_LIBBIN)/libPolyhedronReader
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
EXE_NDEBUG = -DNDEBUG
|
||||||
|
/* EXE_NDEBUG = -g -O0 -DFULLDEBUG */
|
||||||
|
|
||||||
|
|
||||||
|
c++CGALWARN = -Wno-old-style-cast
|
||||||
|
|
||||||
|
/*-- Define CGAL_INEXACT to use inexact CGAL constructions */
|
||||||
|
|
||||||
|
include $(GENERAL_RULES)/CGAL
|
||||||
|
|
||||||
|
EXE_INC = \
|
||||||
|
${ROUNDING_MATH} \
|
||||||
|
${EXE_NDEBUG} \
|
||||||
|
${CGAL_INC} \
|
||||||
|
${c++CGALWARN} \
|
||||||
|
-I.. \
|
||||||
|
-I$(FOAM_SRC)/surfMesh/lnInclude \
|
||||||
|
-I$(FOAM_SRC)/triSurface/lnInclude \
|
||||||
|
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
|
-I/usr/include/Qt
|
||||||
|
|
||||||
|
LIB_LIBS = \
|
||||||
|
-L${CGAL_ARCH_PATH}/lib \
|
||||||
|
-ltriSurface
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "PolyhedronReader.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::PolyhedronReader::PolyhedronReader(const triSurface& s, Polyhedron& p)
|
||||||
|
{
|
||||||
|
Build_triangle<HalfedgeDS> triangle(s);
|
||||||
|
p.delegate(triangle);
|
||||||
|
// Populate index and region
|
||||||
|
Foam::label nTris = 0;
|
||||||
|
for
|
||||||
|
(
|
||||||
|
Facet_iterator fi = p.facets_begin();
|
||||||
|
fi != p.facets_end();
|
||||||
|
++fi
|
||||||
|
)
|
||||||
|
{
|
||||||
|
fi->index = nTris++;
|
||||||
|
fi->region = s[fi->index].region();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,101 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::PolyhedronReader
|
||||||
|
|
||||||
|
Description
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
PolyhedronReader.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef PolyhedronReader_H
|
||||||
|
#define PolyhedronReader_H
|
||||||
|
|
||||||
|
#include "CGALIndexedPolyhedron.H"
|
||||||
|
#include "triSurface.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class PolyhedronReader Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class PolyhedronReader
|
||||||
|
{
|
||||||
|
// Private Classes
|
||||||
|
|
||||||
|
template<class HDS>
|
||||||
|
class Build_triangle
|
||||||
|
:
|
||||||
|
public CGAL::Modifier_base<HDS>
|
||||||
|
{
|
||||||
|
const triSurface& s_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Build_triangle(const triSurface& s);
|
||||||
|
|
||||||
|
void operator()(HDS& hds);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
PolyhedronReader(const PolyhedronReader&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const PolyhedronReader&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Populate polyhedron from surface
|
||||||
|
PolyhedronReader(const triSurface& s, Polyhedron& p);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
# include "PolyhedronReaderTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "PolyhedronReader.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class HDS>
|
||||||
|
Foam::PolyhedronReader::Build_triangle<HDS>::Build_triangle
|
||||||
|
(
|
||||||
|
const triSurface& s
|
||||||
|
)
|
||||||
|
:
|
||||||
|
s_(s)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class HDS>
|
||||||
|
void Foam::PolyhedronReader::Build_triangle<HDS>::operator()(HDS& hds)
|
||||||
|
{
|
||||||
|
// Postcondition: hds is a valid polyhedral surface.
|
||||||
|
CGAL::Polyhedron_incremental_builder_3<HDS> B(hds, true);
|
||||||
|
|
||||||
|
B.begin_surface(s_.nPoints(), s_.size());
|
||||||
|
|
||||||
|
typedef typename HDS::Vertex Vertex;
|
||||||
|
typedef typename Vertex::Point Point;
|
||||||
|
|
||||||
|
const Foam::pointField& pts = s_.points();
|
||||||
|
forAll(pts, i)
|
||||||
|
{
|
||||||
|
const Foam::point& pt = pts[i];
|
||||||
|
B.add_vertex(Point(pt.x(), pt.y(), pt.z()));
|
||||||
|
}
|
||||||
|
forAll(s_, i)
|
||||||
|
{
|
||||||
|
const Foam::labelledTri& t = s_[i];
|
||||||
|
B.begin_facet();
|
||||||
|
B.add_vertex_to_facet(t[0]);
|
||||||
|
B.add_vertex_to_facet(t[1]);
|
||||||
|
B.add_vertex_to_facet(t[2]);
|
||||||
|
B.end_facet();
|
||||||
|
}
|
||||||
|
B.end_surface();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -170,6 +170,101 @@ labelList countBins
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void writeZoning
|
||||||
|
(
|
||||||
|
const triSurface& surf,
|
||||||
|
const labelList& faceZone,
|
||||||
|
const word& fieldName,
|
||||||
|
const fileName& surfFilePath,
|
||||||
|
const fileName& surfFileNameBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "Writing zoning to "
|
||||||
|
<< fileName
|
||||||
|
(
|
||||||
|
surfFilePath
|
||||||
|
/ fieldName
|
||||||
|
+ '_'
|
||||||
|
+ surfFileNameBase
|
||||||
|
+ '.'
|
||||||
|
+ vtkSurfaceWriter::typeName
|
||||||
|
)
|
||||||
|
<< "..." << endl << endl;
|
||||||
|
|
||||||
|
// Convert data
|
||||||
|
scalarField scalarFaceZone(faceZone.size());
|
||||||
|
forAll(faceZone, i)
|
||||||
|
{
|
||||||
|
scalarFaceZone[i] = faceZone[i];
|
||||||
|
}
|
||||||
|
faceList faces(surf.size());
|
||||||
|
forAll(surf, i)
|
||||||
|
{
|
||||||
|
faces[i] = surf[i].triFaceFace();
|
||||||
|
}
|
||||||
|
|
||||||
|
vtkSurfaceWriter().write
|
||||||
|
(
|
||||||
|
surfFilePath,
|
||||||
|
surfFileNameBase,
|
||||||
|
surf.points(),
|
||||||
|
faces,
|
||||||
|
fieldName,
|
||||||
|
scalarFaceZone,
|
||||||
|
false // face based data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void writeParts
|
||||||
|
(
|
||||||
|
const triSurface& surf,
|
||||||
|
const label nFaceZones,
|
||||||
|
const labelList& faceZone,
|
||||||
|
const fileName& surfFilePath,
|
||||||
|
const fileName& surfFileNameBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (label zone = 0; zone < nFaceZones; zone++)
|
||||||
|
{
|
||||||
|
boolList includeMap(surf.size(), false);
|
||||||
|
|
||||||
|
forAll(faceZone, faceI)
|
||||||
|
{
|
||||||
|
if (faceZone[faceI] == zone)
|
||||||
|
{
|
||||||
|
includeMap[faceI] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList pointMap;
|
||||||
|
labelList faceMap;
|
||||||
|
|
||||||
|
triSurface subSurf
|
||||||
|
(
|
||||||
|
surf.subsetMesh
|
||||||
|
(
|
||||||
|
includeMap,
|
||||||
|
pointMap,
|
||||||
|
faceMap
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
fileName subName
|
||||||
|
(
|
||||||
|
surfFilePath
|
||||||
|
/surfFileNameBase + "_" + name(zone) + ".obj"
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< "writing part " << zone << " size " << subSurf.size()
|
||||||
|
<< " to " << subName << endl;
|
||||||
|
|
||||||
|
subSurf.write(subName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -218,6 +313,20 @@ int main(int argc, char *argv[])
|
|||||||
surf.writeStats(Info);
|
surf.writeStats(Info);
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
|
|
||||||
|
|
||||||
|
// Determine path and extension
|
||||||
|
fileName surfFileNameBase(surfFileName.name());
|
||||||
|
const word fileType = surfFileNameBase.ext();
|
||||||
|
// Strip extension
|
||||||
|
surfFileNameBase = surfFileNameBase.lessExt();
|
||||||
|
// If extension was .gz strip original extension
|
||||||
|
if (fileType == "gz")
|
||||||
|
{
|
||||||
|
surfFileNameBase = surfFileNameBase.lessExt();
|
||||||
|
}
|
||||||
|
const fileName surfFilePath(surfFileName.path());
|
||||||
|
|
||||||
|
|
||||||
// write bounding box corners
|
// write bounding box corners
|
||||||
if (args.optionFound("blockMesh"))
|
if (args.optionFound("blockMesh"))
|
||||||
{
|
{
|
||||||
@ -515,12 +624,12 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
DynamicList<label> problemFaces(surf.size()/100 + 1);
|
DynamicList<label> problemFaces(surf.size()/100 + 1);
|
||||||
|
|
||||||
const labelListList& eFaces = surf.edgeFaces();
|
const labelListList& edgeFaces = surf.edgeFaces();
|
||||||
|
|
||||||
label nSingleEdges = 0;
|
label nSingleEdges = 0;
|
||||||
forAll(eFaces, edgeI)
|
forAll(edgeFaces, edgeI)
|
||||||
{
|
{
|
||||||
const labelList& myFaces = eFaces[edgeI];
|
const labelList& myFaces = edgeFaces[edgeI];
|
||||||
|
|
||||||
if (myFaces.size() == 1)
|
if (myFaces.size() == 1)
|
||||||
{
|
{
|
||||||
@ -531,9 +640,9 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
label nMultEdges = 0;
|
label nMultEdges = 0;
|
||||||
forAll(eFaces, edgeI)
|
forAll(edgeFaces, edgeI)
|
||||||
{
|
{
|
||||||
const labelList& myFaces = eFaces[edgeI];
|
const labelList& myFaces = edgeFaces[edgeI];
|
||||||
|
|
||||||
if (myFaces.size() > 2)
|
if (myFaces.size() > 2)
|
||||||
{
|
{
|
||||||
@ -549,7 +658,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if ((nSingleEdges != 0) || (nMultEdges != 0))
|
if ((nSingleEdges != 0) || (nMultEdges != 0))
|
||||||
{
|
{
|
||||||
Info<< "Surface is not closed since not all edges connected to "
|
Info<< "Surface is not closed since not all edges ("
|
||||||
|
<< edgeFaces.size() << ") connected to "
|
||||||
<< "two faces:" << endl
|
<< "two faces:" << endl
|
||||||
<< " connected to one face : " << nSingleEdges << endl
|
<< " connected to one face : " << nSingleEdges << endl
|
||||||
<< " connected to >2 faces : " << nMultEdges << endl;
|
<< " connected to >2 faces : " << nMultEdges << endl;
|
||||||
@ -578,10 +688,9 @@ int main(int argc, char *argv[])
|
|||||||
boolList borderEdge(surf.nEdges(), false);
|
boolList borderEdge(surf.nEdges(), false);
|
||||||
if (splitNonManifold)
|
if (splitNonManifold)
|
||||||
{
|
{
|
||||||
const labelListList& eFaces = surf.edgeFaces();
|
forAll(edgeFaces, edgeI)
|
||||||
forAll(eFaces, edgeI)
|
|
||||||
{
|
{
|
||||||
if (eFaces[edgeI].size() > 2)
|
if (edgeFaces[edgeI].size() > 2)
|
||||||
{
|
{
|
||||||
borderEdge[edgeI] = true;
|
borderEdge[edgeI] = true;
|
||||||
}
|
}
|
||||||
@ -597,85 +706,15 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
Info<< "Splitting surface into parts ..." << endl << endl;
|
Info<< "Splitting surface into parts ..." << endl << endl;
|
||||||
|
|
||||||
fileName surfFileNameBase(surfFileName.name());
|
writeZoning(surf, faceZone, "zone", surfFilePath, surfFileNameBase);
|
||||||
const word fileType = surfFileNameBase.ext();
|
writeParts
|
||||||
// Strip extension
|
(
|
||||||
surfFileNameBase = surfFileNameBase.lessExt();
|
surf,
|
||||||
// If extension was .gz strip original extension
|
numZones,
|
||||||
if (fileType == "gz")
|
faceZone,
|
||||||
{
|
surfFilePath,
|
||||||
surfFileNameBase = surfFileNameBase.lessExt();
|
surfFileNameBase
|
||||||
}
|
);
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
Info<< "Writing zoning to "
|
|
||||||
<< fileName
|
|
||||||
(
|
|
||||||
"zone_"
|
|
||||||
+ surfFileNameBase
|
|
||||||
+ '.'
|
|
||||||
+ vtkSurfaceWriter::typeName
|
|
||||||
)
|
|
||||||
<< "..." << endl << endl;
|
|
||||||
|
|
||||||
// Convert data
|
|
||||||
scalarField scalarFaceZone(faceZone.size());
|
|
||||||
forAll(faceZone, i)
|
|
||||||
{
|
|
||||||
scalarFaceZone[i] = faceZone[i];
|
|
||||||
}
|
|
||||||
faceList faces(surf.size());
|
|
||||||
forAll(surf, i)
|
|
||||||
{
|
|
||||||
faces[i] = surf[i].triFaceFace();
|
|
||||||
}
|
|
||||||
|
|
||||||
vtkSurfaceWriter().write
|
|
||||||
(
|
|
||||||
surfFileName.path(),
|
|
||||||
surfFileNameBase,
|
|
||||||
surf.points(),
|
|
||||||
faces,
|
|
||||||
"zone",
|
|
||||||
scalarFaceZone,
|
|
||||||
false // face based data
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (label zone = 0; zone < numZones; zone++)
|
|
||||||
{
|
|
||||||
boolList includeMap(surf.size(), false);
|
|
||||||
|
|
||||||
forAll(faceZone, faceI)
|
|
||||||
{
|
|
||||||
if (faceZone[faceI] == zone)
|
|
||||||
{
|
|
||||||
includeMap[faceI] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
labelList pointMap;
|
|
||||||
labelList faceMap;
|
|
||||||
|
|
||||||
triSurface subSurf
|
|
||||||
(
|
|
||||||
surf.subsetMesh
|
|
||||||
(
|
|
||||||
includeMap,
|
|
||||||
pointMap,
|
|
||||||
faceMap
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
fileName subName(surfFileNameBase + "_" + name(zone) + ".obj");
|
|
||||||
|
|
||||||
Info<< "writing part " << zone << " size " << subSurf.size()
|
|
||||||
<< " to " << subName << endl;
|
|
||||||
|
|
||||||
subSurf.write(subName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,6 +739,15 @@ int main(int argc, char *argv[])
|
|||||||
if (numNormalZones > 1)
|
if (numNormalZones > 1)
|
||||||
{
|
{
|
||||||
Info<< "More than one normal orientation." << endl;
|
Info<< "More than one normal orientation." << endl;
|
||||||
|
writeZoning(surf, normalZone, "normal", surfFilePath, surfFileNameBase);
|
||||||
|
writeParts
|
||||||
|
(
|
||||||
|
surf,
|
||||||
|
numNormalZones,
|
||||||
|
normalZone,
|
||||||
|
surfFilePath,
|
||||||
|
surfFileNameBase + "_normal"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -99,7 +99,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
mesh.write(exportName);
|
mesh.write(exportName);
|
||||||
mesh.writeStats(Info);
|
mesh.writeStats(Info);
|
||||||
Info<< endl;
|
|
||||||
|
|
||||||
Info<< "\nEnd\n" << endl;
|
Info<< "\nEnd\n" << endl;
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -406,7 +406,7 @@ int main(int argc, char *argv[])
|
|||||||
str << "l " << 1 << ' ' << i + 1 << endl;
|
str << "l " << 1 << ' ' << i + 1 << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< nl << "End" << nl << endl;
|
Info<< "\nEnd\n" << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
3
applications/utilities/surface/surfaceInflate/Make/files
Normal file
3
applications/utilities/surface/surfaceInflate/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
surfaceInflate.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_APPBIN)/surfaceInflate
|
||||||
10
applications/utilities/surface/surfaceInflate/Make/options
Normal file
10
applications/utilities/surface/surfaceInflate/Make/options
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
EXE_INC = \
|
||||||
|
-I$(FOAM_SRC)/triSurface/lnInclude \
|
||||||
|
-I$(FOAM_SRC)/surfMesh/lnInclude \
|
||||||
|
-I$(FOAM_SRC)/meshTools/lnInclude
|
||||||
|
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-ltriSurface \
|
||||||
|
-lsurfMesh \
|
||||||
|
-lmeshTools
|
||||||
879
applications/utilities/surface/surfaceInflate/surfaceInflate.C
Normal file
879
applications/utilities/surface/surfaceInflate/surfaceInflate.C
Normal file
@ -0,0 +1,879 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Application
|
||||||
|
surfaceInflate
|
||||||
|
|
||||||
|
Description
|
||||||
|
Inflates surface. WIP. Checks for overlaps and locally lowers
|
||||||
|
inflation distance
|
||||||
|
|
||||||
|
Usage
|
||||||
|
- surfaceInflate [OPTION]
|
||||||
|
|
||||||
|
\param -checkSelfIntersection \n
|
||||||
|
Includes checks for self-intersection.
|
||||||
|
|
||||||
|
\param -nSmooth
|
||||||
|
Specify number of smoothing iterations
|
||||||
|
|
||||||
|
\param -featureAngle
|
||||||
|
Specify a feature angle
|
||||||
|
|
||||||
|
|
||||||
|
E.g. inflate surface by 2cm with 1.5 safety factor:
|
||||||
|
surfaceInflate DTC-scaled.obj 0.02 1.5 -featureAngle 45 -nSmooth 2
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "argList.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "triSurfaceFields.H"
|
||||||
|
#include "triSurfaceMesh.H"
|
||||||
|
#include "triSurfaceGeoMesh.H"
|
||||||
|
#include "PackedBoolList.H"
|
||||||
|
#include "OBJstream.H"
|
||||||
|
#include "surfaceFeatures.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
scalar calcVertexNormalWeight
|
||||||
|
(
|
||||||
|
const triFace& f,
|
||||||
|
const label pI,
|
||||||
|
const vector& fN,
|
||||||
|
const pointField& points
|
||||||
|
)
|
||||||
|
{
|
||||||
|
label index = findIndex(f, pI);
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
{
|
||||||
|
FatalErrorIn("calcVertexNormals()")
|
||||||
|
<< "Point not in face" << abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const vector e1 = points[f[index]] - points[f[f.fcIndex(index)]];
|
||||||
|
const vector e2 = points[f[index]] - points[f[f.rcIndex(index)]];
|
||||||
|
|
||||||
|
return mag(fN)/(magSqr(e1)*magSqr(e2) + VSMALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tmp<vectorField> calcVertexNormals(const triSurface& surf)
|
||||||
|
{
|
||||||
|
// Weighted average of normals of faces attached to the vertex
|
||||||
|
// Weight = fA / (mag(e0)^2 * mag(e1)^2);
|
||||||
|
tmp<vectorField> tpointNormals
|
||||||
|
(
|
||||||
|
new pointField(surf.nPoints(), vector::zero)
|
||||||
|
);
|
||||||
|
vectorField& pointNormals = tpointNormals();
|
||||||
|
|
||||||
|
const pointField& points = surf.points();
|
||||||
|
const labelListList& pointFaces = surf.pointFaces();
|
||||||
|
const labelList& meshPoints = surf.meshPoints();
|
||||||
|
|
||||||
|
forAll(pointFaces, pI)
|
||||||
|
{
|
||||||
|
const labelList& pFaces = pointFaces[pI];
|
||||||
|
|
||||||
|
forAll(pFaces, fI)
|
||||||
|
{
|
||||||
|
const label faceI = pFaces[fI];
|
||||||
|
const triFace& f = surf[faceI];
|
||||||
|
|
||||||
|
vector fN = f.normal(points);
|
||||||
|
|
||||||
|
scalar weight = calcVertexNormalWeight
|
||||||
|
(
|
||||||
|
f,
|
||||||
|
meshPoints[pI],
|
||||||
|
fN,
|
||||||
|
points
|
||||||
|
);
|
||||||
|
|
||||||
|
pointNormals[pI] += weight*fN;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointNormals[pI] /= mag(pointNormals[pI]) + VSMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tpointNormals;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tmp<vectorField> calcPointNormals
|
||||||
|
(
|
||||||
|
const triSurface& s,
|
||||||
|
const PackedBoolList& isFeaturePoint,
|
||||||
|
const List<surfaceFeatures::edgeStatus>& edgeStat
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//const pointField pointNormals(s.pointNormals());
|
||||||
|
tmp<vectorField> tpointNormals(calcVertexNormals(s));
|
||||||
|
vectorField& pointNormals = tpointNormals();
|
||||||
|
|
||||||
|
|
||||||
|
// feature edges: create edge normals from edgeFaces only.
|
||||||
|
{
|
||||||
|
const labelListList& edgeFaces = s.edgeFaces();
|
||||||
|
|
||||||
|
labelList nNormals(s.nPoints(), 0);
|
||||||
|
forAll(edgeStat, edgeI)
|
||||||
|
{
|
||||||
|
if (edgeStat[edgeI] != surfaceFeatures::NONE)
|
||||||
|
{
|
||||||
|
const edge& e = s.edges()[edgeI];
|
||||||
|
forAll(e, i)
|
||||||
|
{
|
||||||
|
if (!isFeaturePoint[e[i]])
|
||||||
|
{
|
||||||
|
pointNormals[e[i]] = vector::zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(edgeStat, edgeI)
|
||||||
|
{
|
||||||
|
if (edgeStat[edgeI] != surfaceFeatures::NONE)
|
||||||
|
{
|
||||||
|
const labelList& eFaces = edgeFaces[edgeI];
|
||||||
|
|
||||||
|
// Get average edge normal
|
||||||
|
vector n = vector::zero;
|
||||||
|
forAll(eFaces, i)
|
||||||
|
{
|
||||||
|
n += s.faceNormals()[eFaces[i]];
|
||||||
|
}
|
||||||
|
n /= eFaces.size();
|
||||||
|
|
||||||
|
|
||||||
|
// Sum to points
|
||||||
|
const edge& e = s.edges()[edgeI];
|
||||||
|
forAll(e, i)
|
||||||
|
{
|
||||||
|
if (!isFeaturePoint[e[i]])
|
||||||
|
{
|
||||||
|
pointNormals[e[i]] += n;
|
||||||
|
nNormals[e[i]]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(nNormals, pointI)
|
||||||
|
{
|
||||||
|
if (nNormals[pointI] > 0)
|
||||||
|
{
|
||||||
|
pointNormals[pointI] /= mag(pointNormals[pointI]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
forAll(pointNormals, pointI)
|
||||||
|
{
|
||||||
|
if (mag(mag(pointNormals[pointI])-1) > SMALL)
|
||||||
|
{
|
||||||
|
FatalErrorIn("calcPointNormals()") << "unitialised"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tpointNormals;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void detectSelfIntersections
|
||||||
|
(
|
||||||
|
const triSurfaceMesh& s,
|
||||||
|
PackedBoolList& isEdgeIntersecting
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const edgeList& edges = s.edges();
|
||||||
|
const indexedOctree<treeDataTriSurface>& tree = s.tree();
|
||||||
|
const labelList& meshPoints = s.meshPoints();
|
||||||
|
const pointField& points = s.points();
|
||||||
|
|
||||||
|
isEdgeIntersecting.setSize(edges.size());
|
||||||
|
isEdgeIntersecting = false;
|
||||||
|
|
||||||
|
forAll(edges, edgeI)
|
||||||
|
{
|
||||||
|
const edge& e = edges[edgeI];
|
||||||
|
|
||||||
|
pointIndexHit hitInfo
|
||||||
|
(
|
||||||
|
tree.findLine
|
||||||
|
(
|
||||||
|
points[meshPoints[e[0]]],
|
||||||
|
points[meshPoints[e[1]]],
|
||||||
|
treeDataTriSurface::findSelfIntersectOp(tree, edgeI)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hitInfo.hit())
|
||||||
|
{
|
||||||
|
isEdgeIntersecting[edgeI] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
label detectIntersectionPoints
|
||||||
|
(
|
||||||
|
const scalar tolerance,
|
||||||
|
const triSurfaceMesh& s,
|
||||||
|
|
||||||
|
const scalar extendFactor,
|
||||||
|
const pointField& initialPoints,
|
||||||
|
const vectorField& displacement,
|
||||||
|
|
||||||
|
const bool checkSelfIntersect,
|
||||||
|
const PackedBoolList& initialIsEdgeIntersecting,
|
||||||
|
|
||||||
|
PackedBoolList& isPointOnHitEdge,
|
||||||
|
scalarField& scale
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const pointField initialLocalPoints(initialPoints, s.meshPoints());
|
||||||
|
const List<labelledTri>& localFaces = s.localFaces();
|
||||||
|
|
||||||
|
|
||||||
|
label nHits = 0;
|
||||||
|
isPointOnHitEdge.setSize(s.nPoints());
|
||||||
|
isPointOnHitEdge = false;
|
||||||
|
|
||||||
|
|
||||||
|
// 1. Extrusion offset vectors intersecting new surface location
|
||||||
|
{
|
||||||
|
scalar tol = max(tolerance, 10*s.tolerance());
|
||||||
|
|
||||||
|
// Collect all the edge vectors. Slightly shorten the edges to prevent
|
||||||
|
// finding lots of intersections. The fast triangle intersection routine
|
||||||
|
// has problems with rays passing through a point of the
|
||||||
|
// triangle.
|
||||||
|
pointField start(initialLocalPoints+tol*displacement);
|
||||||
|
pointField end(initialLocalPoints+extendFactor*displacement);
|
||||||
|
|
||||||
|
List<pointIndexHit> hits;
|
||||||
|
s.findLineAny(start, end, hits);
|
||||||
|
|
||||||
|
forAll(hits, pointI)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
hits[pointI].hit()
|
||||||
|
&& findIndex(localFaces[hits[pointI].index()], pointI) == -1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
scale[pointI] = max(0.0, scale[pointI]-0.2);
|
||||||
|
|
||||||
|
isPointOnHitEdge[pointI] = true;
|
||||||
|
nHits++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 2. (new) surface self intersections
|
||||||
|
if (checkSelfIntersect)
|
||||||
|
{
|
||||||
|
PackedBoolList isEdgeIntersecting;
|
||||||
|
detectSelfIntersections(s, isEdgeIntersecting);
|
||||||
|
|
||||||
|
const edgeList& edges = s.edges();
|
||||||
|
const pointField& points = s.points();
|
||||||
|
|
||||||
|
forAll(edges, edgeI)
|
||||||
|
{
|
||||||
|
const edge& e = edges[edgeI];
|
||||||
|
|
||||||
|
if (isEdgeIntersecting[edgeI] && !initialIsEdgeIntersecting[edgeI])
|
||||||
|
{
|
||||||
|
if (isPointOnHitEdge.set(e[0]))
|
||||||
|
{
|
||||||
|
label start = s.meshPoints()[e[0]];
|
||||||
|
const point& pt = points[start];
|
||||||
|
|
||||||
|
Pout<< "Additional self intersection at "
|
||||||
|
<< pt
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
scale[e[0]] = max(0.0, scale[e[0]]-0.2);
|
||||||
|
nHits++;
|
||||||
|
}
|
||||||
|
if (isPointOnHitEdge.set(e[1]))
|
||||||
|
{
|
||||||
|
label end = s.meshPoints()[e[1]];
|
||||||
|
const point& pt = points[end];
|
||||||
|
|
||||||
|
Pout<< "Additional self intersection at "
|
||||||
|
<< pt
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
scale[e[1]] = max(0.0, scale[e[1]]-0.2);
|
||||||
|
nHits++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nHits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tmp<scalarField> avg
|
||||||
|
(
|
||||||
|
const triSurface& s,
|
||||||
|
const scalarField& fld,
|
||||||
|
const scalarField& edgeWeights
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tmp<scalarField> tres(new scalarField(s.nPoints(), 0.0));
|
||||||
|
scalarField& res = tres();
|
||||||
|
|
||||||
|
scalarField sumWeight(s.nPoints(), 0.0);
|
||||||
|
|
||||||
|
const edgeList& edges = s.edges();
|
||||||
|
|
||||||
|
forAll(edges, edgeI)
|
||||||
|
{
|
||||||
|
const edge& e = edges[edgeI];
|
||||||
|
const scalar w = edgeWeights[edgeI];
|
||||||
|
|
||||||
|
res[e[0]] += w*fld[e[1]];
|
||||||
|
sumWeight[e[0]] += w;
|
||||||
|
|
||||||
|
res[e[1]] += w*fld[e[0]];
|
||||||
|
sumWeight[e[1]] += w;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Average
|
||||||
|
// ~~~~~~~
|
||||||
|
|
||||||
|
forAll(res, pointI)
|
||||||
|
{
|
||||||
|
if (mag(sumWeight[pointI]) < VSMALL)
|
||||||
|
{
|
||||||
|
// Unconnected point. Take over original value
|
||||||
|
res[pointI] = fld[pointI];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res[pointI] /= sumWeight[pointI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tres;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void minSmooth
|
||||||
|
(
|
||||||
|
const triSurface& s,
|
||||||
|
const PackedBoolList& isAffectedPoint,
|
||||||
|
const scalarField& fld,
|
||||||
|
scalarField& newFld
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
const edgeList& edges = s.edges();
|
||||||
|
const pointField& points = s.points();
|
||||||
|
const labelList& mp = s.meshPoints();
|
||||||
|
|
||||||
|
scalarField edgeWeights(edges.size());
|
||||||
|
forAll(edges, edgeI)
|
||||||
|
{
|
||||||
|
const edge& e = edges[edgeI];
|
||||||
|
scalar w = mag(points[mp[e[0]]]-points[mp[e[1]]]);
|
||||||
|
|
||||||
|
edgeWeights[edgeI] = 1.0/(max(w, SMALL));
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp<scalarField> tavgFld = avg(s, fld, edgeWeights);
|
||||||
|
|
||||||
|
const scalarField& avgFld = tavgFld();
|
||||||
|
|
||||||
|
forAll(fld, pointI)
|
||||||
|
{
|
||||||
|
if (isAffectedPoint.get(pointI) == 1)
|
||||||
|
{
|
||||||
|
newFld[pointI] = min
|
||||||
|
(
|
||||||
|
fld[pointI],
|
||||||
|
0.5*fld[pointI] + 0.5*avgFld[pointI]
|
||||||
|
//avgFld[pointI]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void lloydsSmoothing
|
||||||
|
(
|
||||||
|
const label nSmooth,
|
||||||
|
triSurface& s,
|
||||||
|
const PackedBoolList& isFeaturePoint,
|
||||||
|
const List<surfaceFeatures::edgeStatus>& edgeStat,
|
||||||
|
const PackedBoolList& isAffectedPoint
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const labelList& meshPoints = s.meshPoints();
|
||||||
|
const edgeList& edges = s.edges();
|
||||||
|
|
||||||
|
|
||||||
|
PackedBoolList isSmoothPoint(isAffectedPoint);
|
||||||
|
// Extend isSmoothPoint
|
||||||
|
{
|
||||||
|
PackedBoolList newIsSmoothPoint(isSmoothPoint);
|
||||||
|
forAll(edges, edgeI)
|
||||||
|
{
|
||||||
|
const edge& e = edges[edgeI];
|
||||||
|
if (isSmoothPoint[e[0]])
|
||||||
|
{
|
||||||
|
newIsSmoothPoint[e[1]] = true;
|
||||||
|
}
|
||||||
|
if (isSmoothPoint[e[1]])
|
||||||
|
{
|
||||||
|
newIsSmoothPoint[e[0]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Info<< "From points-to-smooth " << isSmoothPoint.count()
|
||||||
|
<< " to " << newIsSmoothPoint.count()
|
||||||
|
<< endl;
|
||||||
|
isSmoothPoint.transfer(newIsSmoothPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do some smoothing (Lloyds algorithm) around problematic points
|
||||||
|
for (label i = 0; i < nSmooth; i++)
|
||||||
|
{
|
||||||
|
const labelListList& pointFaces = s.pointFaces();
|
||||||
|
const pointField& faceCentres = s.faceCentres();
|
||||||
|
|
||||||
|
pointField newPoints(s.points());
|
||||||
|
forAll(isSmoothPoint, pointI)
|
||||||
|
{
|
||||||
|
if (isSmoothPoint[pointI] && !isFeaturePoint[pointI])
|
||||||
|
{
|
||||||
|
const labelList& pFaces = pointFaces[pointI];
|
||||||
|
|
||||||
|
point avg = point::zero;
|
||||||
|
forAll(pFaces, pFaceI)
|
||||||
|
{
|
||||||
|
avg += faceCentres[pFaces[pFaceI]];
|
||||||
|
}
|
||||||
|
avg /= pFaces.size();
|
||||||
|
newPoints[meshPoints[pointI]] = avg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Move points on feature edges only according to feature edges.
|
||||||
|
|
||||||
|
const pointField& points = s.points();
|
||||||
|
|
||||||
|
vectorField pointSum(s.nPoints(), vector::zero);
|
||||||
|
labelList nPointSum(s.nPoints(), 0);
|
||||||
|
|
||||||
|
forAll(edges, edgeI)
|
||||||
|
{
|
||||||
|
if (edgeStat[edgeI] != surfaceFeatures::NONE)
|
||||||
|
{
|
||||||
|
const edge& e = edges[edgeI];
|
||||||
|
const point& start = points[meshPoints[e[0]]];
|
||||||
|
const point& end = points[meshPoints[e[1]]];
|
||||||
|
point eMid = 0.5*(start+end);
|
||||||
|
pointSum[e[0]] += eMid;
|
||||||
|
nPointSum[e[0]]++;
|
||||||
|
pointSum[e[1]] += eMid;
|
||||||
|
nPointSum[e[1]]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(pointSum, pointI)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
isSmoothPoint[pointI]
|
||||||
|
&& isFeaturePoint[pointI]
|
||||||
|
&& nPointSum[pointI] >= 2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
newPoints[meshPoints[pointI]] =
|
||||||
|
pointSum[pointI]/nPointSum[pointI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
s.movePoints(newPoints);
|
||||||
|
|
||||||
|
|
||||||
|
// Extend isSmoothPoint
|
||||||
|
{
|
||||||
|
PackedBoolList newIsSmoothPoint(isSmoothPoint);
|
||||||
|
forAll(edges, edgeI)
|
||||||
|
{
|
||||||
|
const edge& e = edges[edgeI];
|
||||||
|
if (isSmoothPoint[e[0]])
|
||||||
|
{
|
||||||
|
newIsSmoothPoint[e[1]] = true;
|
||||||
|
}
|
||||||
|
if (isSmoothPoint[e[1]])
|
||||||
|
{
|
||||||
|
newIsSmoothPoint[e[0]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Info<< "From points-to-smooth " << isSmoothPoint.count()
|
||||||
|
<< " to " << newIsSmoothPoint.count()
|
||||||
|
<< endl;
|
||||||
|
isSmoothPoint.transfer(newIsSmoothPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Main program:
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
argList::addNote("Inflates surface according to point normals.");
|
||||||
|
|
||||||
|
argList::noParallel();
|
||||||
|
argList::addNote
|
||||||
|
(
|
||||||
|
"Creates inflated version of surface using point normals."
|
||||||
|
" Takes surface, distance to inflate and additional safety factor"
|
||||||
|
);
|
||||||
|
argList::addBoolOption
|
||||||
|
(
|
||||||
|
"checkSelfIntersection",
|
||||||
|
"also check for self-intersection"
|
||||||
|
);
|
||||||
|
argList::addOption
|
||||||
|
(
|
||||||
|
"nSmooth",
|
||||||
|
"integer",
|
||||||
|
"number of smoothing iterations (default 20)"
|
||||||
|
);
|
||||||
|
argList::addOption
|
||||||
|
(
|
||||||
|
"featureAngle",
|
||||||
|
"scalar",
|
||||||
|
"feature angle"
|
||||||
|
);
|
||||||
|
argList::addBoolOption
|
||||||
|
(
|
||||||
|
"debug",
|
||||||
|
"switch on additional debug information"
|
||||||
|
);
|
||||||
|
|
||||||
|
argList::validArgs.append("inputFile");
|
||||||
|
argList::validArgs.append("distance");
|
||||||
|
argList::validArgs.append("safety factor [1..]");
|
||||||
|
|
||||||
|
#include "setRootCase.H"
|
||||||
|
#include "createTime.H"
|
||||||
|
runTime.functionObjects().off();
|
||||||
|
|
||||||
|
const word inputName(args.args()[1]);
|
||||||
|
const scalar distance(args.argRead<scalar>(2));
|
||||||
|
const scalar extendFactor(args.argRead<scalar>(3));
|
||||||
|
const bool checkSelfIntersect = args.optionFound("checkSelfIntersection");
|
||||||
|
const label nSmooth = args.optionLookupOrDefault("nSmooth", 10);
|
||||||
|
const scalar featureAngle = args.optionLookupOrDefault<scalar>
|
||||||
|
(
|
||||||
|
"featureAngle",
|
||||||
|
180
|
||||||
|
);
|
||||||
|
const bool debug = args.optionFound("debug");
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Inflating surface " << inputName
|
||||||
|
<< " according to point normals" << nl
|
||||||
|
<< " distance : " << distance << nl
|
||||||
|
<< " safety factor : " << extendFactor << nl
|
||||||
|
<< " self intersection test : " << checkSelfIntersect << nl
|
||||||
|
<< " smoothing iterations : " << nSmooth << nl
|
||||||
|
<< " feature angle : " << featureAngle << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
|
if (extendFactor < 1 || extendFactor > 10)
|
||||||
|
{
|
||||||
|
FatalErrorIn(args.executable())
|
||||||
|
<< "Illegal safety factor " << extendFactor
|
||||||
|
<< ". It is usually 1..2"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Load triSurfaceMesh
|
||||||
|
triSurfaceMesh s
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
inputName, // name
|
||||||
|
runTime.constant(), // instance
|
||||||
|
"triSurface", // local
|
||||||
|
runTime, // registry
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mark features
|
||||||
|
const surfaceFeatures features(s, 180.0-featureAngle);
|
||||||
|
|
||||||
|
Info<< "Detected features:" << nl
|
||||||
|
<< " feature points : " << features.featurePoints().size()
|
||||||
|
<< " out of " << s.nPoints() << nl
|
||||||
|
<< " feature edges : " << features.featureEdges().size()
|
||||||
|
<< " out of " << s.nEdges() << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
PackedBoolList isFeaturePoint(s.nPoints());
|
||||||
|
forAll(features.featurePoints(), i)
|
||||||
|
{
|
||||||
|
label pointI = features.featurePoints()[i];
|
||||||
|
isFeaturePoint[pointI] = true;
|
||||||
|
}
|
||||||
|
const List<surfaceFeatures::edgeStatus> edgeStat(features.toStatus());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const pointField initialPoints(s.points());
|
||||||
|
|
||||||
|
|
||||||
|
// Construct scale
|
||||||
|
Info<< "Constructing field scale\n" << endl;
|
||||||
|
triSurfacePointScalarField scale
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"scale", // name
|
||||||
|
runTime.timeName(), // instance
|
||||||
|
s, // registry
|
||||||
|
IOobject::READ_IF_PRESENT,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
s,
|
||||||
|
dimensionedScalar("scale", dimLength, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Construct unit normals
|
||||||
|
|
||||||
|
Info<< "Calculating vertex normals\n" << endl;
|
||||||
|
const pointField pointNormals
|
||||||
|
(
|
||||||
|
calcPointNormals
|
||||||
|
(
|
||||||
|
s,
|
||||||
|
isFeaturePoint,
|
||||||
|
edgeStat
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Construct pointDisplacement
|
||||||
|
Info<< "Constructing field pointDisplacement\n" << endl;
|
||||||
|
triSurfacePointVectorField pointDisplacement
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"pointDisplacement", // name
|
||||||
|
runTime.timeName(), // instance
|
||||||
|
s, // registry
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
s,
|
||||||
|
dimLength,
|
||||||
|
distance*scale*pointNormals
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const labelList& meshPoints = s.meshPoints();
|
||||||
|
|
||||||
|
|
||||||
|
// Any point on any intersected edge in any of the iterations
|
||||||
|
PackedBoolList isScaledPoint(s.nPoints());
|
||||||
|
|
||||||
|
|
||||||
|
// Detect any self intersections on initial mesh
|
||||||
|
PackedBoolList initialIsEdgeIntersecting;
|
||||||
|
if (checkSelfIntersect)
|
||||||
|
{
|
||||||
|
detectSelfIntersections(s, initialIsEdgeIntersecting);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Mark all edges as already self intersecting so avoid detecting any
|
||||||
|
// new ones
|
||||||
|
initialIsEdgeIntersecting.setSize(s.nEdges(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Inflate
|
||||||
|
while (runTime.loop())
|
||||||
|
{
|
||||||
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
|
// Move to new location
|
||||||
|
pointField newPoints(initialPoints);
|
||||||
|
forAll(meshPoints, i)
|
||||||
|
{
|
||||||
|
newPoints[meshPoints[i]] += pointDisplacement[i];
|
||||||
|
}
|
||||||
|
s.movePoints(newPoints);
|
||||||
|
Info<< "Bounding box : " << s.bounds() << endl;
|
||||||
|
|
||||||
|
|
||||||
|
// Work out scale from pointDisplacement
|
||||||
|
forAll(scale, pointI)
|
||||||
|
{
|
||||||
|
if (s.pointFaces()[pointI].size())
|
||||||
|
{
|
||||||
|
scale[pointI] = mag(pointDisplacement[pointI])/distance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scale[pointI] = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Scale : " << gAverage(scale) << endl;
|
||||||
|
Info<< "Displacement : " << gAverage(pointDisplacement) << endl;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Detect any intersections and scale back
|
||||||
|
PackedBoolList isAffectedPoint;
|
||||||
|
label nIntersections = detectIntersectionPoints
|
||||||
|
(
|
||||||
|
1e-9, // intersection tolerance
|
||||||
|
s,
|
||||||
|
extendFactor,
|
||||||
|
initialPoints,
|
||||||
|
pointDisplacement,
|
||||||
|
|
||||||
|
checkSelfIntersect,
|
||||||
|
initialIsEdgeIntersecting,
|
||||||
|
|
||||||
|
isAffectedPoint,
|
||||||
|
scale
|
||||||
|
);
|
||||||
|
Info<< "Detected " << nIntersections << " intersections" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
if (nIntersections == 0)
|
||||||
|
{
|
||||||
|
runTime.write();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Accumulate all affected points
|
||||||
|
forAll(isAffectedPoint, pointI)
|
||||||
|
{
|
||||||
|
if (isAffectedPoint[pointI])
|
||||||
|
{
|
||||||
|
isScaledPoint[pointI] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smear out lowering of scale so any edges not found are
|
||||||
|
// still included
|
||||||
|
for (label i = 0; i < nSmooth; i++)
|
||||||
|
{
|
||||||
|
triSurfacePointScalarField oldScale(scale);
|
||||||
|
oldScale.rename("oldScale");
|
||||||
|
minSmooth
|
||||||
|
(
|
||||||
|
s,
|
||||||
|
PackedBoolList(s.nPoints(), true),
|
||||||
|
oldScale,
|
||||||
|
scale
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// From scale update the pointDisplacement
|
||||||
|
pointDisplacement *= distance*scale/mag(pointDisplacement);
|
||||||
|
|
||||||
|
|
||||||
|
// Do some smoothing (Lloyds algorithm)
|
||||||
|
lloydsSmoothing(nSmooth, s, isFeaturePoint, edgeStat, isAffectedPoint);
|
||||||
|
|
||||||
|
|
||||||
|
// Update pointDisplacement
|
||||||
|
const pointField& pts = s.points();
|
||||||
|
forAll(meshPoints, i)
|
||||||
|
{
|
||||||
|
label meshPointI = meshPoints[i];
|
||||||
|
pointDisplacement[i] = pts[meshPointI]-initialPoints[meshPointI];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Write
|
||||||
|
runTime.write();
|
||||||
|
|
||||||
|
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Detected overall intersecting points " << isScaledPoint.count()
|
||||||
|
<< " out of " << s.nPoints() << nl << endl;
|
||||||
|
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
OBJstream str(runTime.path()/"isScaledPoint.obj");
|
||||||
|
forAll(isScaledPoint, pointI)
|
||||||
|
{
|
||||||
|
if (isScaledPoint[pointI])
|
||||||
|
{
|
||||||
|
str.write(initialPoints[meshPoints[pointI]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Info << "End\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -189,8 +189,6 @@ int main(int argc, char *argv[])
|
|||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
pointField newPoints(surf1.localPoints());
|
|
||||||
|
|
||||||
for (label iter = 0; iter < iters; iter++)
|
for (label iter = 0; iter < iters; iter++)
|
||||||
{
|
{
|
||||||
// Lambda
|
// Lambda
|
||||||
|
|||||||
7
applications/utilities/surface/surfacePatch/Make/files
Normal file
7
applications/utilities/surface/surfacePatch/Make/files
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
searchableSurfaceModifier/searchableSurfaceModifier.C
|
||||||
|
searchableSurfaceModifier/autoPatch.C
|
||||||
|
searchableSurfaceModifier/cut.C
|
||||||
|
|
||||||
|
surfacePatch.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_APPBIN)/surfacePatch
|
||||||
10
applications/utilities/surface/surfacePatch/Make/options
Normal file
10
applications/utilities/surface/surfacePatch/Make/options
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
EXE_INC = \
|
||||||
|
-IsearchableSurfaceModifier \
|
||||||
|
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||||
|
-I$(LIB_SRC)/fileFormats/lnInclude \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude
|
||||||
|
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-ltriSurface \
|
||||||
|
-lmeshTools
|
||||||
@ -0,0 +1,155 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "autoPatch.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "surfaceFeatures.H"
|
||||||
|
#include "triSurfaceMesh.H"
|
||||||
|
#include "PatchTools.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace searchableSurfaceModifiers
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(autoPatch, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
searchableSurfaceModifier,
|
||||||
|
autoPatch,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableSurfaceModifiers::autoPatch::autoPatch
|
||||||
|
(
|
||||||
|
const searchableSurfaces& geometry,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
searchableSurfaceModifier(geometry, dict),
|
||||||
|
featureAngle_(readScalar(dict.lookup("featureAngle")))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableSurfaceModifiers::autoPatch::~autoPatch()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::searchableSurfaceModifiers::autoPatch::modify
|
||||||
|
(
|
||||||
|
const labelList& regions,
|
||||||
|
searchableSurface& geom
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
triSurface& surf = refCast<triSurfaceMesh>(geom);
|
||||||
|
|
||||||
|
surfaceFeatures set(surf, 180.0-featureAngle_);
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Feature set:" << nl
|
||||||
|
<< " feature points : " << set.featurePoints().size() << nl
|
||||||
|
<< " feature edges : " << set.featureEdges().size() << nl
|
||||||
|
<< " of which" << nl
|
||||||
|
<< " region edges : " << set.nRegionEdges() << nl
|
||||||
|
<< " external edges : " << set.nExternalEdges() << nl
|
||||||
|
<< " internal edges : " << set.nInternalEdges() << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
|
// Get per-edge status.
|
||||||
|
boolList borderEdge(surf.nEdges(), false);
|
||||||
|
forAll(set.featureEdges(), i)
|
||||||
|
{
|
||||||
|
borderEdge[set.featureEdges()[i]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
forAll(regions, i)
|
||||||
|
{
|
||||||
|
label regionI = regions[i];
|
||||||
|
|
||||||
|
labelList subRegion(surf.size(), -1);
|
||||||
|
label nSub = 0;
|
||||||
|
|
||||||
|
forAll(surf, faceI)
|
||||||
|
{
|
||||||
|
if (surf[faceI].region() == regionI && subRegion[faceI] == -1)
|
||||||
|
{
|
||||||
|
PatchTools::markZone(surf, borderEdge, faceI, nSub, subRegion);
|
||||||
|
nSub++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "For region " << surf.patches()[regionI].name()
|
||||||
|
<< " detected sub regions " << nSub << endl;
|
||||||
|
|
||||||
|
|
||||||
|
if (nSub > 1)
|
||||||
|
{
|
||||||
|
label nOldPatches = surf.patches().size();
|
||||||
|
|
||||||
|
for (label subI = 0; subI < nSub; subI++)
|
||||||
|
{
|
||||||
|
geometricSurfacePatch patch
|
||||||
|
(
|
||||||
|
surf.patches()[regionI].geometricType(),
|
||||||
|
surf.patches()[regionI].name() + Foam::name(subI),
|
||||||
|
surf.patches().size()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "For region " << surf.patches()[regionI].name()
|
||||||
|
<< " creating region " << patch.name() << endl;
|
||||||
|
|
||||||
|
surf.patches().append(patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(subRegion, faceI)
|
||||||
|
{
|
||||||
|
if (subRegion[faceI] != -1)
|
||||||
|
{
|
||||||
|
surf[faceI].region() = nOldPatches + subRegion[faceI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,104 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::searchableSurfaceModifier::autoPatch
|
||||||
|
|
||||||
|
Description
|
||||||
|
Patchify triangles based on a feature angle. Replacement of surfaceAutoPatch
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
autoPatch.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef autoPatch_H
|
||||||
|
#define autoPatch_H
|
||||||
|
|
||||||
|
#include "searchableSurfaceModifier.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace searchableSurfaceModifiers
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class autoPatch Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class autoPatch
|
||||||
|
:
|
||||||
|
public searchableSurfaceModifier
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Feature angle
|
||||||
|
const scalar featureAngle_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("autoPatch");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary
|
||||||
|
autoPatch(const searchableSurfaces&, const dictionary&);
|
||||||
|
|
||||||
|
//- Clone
|
||||||
|
autoPtr<searchableSurfaceModifier> clone() const
|
||||||
|
{
|
||||||
|
notImplemented("autoPtr<searchableSurfaceModifier> clone() const");
|
||||||
|
return autoPtr<searchableSurfaceModifier>(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~autoPatch();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Apply this selector
|
||||||
|
virtual bool modify(const labelList& regions, searchableSurface&) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace searchableSurfaceModifiers
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,390 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "cut.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "searchableSurfaces.H"
|
||||||
|
#include "triSurfaceMesh.H"
|
||||||
|
#include "searchableBox.H"
|
||||||
|
#include "searchableRotatedBox.H"
|
||||||
|
#include "surfaceIntersection.H"
|
||||||
|
#include "intersectedSurface.H"
|
||||||
|
#include "edgeIntersections.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace searchableSurfaceModifiers
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(cut, 0);
|
||||||
|
addToRunTimeSelectionTable(searchableSurfaceModifier, cut, dictionary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::searchableSurfaceModifiers::cut::triangulate
|
||||||
|
(
|
||||||
|
const faceList& fcs,
|
||||||
|
pointField& pts,
|
||||||
|
triSurface& cutSurf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
label nTris = 0;
|
||||||
|
forAll(fcs, i)
|
||||||
|
{
|
||||||
|
nTris += fcs[i].size()-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicList<labelledTri> tris(nTris);
|
||||||
|
|
||||||
|
forAll(fcs, i)
|
||||||
|
{
|
||||||
|
const face& f = fcs[i];
|
||||||
|
// Triangulate around vertex 0
|
||||||
|
for (label fp = 1; fp < f.size()-1; fp++)
|
||||||
|
{
|
||||||
|
tris.append(labelledTri(f[0], f[fp], f[f.fcIndex(fp)], i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
geometricSurfacePatchList patches(fcs.size());
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
patches[patchI] = geometricSurfacePatch
|
||||||
|
(
|
||||||
|
"",
|
||||||
|
"patch" + Foam::name(patchI),
|
||||||
|
patchI
|
||||||
|
);
|
||||||
|
}
|
||||||
|
cutSurf = triSurface(tris.xfer(), patches, pts.xfer());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::triSurface& Foam::searchableSurfaceModifiers::cut::triangulate
|
||||||
|
(
|
||||||
|
const searchableSurface& cutter,
|
||||||
|
triSurface& cutSurf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (isA<searchableBox>(cutter))
|
||||||
|
{
|
||||||
|
const searchableBox& bb = refCast<const searchableBox>(cutter);
|
||||||
|
|
||||||
|
pointField pts(bb.points());
|
||||||
|
triangulate(treeBoundBox::faces, pts, cutSurf);
|
||||||
|
|
||||||
|
return cutSurf;
|
||||||
|
}
|
||||||
|
else if (isA<searchableRotatedBox>(cutter))
|
||||||
|
{
|
||||||
|
const searchableRotatedBox& bb =
|
||||||
|
refCast<const searchableRotatedBox>(cutter);
|
||||||
|
|
||||||
|
pointField pts(bb.points());
|
||||||
|
triangulate(treeBoundBox::faces, pts, cutSurf);
|
||||||
|
|
||||||
|
return cutSurf;
|
||||||
|
}
|
||||||
|
else if (isA<triSurfaceMesh>(cutter))
|
||||||
|
{
|
||||||
|
return const_cast<triSurfaceMesh&>
|
||||||
|
(
|
||||||
|
refCast<const triSurfaceMesh>(cutter)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"searchableSurfaceModifiers::cut::triangulate\n"
|
||||||
|
"(\n"
|
||||||
|
" const searchableSurface&,\n"
|
||||||
|
" triSurface&\n"
|
||||||
|
")"
|
||||||
|
) << "Triangulation only supported for triSurfaceMesh, searchableBox"
|
||||||
|
<< ", not for surface " << cutter.name()
|
||||||
|
<< " of type " << cutter.type()
|
||||||
|
<< exit(FatalError);
|
||||||
|
return const_cast<triSurfaceMesh&>
|
||||||
|
(
|
||||||
|
refCast<const triSurfaceMesh>(cutter)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Keep on shuffling surface points until no more degenerate intersections.
|
||||||
|
// Moves both surfaces and updates set of edge cuts.
|
||||||
|
bool Foam::searchableSurfaceModifiers::cut::intersectSurfaces
|
||||||
|
(
|
||||||
|
triSurface& surf1,
|
||||||
|
edgeIntersections& edgeCuts1,
|
||||||
|
triSurface& surf2,
|
||||||
|
edgeIntersections& edgeCuts2
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
bool hasMoved1 = false;
|
||||||
|
bool hasMoved2 = false;
|
||||||
|
|
||||||
|
for (label iter = 0; iter < 10; iter++)
|
||||||
|
{
|
||||||
|
Info<< "Determining intersections of surf1 edges with surf2"
|
||||||
|
<< " faces" << endl;
|
||||||
|
|
||||||
|
// Determine surface1 edge intersections. Allow surface to be moved.
|
||||||
|
|
||||||
|
// Number of iterations needed to resolve degenerates
|
||||||
|
label nIters1 = 0;
|
||||||
|
{
|
||||||
|
triSurfaceSearch querySurf2(surf2);
|
||||||
|
|
||||||
|
scalarField surf1PointTol
|
||||||
|
(
|
||||||
|
1E-6*edgeIntersections::minEdgeLength(surf1)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Determine raw intersections
|
||||||
|
edgeCuts1 = edgeIntersections
|
||||||
|
(
|
||||||
|
surf1,
|
||||||
|
querySurf2,
|
||||||
|
surf1PointTol
|
||||||
|
);
|
||||||
|
|
||||||
|
// Shuffle a bit to resolve degenerate edge-face hits
|
||||||
|
{
|
||||||
|
pointField points1(surf1.points());
|
||||||
|
|
||||||
|
nIters1 =
|
||||||
|
edgeCuts1.removeDegenerates
|
||||||
|
(
|
||||||
|
5, // max iterations
|
||||||
|
surf1,
|
||||||
|
querySurf2,
|
||||||
|
surf1PointTol,
|
||||||
|
points1 // work array
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nIters1 != 0)
|
||||||
|
{
|
||||||
|
// Update geometric quantities
|
||||||
|
surf1.movePoints(points1);
|
||||||
|
hasMoved1 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Determining intersections of surf2 edges with surf1"
|
||||||
|
<< " faces" << endl;
|
||||||
|
|
||||||
|
label nIters2 = 0;
|
||||||
|
{
|
||||||
|
triSurfaceSearch querySurf1(surf1);
|
||||||
|
|
||||||
|
scalarField surf2PointTol
|
||||||
|
(
|
||||||
|
1E-6*edgeIntersections::minEdgeLength(surf2)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Determine raw intersections
|
||||||
|
edgeCuts2 = edgeIntersections
|
||||||
|
(
|
||||||
|
surf2,
|
||||||
|
querySurf1,
|
||||||
|
surf2PointTol
|
||||||
|
);
|
||||||
|
|
||||||
|
// Shuffle a bit to resolve degenerate edge-face hits
|
||||||
|
{
|
||||||
|
pointField points2(surf2.points());
|
||||||
|
|
||||||
|
nIters2 =
|
||||||
|
edgeCuts2.removeDegenerates
|
||||||
|
(
|
||||||
|
5, // max iterations
|
||||||
|
surf2,
|
||||||
|
querySurf1,
|
||||||
|
surf2PointTol,
|
||||||
|
points2 // work array
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nIters2 != 0)
|
||||||
|
{
|
||||||
|
// Update geometric quantities
|
||||||
|
surf2.movePoints(points2);
|
||||||
|
hasMoved2 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (nIters1 == 0 && nIters2 == 0)
|
||||||
|
{
|
||||||
|
//Info<< "** Resolved all intersections to be proper"
|
||||||
|
// << "edge-face pierce" << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (hasMoved1)
|
||||||
|
//{
|
||||||
|
// fileName newFile("surf1.ftr");
|
||||||
|
// Info<< "Surface 1 has been moved. Writing to " << newFile
|
||||||
|
// << endl;
|
||||||
|
// surf1.write(newFile);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//if (hasMoved2)
|
||||||
|
//{
|
||||||
|
// fileName newFile("surf2.ftr");
|
||||||
|
// Info<< "Surface 2 has been moved. Writing to " << newFile
|
||||||
|
// << endl;
|
||||||
|
// surf2.write(newFile);
|
||||||
|
//}
|
||||||
|
|
||||||
|
return hasMoved1 || hasMoved2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableSurfaceModifiers::cut::cut
|
||||||
|
(
|
||||||
|
const searchableSurfaces& geometry,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
searchableSurfaceModifier(geometry, dict),
|
||||||
|
cutterNames_(dict_.lookup("cutters"))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableSurfaceModifiers::cut::~cut()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::searchableSurfaceModifiers::cut::modify
|
||||||
|
(
|
||||||
|
const labelList& regions,
|
||||||
|
searchableSurface& geom
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
triSurface& surf = refCast<triSurfaceMesh>(geom);
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
// Find the surfaces to cut with
|
||||||
|
forAll(cutterNames_, cutNameI)
|
||||||
|
{
|
||||||
|
labelList geomIDs =
|
||||||
|
findStrings(cutterNames_[cutNameI], geometry_.names());
|
||||||
|
|
||||||
|
forAll(geomIDs, j)
|
||||||
|
{
|
||||||
|
label geomI = geomIDs[j];
|
||||||
|
const searchableSurface& cutter = geometry_[geomI];
|
||||||
|
|
||||||
|
// Triangulate
|
||||||
|
triSurface work;
|
||||||
|
triSurface& cutSurf = triangulate(cutter, work);
|
||||||
|
|
||||||
|
// Determine intersection (with perturbation)
|
||||||
|
edgeIntersections edge1Cuts;
|
||||||
|
edgeIntersections edge2Cuts;
|
||||||
|
intersectSurfaces
|
||||||
|
(
|
||||||
|
surf,
|
||||||
|
edge1Cuts,
|
||||||
|
cutSurf,
|
||||||
|
edge2Cuts
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Determine intersection edges
|
||||||
|
surfaceIntersection inter(surf, edge1Cuts, cutSurf, edge2Cuts);
|
||||||
|
|
||||||
|
|
||||||
|
// Use intersection edges to cut up faces. (does all the hard work)
|
||||||
|
intersectedSurface surf3(surf, true, inter);
|
||||||
|
|
||||||
|
|
||||||
|
// Mark triangles based on whether they are inside or outside
|
||||||
|
List<volumeType> volTypes;
|
||||||
|
cutter.getVolumeType(surf3.faceCentres(), volTypes);
|
||||||
|
|
||||||
|
label nInside = 0;
|
||||||
|
forAll(volTypes, i)
|
||||||
|
{
|
||||||
|
if (volTypes[i] == volumeType::INSIDE)
|
||||||
|
{
|
||||||
|
nInside++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a patch for inside the box
|
||||||
|
if (nInside > 0 && surf3.patches().size() > 0)
|
||||||
|
{
|
||||||
|
geometricSurfacePatchList newPatches(surf3.patches());
|
||||||
|
label sz = newPatches.size();
|
||||||
|
newPatches.setSize(sz+1);
|
||||||
|
newPatches[sz] = geometricSurfacePatch
|
||||||
|
(
|
||||||
|
newPatches[sz-1].geometricType(),
|
||||||
|
newPatches[sz-1].name() + "_inside",
|
||||||
|
newPatches[sz-1].index()
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< "Moving " << nInside << " out of " << surf3.size()
|
||||||
|
<< " triangles to region "
|
||||||
|
<< newPatches[sz].name() << endl;
|
||||||
|
|
||||||
|
|
||||||
|
List<labelledTri> newTris(surf3);
|
||||||
|
forAll(volTypes, i)
|
||||||
|
{
|
||||||
|
if (volTypes[i] == volumeType::INSIDE)
|
||||||
|
{
|
||||||
|
newTris[i].region() = sz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointField newPoints(surf3.points());
|
||||||
|
surf = triSurface(newTris.xfer(), newPatches, newPoints.xfer());
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,128 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::searchableSurfaceModifier::cut
|
||||||
|
|
||||||
|
Description
|
||||||
|
Patchify triangles based on orientation w.r.t other (triangulated or
|
||||||
|
triangulatable) surfaces
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
cut.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef cut_H
|
||||||
|
#define cut_H
|
||||||
|
|
||||||
|
#include "searchableSurfaceModifier.H"
|
||||||
|
#include "wordReList.H"
|
||||||
|
#include "faceList.H"
|
||||||
|
#include "pointField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
class edgeIntersections;
|
||||||
|
|
||||||
|
namespace searchableSurfaceModifiers
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class cut Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class cut
|
||||||
|
:
|
||||||
|
public searchableSurfaceModifier
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Name of surfaces to cut with
|
||||||
|
const wordReList cutterNames_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Triangulate faces around 0th vertex
|
||||||
|
void triangulate(const faceList&, pointField&, triSurface&) const;
|
||||||
|
|
||||||
|
//- Triangulate searchableSurface (currently only supported for
|
||||||
|
// searchableBox and triSurfaceMesh)
|
||||||
|
triSurface& triangulate(const searchableSurface&, triSurface&) const;
|
||||||
|
|
||||||
|
//- Intersect surfaces. Perturb to avoid degenerates.
|
||||||
|
bool intersectSurfaces
|
||||||
|
(
|
||||||
|
triSurface& surf1,
|
||||||
|
edgeIntersections& edgeCuts1,
|
||||||
|
triSurface& surf2,
|
||||||
|
edgeIntersections& edgeCuts2
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("cut");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary
|
||||||
|
cut(const searchableSurfaces&, const dictionary&);
|
||||||
|
|
||||||
|
//- Clone
|
||||||
|
autoPtr<searchableSurfaceModifier> clone() const
|
||||||
|
{
|
||||||
|
notImplemented("autoPtr<searchableSurfaceModifier> clone() const");
|
||||||
|
return autoPtr<searchableSurfaceModifier>(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~cut();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Apply this selector
|
||||||
|
virtual bool modify(const labelList& regions, searchableSurface&) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace searchableSurfaceModifiers
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "searchableSurfaceModifier.H"
|
||||||
|
#include "triSurface.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(searchableSurfaceModifier, 0);
|
||||||
|
defineRunTimeSelectionTable(searchableSurfaceModifier, dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableSurfaceModifier::searchableSurfaceModifier
|
||||||
|
(
|
||||||
|
const searchableSurfaces& geometry,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
geometry_(geometry),
|
||||||
|
dict_(dict)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::searchableSurfaceModifier::~searchableSurfaceModifier()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::searchableSurfaceModifier>
|
||||||
|
Foam::searchableSurfaceModifier::New
|
||||||
|
(
|
||||||
|
const word& type,
|
||||||
|
const searchableSurfaces& geometry,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
{
|
||||||
|
dictionaryConstructorTable::iterator cstrIter =
|
||||||
|
dictionaryConstructorTablePtr_->find(type);
|
||||||
|
|
||||||
|
if (cstrIter == dictionaryConstructorTablePtr_->end())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"searchableSurfaceModifier::New"
|
||||||
|
"(const word&, const searchableSurfaces&, const dictionary&)"
|
||||||
|
) << "Unknown searchableSurfaceModifier type "
|
||||||
|
<< type << nl << nl
|
||||||
|
<< "Valid searchableSurfaceModifier types : " << endl
|
||||||
|
<< dictionaryConstructorTablePtr_->sortedToc()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<searchableSurfaceModifier>(cstrIter()(geometry, dict));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::searchableSurfaceModifier
|
||||||
|
|
||||||
|
Description
|
||||||
|
Changing a surface
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
searchableSurfaceModifier.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef searchableSurfaceModifier_H
|
||||||
|
#define searchableSurfaceModifier_H
|
||||||
|
|
||||||
|
#include "dictionary.H"
|
||||||
|
#include "typeInfo.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
#include "autoPtr.H"
|
||||||
|
#include "labelList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of classes
|
||||||
|
class triSurface;
|
||||||
|
class searchableSurface;
|
||||||
|
class searchableSurfaces;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class searchableSurfaceModifier Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class searchableSurfaceModifier
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
const searchableSurfaces& geometry_;
|
||||||
|
|
||||||
|
//- Input dictionary
|
||||||
|
const dictionary dict_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("searchableSurfaceModifier");
|
||||||
|
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
searchableSurfaceModifier,
|
||||||
|
dictionary,
|
||||||
|
(
|
||||||
|
const searchableSurfaces& geometry,
|
||||||
|
const dictionary& dict
|
||||||
|
),
|
||||||
|
(geometry, dict)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary
|
||||||
|
searchableSurfaceModifier(const searchableSurfaces&, const dictionary&);
|
||||||
|
|
||||||
|
//- Clone
|
||||||
|
autoPtr<searchableSurfaceModifier> clone() const
|
||||||
|
{
|
||||||
|
notImplemented("autoPtr<searchableSurfaceModifier> clone() const");
|
||||||
|
return autoPtr<searchableSurfaceModifier>(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return a reference to the selected searchableSurfaceModifier
|
||||||
|
static autoPtr<searchableSurfaceModifier> New
|
||||||
|
(
|
||||||
|
const word& type,
|
||||||
|
const searchableSurfaces&,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~searchableSurfaceModifier();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Do any operation on surface. Return true if anything changed
|
||||||
|
virtual bool modify(const labelList&, searchableSurface&) const = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
169
applications/utilities/surface/surfacePatch/surfacePatch.C
Normal file
169
applications/utilities/surface/surfacePatch/surfacePatch.C
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Application
|
||||||
|
surfacePatch
|
||||||
|
|
||||||
|
Description
|
||||||
|
Patches (regionises) a surface using a user-selectable method.
|
||||||
|
|
||||||
|
The current methods are either based on a geometric feature angle
|
||||||
|
(a replacement for the surfaceAutoPatch functionality) or on intersecting
|
||||||
|
a set of searchableSurfaces - this will re-triangulate the intersecting
|
||||||
|
triangles and regonise the resulting triangles according to being
|
||||||
|
inside/outside the surface.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "triSurface.H"
|
||||||
|
#include "argList.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "triSurfaceMesh.H"
|
||||||
|
#include "searchableSurfaces.H"
|
||||||
|
#include "searchableSurfaceModifier.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
// Main program:
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
argList::validArgs.clear();
|
||||||
|
argList::noParallel();
|
||||||
|
#include "addDictOption.H"
|
||||||
|
|
||||||
|
#include "setRootCase.H"
|
||||||
|
#include "createTime.H"
|
||||||
|
|
||||||
|
const word dictName("surfacePatchDict");
|
||||||
|
#include "setSystemRunTimeDictionaryIO.H"
|
||||||
|
const IOdictionary meshDict(dictIO);
|
||||||
|
|
||||||
|
|
||||||
|
// Read geometry
|
||||||
|
// ~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
searchableSurfaces allGeometry
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"abc", // dummy name
|
||||||
|
runTime.constant(), // instance
|
||||||
|
triSurfaceMesh::meshSubDir, // local
|
||||||
|
runTime, // registry
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
meshDict.subDict("geometry"),
|
||||||
|
meshDict.lookupOrDefault("singleRegionName", true)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const dictionary& surfacesDict = meshDict.subDict("surfaces");
|
||||||
|
|
||||||
|
forAllConstIter(dictionary, surfacesDict, surfacesIter)
|
||||||
|
{
|
||||||
|
if (surfacesIter().isDict())
|
||||||
|
{
|
||||||
|
const word& surfName = surfacesIter().keyword();
|
||||||
|
const dictionary& surfDict = surfacesIter().dict();
|
||||||
|
|
||||||
|
// Look up surface
|
||||||
|
searchableSurface& surf = allGeometry[surfName];
|
||||||
|
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
// Check for modifier on global level
|
||||||
|
if (surfDict.found("type"))
|
||||||
|
{
|
||||||
|
autoPtr<searchableSurfaceModifier> modifier
|
||||||
|
(
|
||||||
|
searchableSurfaceModifier::New
|
||||||
|
(
|
||||||
|
surfDict.lookup("type"),
|
||||||
|
allGeometry,
|
||||||
|
surfDict
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (modifier().modify(identity(surf.regions().size()), surf))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for modifier on a per-region level
|
||||||
|
if (surfDict.found("regions"))
|
||||||
|
{
|
||||||
|
const dictionary& regionsDict = surfDict.subDict("regions");
|
||||||
|
forAllConstIter(dictionary, regionsDict, regionsIter)
|
||||||
|
{
|
||||||
|
const dictionary& regionDict = regionsIter().dict();
|
||||||
|
const keyType& regionName = regionsIter().keyword();
|
||||||
|
|
||||||
|
autoPtr<searchableSurfaceModifier> modifier
|
||||||
|
(
|
||||||
|
searchableSurfaceModifier::New
|
||||||
|
(
|
||||||
|
regionDict.lookup("type"),
|
||||||
|
allGeometry,
|
||||||
|
regionDict
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
labelList regionIDs =
|
||||||
|
findStrings(regionName, surf.regions());
|
||||||
|
if (modifier().modify(regionIDs, surf))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
const fileName name(surf.name());
|
||||||
|
surf.rename(name.lessExt() + "_patched." + name.ext());
|
||||||
|
|
||||||
|
Info<< "Writing repatched surface " << name << " to "
|
||||||
|
<< surf.name() << nl << endl;
|
||||||
|
|
||||||
|
surf.write();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "Surface " << surf.name() << " unchanged" << nl << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
69
applications/utilities/surface/surfacePatch/surfacePatchDict
Normal file
69
applications/utilities/surface/surfacePatch/surfacePatchDict
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: dev |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object createPatchDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
geometry
|
||||||
|
{
|
||||||
|
box
|
||||||
|
{
|
||||||
|
type searchableRotatedBox;
|
||||||
|
|
||||||
|
// box rotated 45 degrees around z axis
|
||||||
|
span (1 1 1);
|
||||||
|
origin (0 0 0);
|
||||||
|
e1 (1 1 0);
|
||||||
|
e3 (0 0 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
singleTri.obj
|
||||||
|
{
|
||||||
|
type triSurfaceMesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
unitCube_me.stl
|
||||||
|
{
|
||||||
|
type triSurfaceMesh;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
surfaces
|
||||||
|
{
|
||||||
|
unitCube_me.stl
|
||||||
|
{
|
||||||
|
regions
|
||||||
|
{
|
||||||
|
// Divide region 'maxZ' into multiple regions according to
|
||||||
|
// a geometric feature angle
|
||||||
|
maxZ
|
||||||
|
{
|
||||||
|
type autoPatch;
|
||||||
|
featureAngle 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
singleTri.obj
|
||||||
|
{
|
||||||
|
// Regionise surface according to triangles (after cutting) being
|
||||||
|
// inside or outside the 'box' geometry
|
||||||
|
type cut;
|
||||||
|
cutters (box);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -31,21 +31,17 @@ Description
|
|||||||
|
|
||||||
Note
|
Note
|
||||||
- best decomposition option is hierarchGeomDecomp since
|
- best decomposition option is hierarchGeomDecomp since
|
||||||
guarantees square decompositions.
|
guarantees square decompositions.
|
||||||
- triangles might be present on multiple processors.
|
- triangles might be present on multiple processors.
|
||||||
- merging uses geometric tolerance so take care with writing precision.
|
- merging uses geometric tolerance so take care with writing precision.
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "treeBoundBox.H"
|
|
||||||
#include "FixedList.H"
|
|
||||||
#include "argList.H"
|
#include "argList.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
#include "distributedTriSurfaceMesh.H"
|
#include "distributedTriSurfaceMesh.H"
|
||||||
#include "mapDistribute.H"
|
#include "mapDistribute.H"
|
||||||
#include "triSurfaceFields.H"
|
|
||||||
#include "Pair.H"
|
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -172,7 +168,7 @@ int main(int argc, char *argv[])
|
|||||||
"triSurface", // local
|
"triSurface", // local
|
||||||
runTime, // registry
|
runTime, // registry
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
);
|
);
|
||||||
|
|
||||||
const fileName actualPath(io.filePath());
|
const fileName actualPath(io.filePath());
|
||||||
@ -215,6 +211,7 @@ int main(int argc, char *argv[])
|
|||||||
Info<< "Writing dummy bounds dictionary to " << ioDict.name()
|
Info<< "Writing dummy bounds dictionary to " << ioDict.name()
|
||||||
<< nl << endl;
|
<< nl << endl;
|
||||||
|
|
||||||
|
// Force writing in ascii
|
||||||
ioDict.regIOobject::writeObject
|
ioDict.regIOobject::writeObject
|
||||||
(
|
(
|
||||||
IOstream::ASCII,
|
IOstream::ASCII,
|
||||||
@ -239,23 +236,18 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
surfMesh.searchableSurface::name(), // name
|
"faceCentres", // name
|
||||||
surfMesh.searchableSurface::instance(), // instance
|
surfMesh.searchableSurface::time().timeName(), // instance
|
||||||
surfMesh.searchableSurface::local(), // local
|
surfMesh.searchableSurface::local(), // local
|
||||||
surfMesh,
|
surfMesh,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
surfMesh,
|
surfMesh,
|
||||||
dimLength
|
dimLength,
|
||||||
|
s.faceCentres()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
triSurfaceVectorField& fc = fcPtr();
|
|
||||||
|
|
||||||
forAll(fc, triI)
|
|
||||||
{
|
|
||||||
fc[triI] = s[triI].centre(s.points());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Steal pointer and store object on surfMesh
|
// Steal pointer and store object on surfMesh
|
||||||
fcPtr.ptr()->store();
|
fcPtr.ptr()->store();
|
||||||
@ -290,7 +282,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
Info<< "Writing surface." << nl << endl;
|
Info<< "Writing surface." << nl << endl;
|
||||||
surfMesh.searchableSurface::write();
|
surfMesh.objectRegistry::write();
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -387,6 +387,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
surf2.write(outFileName);
|
surf2.write(outFileName);
|
||||||
|
|
||||||
|
Info<< "\nEnd\n" << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -286,7 +286,11 @@ void Foam::edgeMesh::scalePoints(const scalar scaleFactor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::edgeMesh::mergePoints(const scalar mergeDist)
|
void Foam::edgeMesh::mergePoints
|
||||||
|
(
|
||||||
|
const scalar mergeDist,
|
||||||
|
labelList& reversePointMap
|
||||||
|
)
|
||||||
{
|
{
|
||||||
pointField newPoints;
|
pointField newPoints;
|
||||||
labelList pointMap;
|
labelList pointMap;
|
||||||
@ -307,6 +311,9 @@ void Foam::edgeMesh::mergePoints(const scalar mergeDist)
|
|||||||
|
|
||||||
points_.transfer(newPoints);
|
points_.transfer(newPoints);
|
||||||
|
|
||||||
|
// connectivity changed
|
||||||
|
pointEdgesPtr_.clear();
|
||||||
|
|
||||||
// Renumber and make sure e[0] < e[1] (not really necessary)
|
// Renumber and make sure e[0] < e[1] (not really necessary)
|
||||||
forAll(edges_, edgeI)
|
forAll(edges_, edgeI)
|
||||||
{
|
{
|
||||||
@ -383,6 +390,9 @@ void Foam::edgeMesh::mergeEdges()
|
|||||||
{
|
{
|
||||||
edges_[iter()] = iter.key();
|
edges_[iter()] = iter.key();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// connectivity changed
|
||||||
|
pointEdgesPtr_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -247,11 +247,12 @@ public:
|
|||||||
//- Scale points. A non-positive factor is ignored
|
//- Scale points. A non-positive factor is ignored
|
||||||
virtual void scalePoints(const scalar);
|
virtual void scalePoints(const scalar);
|
||||||
|
|
||||||
//- Merge common points (points within mergeDist)
|
//- Merge common points (points within mergeDist). Return map from
|
||||||
void mergePoints(const scalar mergeDist);
|
// old to new points.
|
||||||
|
virtual void mergePoints(const scalar mergeDist, labelList&);
|
||||||
|
|
||||||
//- Merge similar edges
|
//- Merge duplicate edges
|
||||||
void mergeEdges();
|
virtual void mergeEdges();
|
||||||
|
|
||||||
|
|
||||||
// Write
|
// Write
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -68,7 +68,7 @@ namespace Foam
|
|||||||
{
|
{
|
||||||
|
|
||||||
class surfaceFeatures;
|
class surfaceFeatures;
|
||||||
class objectRegistry;
|
class searchableSurface;
|
||||||
|
|
||||||
// Forward declaration of friend functions and operators
|
// Forward declaration of friend functions and operators
|
||||||
class extendedEdgeMesh;
|
class extendedEdgeMesh;
|
||||||
@ -138,7 +138,7 @@ protected:
|
|||||||
static label externalStart_;
|
static label externalStart_;
|
||||||
|
|
||||||
|
|
||||||
// Private data
|
// Protected data
|
||||||
|
|
||||||
//- Index of the start of the concave feature points
|
//- Index of the start of the concave feature points
|
||||||
label concaveStart_;
|
label concaveStart_;
|
||||||
@ -200,12 +200,33 @@ protected:
|
|||||||
mutable PtrList<indexedOctree<treeDataEdge> > edgeTreesByType_;
|
mutable PtrList<indexedOctree<treeDataEdge> > edgeTreesByType_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
//- Classify the type of feature point. Requires valid stored member
|
//- Classify the type of feature point. Requires valid stored member
|
||||||
// data for edges and normals.
|
// data for edges and normals.
|
||||||
pointStatus classifyFeaturePoint(label ptI) const;
|
pointStatus classifyFeaturePoint(label ptI) const;
|
||||||
|
|
||||||
|
//- Cut edges with surface. Return map from cut points&edges back
|
||||||
|
// to original
|
||||||
|
void cut
|
||||||
|
(
|
||||||
|
const searchableSurface&,
|
||||||
|
labelList& pMap,
|
||||||
|
labelList& eMap,
|
||||||
|
labelList& pointsFromEdge, // new points created by cutting
|
||||||
|
labelList& oldEdge, // the orginal edge
|
||||||
|
labelList& surfTri // the surface triangle index
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Remove outside/inside edges. volType denotes which side to keep
|
||||||
|
void select
|
||||||
|
(
|
||||||
|
const searchableSurface& surf,
|
||||||
|
const volumeType volType,
|
||||||
|
labelList& pMap,
|
||||||
|
labelList& eMap
|
||||||
|
);
|
||||||
|
|
||||||
template<class Patch>
|
template<class Patch>
|
||||||
void sortPointsAndEdges
|
void sortPointsAndEdges
|
||||||
(
|
(
|
||||||
@ -262,9 +283,8 @@ public:
|
|||||||
const Xfer<edgeList>&
|
const Xfer<edgeList>&
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct given a surface with selected edges,point
|
//- Construct given a surface with selected edges,points
|
||||||
// (surfaceFeatures), an objectRegistry and a
|
// (surfaceFeatures)
|
||||||
// fileName to write to.
|
|
||||||
// Extracts, classifies and reorders the data from surfaceFeatures.
|
// Extracts, classifies and reorders the data from surfaceFeatures.
|
||||||
extendedEdgeMesh
|
extendedEdgeMesh
|
||||||
(
|
(
|
||||||
@ -501,6 +521,43 @@ public:
|
|||||||
// etc.
|
// etc.
|
||||||
void flipNormals();
|
void flipNormals();
|
||||||
|
|
||||||
|
//- Update with derived geometry
|
||||||
|
void autoMap
|
||||||
|
(
|
||||||
|
const pointField&,
|
||||||
|
const edgeList&,
|
||||||
|
const labelList& pointMap,
|
||||||
|
const labelList& edgeMap
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Trim to surface. Keep volType side. Return map from current back
|
||||||
|
// to original points (-1 for newly introduced points), edges
|
||||||
|
void trim
|
||||||
|
(
|
||||||
|
const searchableSurface& surf,
|
||||||
|
const volumeType volType,
|
||||||
|
labelList& pointMap,
|
||||||
|
labelList& edgeMap
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Order according to point and edge status
|
||||||
|
void setFromStatus
|
||||||
|
(
|
||||||
|
const List<extendedEdgeMesh::pointStatus>& pointStat,
|
||||||
|
const List<extendedEdgeMesh::edgeStatus>& edgeStat,
|
||||||
|
labelList& sortedToOriginalPoint,
|
||||||
|
labelList& sortedToOriginalEdge
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Geometric merge points. Returns true if any points merged.
|
||||||
|
// Return maps from new back to original points/edges.
|
||||||
|
bool mergePointsAndSort
|
||||||
|
(
|
||||||
|
const scalar mergeDist,
|
||||||
|
labelList& pointMap,
|
||||||
|
labelList& edgeMap
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Read
|
// Read
|
||||||
|
|
||||||
@ -532,6 +589,24 @@ public:
|
|||||||
const vector& fC0tofC1
|
const vector& fC0tofC1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Determine the ordering
|
||||||
|
static void sortedOrder
|
||||||
|
(
|
||||||
|
const List<extendedEdgeMesh::pointStatus>& pointStat,
|
||||||
|
const List<extendedEdgeMesh::edgeStatus>& edgeStat,
|
||||||
|
labelList& sortedToOriginalPoint,
|
||||||
|
labelList& sortedToOriginalEdge,
|
||||||
|
|
||||||
|
label& pointConcaveStart,
|
||||||
|
label& pointMixedStart,
|
||||||
|
label& pointNonFeatStart,
|
||||||
|
|
||||||
|
label& edgeInternalStart,
|
||||||
|
label& edgeFlatStart,
|
||||||
|
label& edgeOpenStart,
|
||||||
|
label& edgeMultipleStart
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Ostream Operator
|
// Ostream Operator
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user