Forward compatibility: flex
[foam-extend-3.2.git] / src / surfMesh / surfaceFormats / starcd / STARCDsurfaceFormat.C
blobc8685b1446f4410de5e01f65dc91737319ddfa7b
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "STARCDsurfaceFormat.H"
27 #include "ListOps.H"
29 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
31 template<class Face>
32 inline void Foam::fileFormats::STARCDsurfaceFormat<Face>::writeShell
34     Ostream& os,
35     const Face& f,
36     const label cellId,
37     const label cellTableId
40     os  << cellId                    // includes 1 offset
41         << ' ' << starcdShellShape_  // 3(shell) shape
42         << ' ' << f.size()
43         << ' ' << cellTableId
44         << ' ' << starcdShellType_;  // 4(shell)
46     // primitives have <= 8 vertices, but prevent overrun anyhow
47     // indent following lines for ease of reading
48     label count = 0;
49     forAll(f, fp)
50     {
51         if ((count % 8) == 0)
52         {
53             os  << nl << "  " << cellId;
54         }
55         os  << ' ' << f[fp] + 1;
56         count++;
57     }
58     os  << endl;
62 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
64 template<class Face>
65 Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat
67     const fileName& filename
70     read(filename);
74 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
76 template<class Face>
77 bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
79     const fileName& filename
82     const bool mustTriangulate = this->isTri();
83     this->clear();
85     fileName baseName = filename.lessExt();
87     // STAR-CD index of points
88     List<label> pointId;
90     // read points from .vrt file
91     readPoints
92     (
93         IFstream(baseName + ".vrt")(),
94         this->storedPoints(),
95         pointId
96     );
98     // Build inverse mapping (STAR-CD pointId -> index)
99     Map<label> mapPointId(2*pointId.size());
100     forAll(pointId, i)
101     {
102         mapPointId.insert(pointId[i], i);
103     }
104     pointId.clear();
106     //
107     // read .cel file
108     // ~~~~~~~~~~~~~~
109     IFstream is(baseName + ".cel");
110     if (!is.good())
111     {
112         FatalErrorIn
113         (
114             "fileFormats::STARCDsurfaceFormat::read(const fileName&)"
115         )
116             << "Cannot read file " << is.name()
117             << exit(FatalError);
118     }
120     readHeader(is, "PROSTAR_CELL");
122     DynamicList<Face>  dynFaces;
123     dynamicLabelList dynZones;
124     DynamicList<word>  dynNames;
125     dynamicLabelList dynSizes;
126     Map<label> lookup;
128     // assume the cellTableIds are not intermixed
129     bool sorted = true;
130     label zoneI = 0;
132     label lineLabel, shapeId, nLabels, cellTableId, typeId;
133     dynamicLabelList vertexLabels(64);
135     while ((is >> lineLabel).good())
136     {
137         is >> shapeId >> nLabels >> cellTableId >> typeId;
139         vertexLabels.clear();
140         vertexLabels.reserve(nLabels);
142         // read indices - max 8 per line
143         for (label i = 0; i < nLabels; ++i)
144         {
145             label vrtId;
146             if ((i % 8) == 0)
147             {
148                is >> lineLabel;
149             }
150             is >> vrtId;
152             // convert original vertex id to point label
153             vertexLabels.append(mapPointId[vrtId]);
154         }
156         if (typeId == starcdShellType_)
157         {
158             // Convert groupID into zoneID
159             Map<label>::const_iterator fnd = lookup.find(cellTableId);
160             if (fnd != lookup.end())
161             {
162                 if (zoneI != fnd())
163                 {
164                     // cellTableIds are intermixed
165                     sorted = false;
166                 }
167                 zoneI = fnd();
168             }
169             else
170             {
171                 zoneI = dynSizes.size();
172                 lookup.insert(cellTableId, zoneI);
173                 dynNames.append(word("cellTable_") + ::Foam::name(zoneI));
174                 dynSizes.append(0);
175             }
177             SubList<label> vertices(vertexLabels, vertexLabels.size());
178             if (mustTriangulate && nLabels > 3)
179             {
180                 face f(vertices);
182                 faceList triFaces(f.nTriangles());
183                 label nTri = 0;
184                 f.triangles(this->points(), nTri, triFaces);
186                 forAll(triFaces, faceI)
187                 {
188                     // a triangular face, but not yet a triFace
189                     dynFaces.append
190                     (
191                         triFace
192                         (
193                             static_cast<UList<label>&>(triFaces[faceI])
194                         )
195                     );
196                     dynZones.append(zoneI);
197                     dynSizes[zoneI]++;
198                 }
199             }
200             else
201             {
202                 dynFaces.append(Face(vertices));
203                 dynZones.append(zoneI);
204                 dynSizes[zoneI]++;
205             }
206         }
207     }
208     mapPointId.clear();
210     this->sortFacesAndStore(dynFaces.xfer(), dynZones.xfer(), sorted);
212     // add zones, culling empty ones
213     this->addZones(dynSizes, dynNames, true);
214     return true;
218 template<class Face>
219 void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
221     const fileName& filename,
222     const MeshedSurfaceProxy<Face>& surf
225     const pointField& pointLst = surf.points();
226     const List<Face>&  faceLst = surf.faces();
227     const List<label>& faceMap = surf.faceMap();
229     const List<surfZone>& zones =
230     (
231         surf.surfZones().size() > 1
232       ? surf.surfZones()
233       : STARCDsurfaceFormat::oneZone(faceLst)
234     );
236     const bool useFaceMap = (surf.useFaceMap() && zones.size() > 1);
239     fileName baseName = filename.lessExt();
241     writePoints(OFstream(baseName + ".vrt")(), pointLst);
242     OFstream os(baseName + ".cel");
243     writeHeader(os, "CELL");
245     label faceIndex = 0;
246     forAll(zones, zoneI)
247     {
248         const surfZone& zone = zones[zoneI];
250         if (useFaceMap)
251         {
252             forAll(zone, localFaceI)
253             {
254                 const Face& f = faceLst[faceMap[faceIndex++]];
255                 writeShell(os, f, faceIndex, zoneI + 1);
256             }
257         }
258         else
259         {
260             forAll(zone, localFaceI)
261             {
262                 const Face& f = faceLst[faceIndex++];
263                 writeShell(os, f, faceIndex, zoneI + 1);
264             }
265         }
266     }
268     // write simple .inp file
269     writeCase
270     (
271         OFstream(baseName + ".inp")(),
272         pointLst,
273         faceLst.size(),
274         zones
275     );
279 // ************************************************************************* //