diff --git a/applications/utilities/surface/README b/applications/utilities/surface/README index acc552cf1c..292d8ca0b5 100644 --- a/applications/utilities/surface/README +++ b/applications/utilities/surface/README @@ -1,40 +1,46 @@ -09/01/04 +2008-10-23 + Contents: surfaceAdd -adds to surface files. (but does not intersect or anything) +- adds to surface files. (but does not intersect or anything) surfaceBooleanOp -Boolean operations (add, or, xor) on closed surfaces. Probably not working. +- Boolean operations (add, or, xor) on closed surfaces. Probably not working. surfaceCheck -checks surface for incorrect topology. Checks normals of neighbouring faces. +- checks surface for incorrect topology. Checks normals of neighbouring faces. surfaceCoarsen -Stan Melax coarsening algorithm +- Stan Melax coarsening algorithm surfaceConvert -Converts surfaces to/from various formats +- Converts surfaces to/from various formats surfaceFind -Finds nearest vertex and face to given point. +- Finds nearest vertex and face to given point. surfaceMeshTriangulate -Triangulate external facses of mesh and write as surface. +- Triangulate external facses of mesh and write as surface. surfacePointMerge -Explicit point merge of surface. +- Explicit point merge of surface. surfaceSetOutside -Orient normals on (closed) surface. +- Orient normals on (closed) surface. surfaceSmooth -Laplacian smoothing on surface vertices +- Laplacian smoothing on surface vertices surfaceSubset -Subsets surface +- Subsets surface surfaceToPatch -Applies region information of surfaces to mesh. Each external face of mesh -gets region number of nearest surface triangle. +- Applies region information of surfaces to mesh. + Each external face of mesh gets region number of nearest surface triangle. + +------------------------------------------------------------------------------- + +surfaceMeshConvert +- Similar to surfaceConvert, but uses surfMesh library diff --git a/applications/utilities/surface/surfaceMeshConvert/Make/files b/applications/utilities/surface/surfaceMeshConvert/Make/files new file mode 100644 index 0000000000..1e0566c6aa --- /dev/null +++ b/applications/utilities/surface/surfaceMeshConvert/Make/files @@ -0,0 +1,3 @@ +surfaceMeshConvert.C + +EXE = $(FOAM_APPBIN)/surfaceMeshConvert diff --git a/applications/utilities/surface/surfaceMeshConvert/Make/options b/applications/utilities/surface/surfaceMeshConvert/Make/options new file mode 100644 index 0000000000..5293dabe4c --- /dev/null +++ b/applications/utilities/surface/surfaceMeshConvert/Make/options @@ -0,0 +1,5 @@ +EXE_INC = \ + -I$(LIB_SRC)/triSurface/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude + +EXE_LIBS = -lsurfMesh diff --git a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C new file mode 100644 index 0000000000..ad09dc328c --- /dev/null +++ b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C @@ -0,0 +1,145 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Application + surfaceMeshConvert + +Description + Converts from one surface mesh format to another + +Usage + - surfaceMeshConvert inputFile outputFile [OPTION] + + @param -clean \n + Perform some surface checking/cleanup on the input surface + + @param -scale \ \n + Specify a scaling factor for writing the files + + @param -triSurface \n + Use triSurface library for input/output + +Note + The filename extensions are used to determine the file format type. + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "timeSelector.H" +#include "Time.H" +#include "polyMesh.H" +#include "meshedSurface.H" +#include "triSurface.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + argList::noParallel(); + argList::validArgs.append("inputFile"); + argList::validArgs.append("outputFile"); + argList::validOptions.insert("scale", "scale"); + argList::validOptions.insert("clean", ""); + argList::validOptions.insert("triSurface", ""); +# include "setRootCase.H" + const stringList& params = args.additionalArgs(); + + scalar scaleFactor = 0; + if (args.options().found("scale")) + { + IStringStream(args.options()["scale"])() >> scaleFactor; + } + + fileName importName(params[0]); + fileName exportName(params[1]); + + if + ( + !meshedSurface::canRead(importName.ext(), true) + || !meshedSurface::canWrite(exportName.ext(), true) + ) + { + return 1; + } + + if (args.options().found("triSurface")) + { +// # include "createTime.H" +// instantList timeDirs = timeSelector::select0(runTime, args); +// # include "createPolyMesh.H" + + triSurface surf(importName); + + if (args.options().found("clean")) + { + surf.cleanup(true); + surf.checkOrientation(true); + } + + Info << "writing " << exportName; + if (scaleFactor <= 0) + { + Info<< " without scaling" << endl; + } + else + { + Info<< " triSurface does not yet support scaling " + << scaleFactor << endl; + // surf.scalePoints(scaleFactor); + } + surf.write(exportName); + } + else + { + meshedSurface surf(importName); + + if (args.options().found("clean")) + { + surf.cleanup(true); + surf.checkOrientation(true); + } + + surf.scalePoints(scaleFactor); + + Info<< "writing " << exportName; + if (scaleFactor <= 0) + { + Info<< " without scaling" << endl; + } + else + { + Info<< " with scaling " << scaleFactor << endl; + } + surf.write(exportName); + } + + Info<< "\nEnd\n" << endl; + + return 0; +} + +// ************************************************************************* // diff --git a/src/Allwmake b/src/Allwmake index 341ee2ed6f..76cc0b157c 100755 --- a/src/Allwmake +++ b/src/Allwmake @@ -13,6 +13,7 @@ wmake libso lagrangian/basic wmake libso triSurface wmake libso edgeMesh +wmake libso surfMesh wmake libso meshTools wmake libso finiteVolume diff --git a/src/OpenFOAM/containers/Keyed/Keyed.H b/src/OpenFOAM/containers/Keyed/Keyed.H index 2d0caa7b18..223ffe7bd6 100644 --- a/src/OpenFOAM/containers/Keyed/Keyed.H +++ b/src/OpenFOAM/containers/Keyed/Keyed.H @@ -39,6 +39,7 @@ SourceFiles #define Keyed_H #include "List.H" +#include "xfer.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -48,6 +49,7 @@ namespace Foam // Forward declaration of friend functions and operators template class Keyed; +template class xfer; template Istream& operator>>(Istream&, Keyed&); template Ostream& operator<<(Ostream&, const Keyed&); @@ -92,6 +94,9 @@ public: //- Construct as a copy of item, with a key inline Keyed(const T& item, const label key=0); + //- Construct by transferring the item, with a key + inline Keyed(const xfer& item, const label key=0); + //- Construct from Istream inline Keyed(Istream&); diff --git a/src/OpenFOAM/containers/Keyed/KeyedI.H b/src/OpenFOAM/containers/Keyed/KeyedI.H index ecae23da3d..61b7d9599f 100644 --- a/src/OpenFOAM/containers/Keyed/KeyedI.H +++ b/src/OpenFOAM/containers/Keyed/KeyedI.H @@ -30,7 +30,6 @@ License // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -//- Construct null template inline Foam::Keyed::Keyed() : @@ -38,7 +37,6 @@ inline Foam::Keyed::Keyed() {} -//- Construct from components template inline Foam::Keyed::Keyed(const T& item, const label key) : @@ -47,6 +45,14 @@ inline Foam::Keyed::Keyed(const T& item, const label key) {} +template +inline Foam::Keyed::Keyed(const xfer& item, const label key) +: + T(item), + key_(key) +{} + + template inline Foam::Keyed::Keyed(Istream& is) { diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files new file mode 100644 index 0000000000..2bf476cb72 --- /dev/null +++ b/src/surfMesh/Make/files @@ -0,0 +1,23 @@ +keyedSurface/keyedSurface.C +keyedSurface/keyedSurfaceCleanup.C +keyedSurface/newKeyedSurface.C + +meshedSurface/meshedSurface.C +meshedSurface/meshedSurfaceCleanup.C +meshedSurface/newMeshedSurface.C + +fileFormats = keyedSurface/fileFormats +$(fileFormats)/ac3d/AC3DfileFormat.C +$(fileFormats)/gts/GTSfileFormat.C +$(fileFormats)/nas/NASfileFormat.C +$(fileFormats)/obj/OBJfileFormat.C +$(fileFormats)/off/OFFfileFormat.C +$(fileFormats)/smesh/SMESHfileFormat.C +$(fileFormats)/starcd/STARCDfileFormat.C +$(fileFormats)/stl/STLfileFormat.C +$(fileFormats)/stl/STLfileFormatASCII.L +$(fileFormats)/tri/TRIfileFormat.C +$(fileFormats)/vtk/VTKfileFormat.C + +LIB = $(FOAM_LIBBIN)/libsurfMesh + diff --git a/src/surfMesh/Make/options b/src/surfMesh/Make/options new file mode 100644 index 0000000000..45765759c1 --- /dev/null +++ b/src/surfMesh/Make/options @@ -0,0 +1,5 @@ +EXE_INC = \ + -I$(LIB_SRC)/triSurface/lnInclude + +LIB_LIBS = \ + -ltriSurface diff --git a/src/surfMesh/keyedSurface/fileFormats/ac3d/AC3DfileFormat.C b/src/surfMesh/keyedSurface/fileFormats/ac3d/AC3DfileFormat.C new file mode 100644 index 0000000000..d92b2f91df --- /dev/null +++ b/src/surfMesh/keyedSurface/fileFormats/ac3d/AC3DfileFormat.C @@ -0,0 +1,588 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "AC3DfileFormat.H" +#include "clock.H" +#include "IFstream.H" +#include "IStringStream.H" +#include "tensor.H" +#include "primitivePatch.H" +#include "addToRunTimeSelectionTable.H" +#include "addToMemberFunctionSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // +namespace Foam +{ +namespace fileFormats +{ + +addNamedToRunTimeSelectionTable +( + keyedSurface, + AC3DfileFormat, + fileExtension, + ac +); + +addNamedToMemberFunctionSelectionTable +( + keyedSurface, + AC3DfileFormat, + write, + fileExtension, + ac +); + +addNamedToMemberFunctionSelectionTable +( + meshedSurface, + AC3DfileFormat, + write, + fileExtension, + ac +); + +} +} + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template +Type Foam::fileFormats::AC3DfileFormat::parse(const string& str) +{ + IStringStream ss(str); + + Type t; + ss >> t; + return t; +} + + +bool Foam::fileFormats::AC3DfileFormat::readCmd +( + IFstream& is, + string& cmd, + string& args +) +{ + if (is.good()) + { + string line; + is.getLine(line); + + string::size_type space = line.find(' '); + + if (space != string::npos) + { + cmd = line.substr(0, space); + args = line.substr(space+1); + + return true; + } + } + return false; +} + + +// Read up to line starting with cmd. Sets args to rest of line. +// Returns true if found, false if stream is not good anymore. +bool Foam::fileFormats::AC3DfileFormat::cueTo +( + IFstream& is, + const string& cmd, + string& args +) +{ + while (is.good()) + { + string line; + is.getLine(line); + + string::size_type space = line.find(' '); + + if (space != string::npos) + { + if (line.substr(0, space) == cmd) + { + args = line.substr(space+1); + + return true; + } + } + } + return false; +} + + +// Similar to cueTo(), but throws error if cmd not found +Foam::string Foam::fileFormats::AC3DfileFormat::cueToOrDie +( + IFstream& is, + const string& cmd, + const string& errorMsg +) +{ + string args; + if (!cueTo(is, cmd, args)) + { + FatalErrorIn + ( + "fileFormats::AC3DfileFormat::AC3DfileFormat" + "(const fileName&)" + ) + << "Cannot find command " << cmd + << " " << errorMsg + << exit(FatalError); + } + + return args; +} + + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::fileFormats::AC3DfileFormat::AC3DfileFormat() +: + Foam::keyedSurface() +{} + + +Foam::fileFormats::AC3DfileFormat::AC3DfileFormat +( + const fileName& fName, + const bool triangulate +) +: + Foam::keyedSurface() +{ + IFstream is(fName); + + if (!is.good()) + { + FatalErrorIn + ( + "fileFormats::AC3DfileFormat::AC3DfileFormat" + "(const fileName&)" + ) + << "Cannot read file " << fName + << exit(FatalError); + } + + string line, cmd, args; + + is.getLine(line); + + string version = line.substr(4); + + if (version != "b") + { + WarningIn + ( + "fileFormats::AC3DfileFormat::AC3DfileFormat" + "(const fileName&)" + ) + << "When reading AC3D file " << fName + << " read header " << line << " with version " + << version << endl + << "Only tested reading with version 'b'." + << " This might give problems" << endl; + } + + + if (!cueTo(is, "OBJECT", args) || (args != "world")) + { + FatalErrorIn + ( + "fileFormats::AC3DfileFormat::AC3DfileFormat" + "(const fileName&)" + ) + << "Cannot find \"OBJECT world\" in file " << fName + << exit(FatalError); + } + + // # of kids is the # of patches + args = cueToOrDie(is, "kids"); + label nPatches = parse(args); + + // Start of vertices for object/patch + label patchVertOffset = 0; + + DynamicList pointLst; + DynamicList faceLst; + + // patchId => patchName + Map regionNames; + + for (label patchI = 0; patchI < nPatches; ++patchI) + { + word patchName = word("patch") + Foam::name(patchI); + + args = cueToOrDie(is, "OBJECT", "while reading " + patchName); + + // number of vertices for this patch + label nPatchPoints = 0; + vector location(pTraits::zero); + // tensor rotation(I); + + // Read all info for current patch + while (is.good()) + { + // Read line and get first word. If end of file break since + // patch should always end with 'kids' command ?not sure. + if (!readCmd(is, cmd, args)) + { + FatalErrorIn + ( + "fileFormats::AC3DfileFormat::AC3DfileFormat" + "(const fileName&)" + ) + << "Did not read up to \"kids 0\" while reading patch " + << patchI << " from file " << fName + << exit(FatalError); + } + + if (cmd == "name") + { + // name %s + string str = parse(args); + string::stripInvalid(str); + + patchName = str; + } + else if (cmd == "rot") + { + // rot %f %f %f %f %f %f %f %f %f + + // IStringStream lineStream(args); + // + // lineStream + // >> rotation.xx() >> rotation.xy() >> rotation.xz() + // >> rotation.yx() >> rotation.yy() >> rotation.yz() + // >> rotation.zx() >> rotation.zy() >> rotation.zz(); + + WarningIn + ( + "fileFormats::AC3DfileFormat::AC3DfileFormat" + "(const fileName&)" + ) + << "rot (rotation tensor) command not implemented" + << "Line:" << cmd << ' ' << args << endl + << "while reading patch " << patchI << endl; + } + else if (cmd == "loc") + { + // loc %f %f %f + IStringStream lineStream(args); + + lineStream + >> location.x() + >> location.y() + >> location.z(); + } + else if (cmd == "numvert") + { + // numvert %d + nPatchPoints = parse(args); + + for (label vertI = 0; vertI < nPatchPoints; ++vertI) + { + is.getLine(line); + IStringStream lineStream(line); + + point pt; + lineStream + >> pt.x() >> pt.y() >> pt.z(); + + // Offset with current translation vector + pointLst.append(location + pt); + } + } + else if (cmd == "numsurf") + { + label nFaces = parse(args); + + for (label faceI = 0; faceI < nFaces; ++faceI) + { + static string errorMsg = + string(" while reading face ") + + Foam::name(faceI) + " on patch " + + Foam::name(patchI) + + " from file " + fName; + + cueToOrDie(is, "SURF", errorMsg); + cueToOrDie(is, "mat", errorMsg); + args = cueToOrDie(is, "refs", errorMsg); + + label nVert = parse(args); + + List