diff --git a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H index c013b733db95dab9f2f4d87a3b15bf878f7c170d..8cf6f1c38caf14daf82243682ec4b15f8ee0abe2 100644 --- a/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H +++ b/applications/solvers/heatTransfer/chtMultiRegionFoam/solid/setRegionSolidFields.H @@ -8,8 +8,8 @@ const volScalarField& cp = tcp(); tmp<volScalarField> tkappa = thermo.K(); - //tmp<volSymmTensorField> tkappa = thermo.directionalkappa(); const volScalarField& kappa = tkappa(); + //tmp<volSymmTensorField> tkappa = thermo.directionalK(); //const volSymmTensorField& kappa = tkappa(); volScalarField& T = thermo.T(); diff --git a/applications/utilities/mesh/generation/cvMesh/Allwmake b/applications/utilities/mesh/generation/cvMesh/Allwmake index 688b3be475c5d9b2a0edb096018b01042de929cc..f059754bab6f69f793ddfd156f50e914d3cf3d55 100755 --- a/applications/utilities/mesh/generation/cvMesh/Allwmake +++ b/applications/utilities/mesh/generation/cvMesh/Allwmake @@ -4,5 +4,6 @@ set -x wmake libso conformalVoronoiMesh wmake +wmake cvMeshSurfaceSimplify # ----------------------------------------------------------------- end-of-file diff --git a/applications/utilities/mesh/generation/cvMesh/checkCvMesh/Make/files b/applications/utilities/mesh/generation/cvMesh/checkCvMesh/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..73871a7532e1c273d0030d8c8bc4180e1ecef2a7 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/checkCvMesh/Make/files @@ -0,0 +1,3 @@ +checkCvMesh.C + +EXE = $(FOAM_APPBIN)/checkCvMesh diff --git a/applications/utilities/mesh/generation/cvMesh/checkCvMesh/Make/options b/applications/utilities/mesh/generation/cvMesh/checkCvMesh/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..ba68fd3819b53037f9711dfbb9691846a215f4d3 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/checkCvMesh/Make/options @@ -0,0 +1,14 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/triSurface/lnInclude \ + -I$(LIB_SRC)/mesh/autoMesh/lnInclude \ + -I$(LIB_SRC)/dynamicMesh/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -ldynamicMesh \ + -ltriSurface \ + -lautoMesh \ + -lmeshTools + diff --git a/applications/utilities/mesh/generation/cvMesh/checkCvMesh/checkCvMesh.C b/applications/utilities/mesh/generation/cvMesh/checkCvMesh/checkCvMesh.C new file mode 100644 index 0000000000000000000000000000000000000000..df2a3b90f81834625c22ab8fc3b490c4c0b73d99 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/checkCvMesh/checkCvMesh.C @@ -0,0 +1,122 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2011 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 + checkCvMesh + +Description + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "Time.H" +#include "fvMesh.H" +#include "autoSnapDriver.H" +#include "faceSet.H" +#include "motionSmoother.H" +#include "timeSelector.H" + + +using namespace Foam; + + +int main(int argc, char *argv[]) +{ +# include "addOverwriteOption.H" + +# include "setRootCase.H" +# include "createTime.H" + + instantList timeDirs = timeSelector::select0(runTime, args); + +# include "createMesh.H" + + runTime.functionObjects().off(); + + forAll(timeDirs, timeI) + { + runTime.setTime(timeDirs[timeI], timeI); + + Info<< "Create mesh for time = " << runTime.timeName() + << nl << endl; + + mesh.readUpdate(); + + Info<< "Read mesh in = " + << runTime.cpuTimeIncrement() << " s" << endl; + + // Check patches and faceZones are synchronised + mesh.boundaryMesh().checkParallelSync(true); + meshRefinement::checkCoupledFaceZones(mesh); + + // Read meshing dictionary + IOdictionary cvMeshDict + ( + IOobject + ( + "cvMeshDict", + runTime.system(), + mesh, + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE + ) + ); + + // mesh motion and mesh quality parameters + const dictionary& meshQualityDict + = cvMeshDict.subDict("meshQualityControls"); + + + Info<< "Checking initial mesh ..." << endl; + faceSet wrongFaces(mesh, "wrongFaces", mesh.nFaces()/100); + motionSmoother::checkMesh(false, mesh, meshQualityDict, wrongFaces); + + const label nInitErrors = returnReduce + ( + wrongFaces.size(), + sumOp<label>() + ); + + Info<< "Detected " << nInitErrors << " illegal faces" + << " (concave, zero area or negative cell pyramid volume)" + << endl; + + if (nInitErrors > 0) + { + Info<< "Writing " << nInitErrors + << " faces in error to set " + << wrongFaces.name() << endl; + + wrongFaces.instance() = mesh.pointsInstance(); + wrongFaces.write(); + } + + Info<< nl << "End of time " << runTime.timeName() << nl << endl; + } + + Info<< "End\n" << endl; + + return 0; + +} + diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C index edafdb50f912e02a89acc6133fc0d7cf7491cd5c..a2d44f0ee1ab506045eabdeac7ccb7300ad3d275 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.C @@ -724,6 +724,8 @@ void Foam::backgroundMeshDecomposition::buildPatchAndTree() globalBackgroundBounds_ = treeBoundBox(bbMin, bbMax); + octreeNearestDistances_ = bFTreePtr_().calcNearestDistance(); + if (cvMesh_.cvMeshControls().objOutput()) { OFstream fStr @@ -795,6 +797,7 @@ Foam::backgroundMeshDecomposition::backgroundMeshDecomposition ), boundaryFacesPtr_(), bFTreePtr_(), + octreeNearestDistances_(), allBackgroundMeshBounds_(Pstream::nProcs()), globalBackgroundBounds_(), decomposeDict_ @@ -1150,6 +1153,8 @@ bool Foam::backgroundMeshDecomposition::positionOnThisProcessor const point& pt ) const { +// return bFTreePtr_().findAnyOverlap(pt, 0.0); + return bFTreePtr_().getVolumeType(pt) == indexedOctree<treeDataBPatch>::INSIDE; @@ -1176,6 +1181,7 @@ bool Foam::backgroundMeshDecomposition::overlapsThisProcessor const treeBoundBox& box ) const { +// return !procBounds().contains(box); return !bFTreePtr_().findBox(box).empty(); } @@ -1183,9 +1189,11 @@ bool Foam::backgroundMeshDecomposition::overlapsThisProcessor bool Foam::backgroundMeshDecomposition::overlapsThisProcessor ( const point& centre, - scalar radiusSqr + const scalar radiusSqr ) const { + //return bFTreePtr_().findAnyOverlap(centre, radiusSqr); + return bFTreePtr_().findNearest(centre, radiusSqr).hit(); } @@ -1645,6 +1653,7 @@ Foam::labelListList Foam::backgroundMeshDecomposition::overlapsProcessors // If the sphere finds a nearest element of the patch, then it overlaps sphereOverlapsCandidate[sI] = bFTreePtr_().findNearest(c, rSqr).hit(); + //sphereOverlapsCandidate[sI] = bFTreePtr_().findAnyOverlap(c, rSqr); } map().reverseDistribute diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H index 87ab88af356873a7fc4f4512645ac46873806110..d8e6388cfb00e28d73c38928d9be482179689697 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H @@ -111,6 +111,8 @@ class backgroundMeshDecomposition //- Search tree for the boundaryFaces_ patch autoPtr<indexedOctree<treeDataBPatch> > bFTreePtr_; + List<scalar> octreeNearestDistances_; + //- The bounds of all background meshes on all processors treeBoundBoxList allBackgroundMeshBounds_; @@ -225,16 +227,16 @@ public: //- Are the given positions inside the domain of this decomposition boolList positionOnThisProcessor(const List<point>& pts) const; - //- Does the given box overlap the faces of the bounday of this + //- Does the given box overlap the faces of the boundary of this // processor bool overlapsThisProcessor(const treeBoundBox& box) const; - //- Does the given sphere overlap the faces of the bounday of this + //- Does the given sphere overlap the faces of the boundary of this // processor bool overlapsThisProcessor ( const point& centre, - scalar radiusSqr + const scalar radiusSqr ) const; //- Find nearest intersection of line between start and end, (exposing @@ -289,6 +291,12 @@ public: //- Return access to the underlying mesh inline const fvMesh& mesh() const; + //- Return access to the underlying tree + inline const indexedOctree<treeDataBPatch>& tree() const; + + //- Return access to the nearest distance of the octree nodes + inline const List<scalar>& octreeNearestDistances() const; + //- Return the boundBox of this processor inline const treeBoundBox& procBounds() const; }; diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H index df659cfd9cc0fed0f996b2bb97ff0b68622a1dcf..2897d3fc5830e133ba305b23436df6f829ccff99 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecompositionI.H @@ -30,6 +30,18 @@ const Foam::fvMesh& Foam::backgroundMeshDecomposition::mesh() const return mesh_; } +const Foam::indexedOctree<Foam::treeDataBPatch>& +Foam::backgroundMeshDecomposition::tree() const +{ + return bFTreePtr_(); +} + +const Foam::List<Foam::scalar>& +Foam::backgroundMeshDecomposition::octreeNearestDistances() const +{ + return octreeNearestDistances_; +} + const Foam::treeBoundBox& Foam::backgroundMeshDecomposition::procBounds() const { diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.H index 4b6c53bc2acb1eae64104a600358f67585e159dc..c813b9fe513e409e14f481ecee01caff978240a7 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfaces.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -122,6 +122,10 @@ public: //- Return the surface indices inline const labelList& surfaces() const; + //- In regions where no cell size function is specified + // use defaultCellSize + inline scalar defaultCellSize() const; + // Query //- Return the cell size at the given location diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfacesI.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfacesI.H index 57dca8cad40cef4dd365f368efa54b283473a490..973638d003ac681c43207ccd57557c848bff9736 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfacesI.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/cellSizeControlSurfaces/cellSizeControlSurfacesI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -37,4 +37,10 @@ const Foam::labelList& Foam::cellSizeControlSurfaces::surfaces() const } +Foam::scalar Foam::cellSizeControlSurfaces::defaultCellSize() const +{ + return defaultCellSize_; +} + + // ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C index e8cedc49c2cbd5e05256b513c4be1250f8140e4f..958fcf6763ec79332bf98faee94882df8eb0c640 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C @@ -240,9 +240,9 @@ void Foam::conformalVoronoiMesh::insertPoints { label preDistributionSize(points.size()); - DynamicList<Foam::point> transferPoints(points.size()/2); + DynamicList<Foam::point> transferPoints; - DynamicList<Point> pointsOnProcessor(points.size()/2); + DynamicList<Point> pointsOnProcessor; for ( @@ -277,12 +277,16 @@ void Foam::conformalVoronoiMesh::insertPoints decomposition_().distributePoints(transferPoints) ); + const label oldSize = points.size(); + + points.setSize(oldSize + transferPoints.size()); + forAll(transferPoints, tPI) { - points.append(toPoint(transferPoints[tPI])); + points[tPI + oldSize] = toPoint(transferPoints[tPI]); } - label sizeChange = preDistributionSize - label(points.size()); + label sizeChange = preDistributionSize - points.size(); // if (mag(sizeChange) > 0) // { @@ -417,7 +421,6 @@ void Foam::conformalVoronoiMesh::insertPoints // ); // } - rangeInsertWithInfo ( pts.begin(), @@ -1246,6 +1249,8 @@ Foam::conformalVoronoiMesh::conformalVoronoiMesh // better balance the surface conformation load. distributeBackground(); +// conformToSurface(); + buildSurfaceConformation(rmCoarse); // The introduction of the surface conformation may have distorted the @@ -1313,7 +1318,7 @@ void Foam::conformalVoronoiMesh::move() { cit->cellIndex() = dualVertI; - dualVertices[dualVertI] = topoint(dual(cit)); + dualVertices[dualVertI] = cit->dual(); dualVertI++; } @@ -1511,7 +1516,6 @@ void Foam::conformalVoronoiMesh::move() ( toPoint(0.5*(dVA + dVB)) ); - } } else if @@ -1671,9 +1675,57 @@ void Foam::conformalVoronoiMesh::move() insertPoints(pointsToInsert); + // Remove internal points that have been inserted outside the surface. + label internalPtIsOutside = 0; + + for + ( + Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (vit->internalPoint()) + { + bool inside + = geometryToConformTo_.inside(topoint(vit->point())); + + if (!inside) + { + remove(vit); + internalPtIsOutside++; + } + } + } + + Info<< " " << internalPtIsOutside + << " internal points were inserted outside the domain. " + << "They have been removed." << endl; + + // Fix points that have not been significantly displaced +// for +// ( +// Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); +// vit != finite_vertices_end(); +// ++vit +// ) +// { +// if (vit->internalPoint()) +// { +// if +// ( +// mag(displacementAccumulator[vit->index()]) +// < 0.1*targetCellSize(topoint(vit->point())) +// ) +// { +// vit->setVertexFixed(); +// } +// } +// } + if (cvMeshControls().objOutput() && runTime_.outputTime()) { - writePoints("points_" + runTime_.timeName() + ".obj", false); + writePoints("points_" + runTime_.timeName() + ".obj", true); } timeCheck("Internal points inserted"); diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H index b590eb31cd67383146216cfbdc4f211a38397137..a514c660a1d96350897478ca826dba7efe5af1d8 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H @@ -48,7 +48,6 @@ SourceFiles #define CGAL_INEXACT #include "CGALTriangulation3Ddefs.H" -#include <CGAL/Spatial_sort_traits_adapter_3.h> #include "uint.H" #include "ulong.H" #include "searchableSurfaces.H" @@ -595,6 +594,12 @@ private: Foam::point& b ) const; + label removeProcessorBoundarySeeds(bool reinsertBoundPts); + + void seedProcessorBoundarySurfaces(bool seedProcessors); + + label numberOfUnusedReferredPoints() const; + //- Build the parallelInterfaces of the mesh void buildParallelInterface ( @@ -1240,7 +1245,7 @@ public: Traits_for_spatial_sort<Triangulation>() ); - typename Triangulation::Cell_handle hint; + typename Triangulation::Vertex_handle hint; for ( @@ -1250,16 +1255,9 @@ public: ++p ) { - typename Triangulation::Locate_type lt; - typename Triangulation::Cell_handle c; - label li, lj; - - c = T.locate(*(p->first), lt, li, lj, hint); - const size_t checkInsertion = T.number_of_vertices(); - typename Triangulation::Vertex_handle v - = T.insert(*(p->first), lt, c, li, lj); + hint = T.insert(*(p->first), hint); if (checkInsertion != T.number_of_vertices() - 1) { @@ -1278,12 +1276,11 @@ public: // type directly (note that this routine never gets // called for referredPoints so type will never be // -procI - type += T.number_of_vertices() - 1; + type += checkInsertion; } - v->index() = indices[oldIndex] - + T.number_of_vertices() - 1; - v->type() = type; + hint->index() = indices[oldIndex] + checkInsertion; + hint->type() = type; } } } diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C index 04ef2af045d22226200bce8d1943ec4ed9438696..d103d3c0fcb1ff968452105319a3c304e5a65578 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C @@ -1890,7 +1890,7 @@ void Foam::conformalVoronoiMesh::indexDualVertices { cit->cellIndex() = dualVertI; - pts[dualVertI] = topoint(dual(cit)); + pts[dualVertI] = cit->dual(); if ( diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C index 847974a2f4ed3c01bdc652fe52baafafcb8bc96c..7f4c7abb6ef2cd34a4513fda2e94a41cf5af0d9b 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C @@ -41,6 +41,11 @@ void Foam::conformalVoronoiMesh::conformToSurface() { reconformationMode reconfMode = reconformationControl(); + if (Pstream::parRun()) + { + seedProcessorBoundarySurfaces(true); + } + if (reconfMode == rmNone) { // Reinsert stored surface conformation @@ -69,6 +74,16 @@ void Foam::conformalVoronoiMesh::conformToSurface() storeSurfaceConformation(); } + if (Pstream::parRun()) + { + label nFarPoints = removeProcessorBoundarySeeds(true); + + reduce(nFarPoints, sumOp<label>()); + + Info<< " Removed " << nFarPoints + << " far points from the mesh." << endl; + } + // reportSurfaceConformationQuality(); } @@ -140,13 +155,8 @@ void Foam::conformalVoronoiMesh::buildSurfaceConformation buildEdgeLocationTree(existingEdgeLocations); buildSurfacePtLocationTree(existingSurfacePtLocations); - - // Initialise the edgeLocationTree - //buildEdgeLocationTree(edgeLocationTree, existingEdgeLocations); - label initialTotalHits = 0; - // Surface protrusion conformation is done in two steps. // 1. the dual edges (of all internal vertices) can stretch to // 'infinity' so any intersection would be badly behaved. So @@ -382,7 +392,7 @@ void Foam::conformalVoronoiMesh::buildSurfaceConformation ( Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); - vit++ + ++vit ) { // The initial surface conformation has already identified the @@ -511,14 +521,18 @@ void Foam::conformalVoronoiMesh::buildSurfaceConformation timeCheck("Conformation iteration " + name(iterationNo)); - // Update the parallel interface - buildParallelInterface - ( - referralVertices, - receivedVertices, - false, - name(iterationNo) - ); + // Only need to update the interface if there are surface/edge hits + if (totalHits > 0) + { + // Update the parallel interface + buildParallelInterface + ( + referralVertices, + receivedVertices, + false, + name(iterationNo) + ); + } iterationNo++; @@ -563,8 +577,8 @@ bool Foam::conformalVoronoiMesh::dualCellSurfaceAnyIntersection continue; } - Foam::point dE0 = topoint(dual(fit->first)); - Foam::point dE1 = topoint(dual(fit->first->neighbor(fit->second))); + Foam::point dE0 = fit->first->dual(); + Foam::point dE1 = fit->first->neighbor(fit->second)->dual(); if (Pstream::parRun()) { @@ -631,8 +645,8 @@ bool Foam::conformalVoronoiMesh::dualCellSurfaceAllIntersections // Construct the dual edge and search for intersections of the edge // with the surface - Foam::point dE0 = topoint(dual(fit->first)); - Foam::point dE1 = topoint(dual(fit->first->neighbor(fit->second))); + Foam::point dE0 = fit->first->dual(); + Foam::point dE1 = fit->first->neighbor(fit->second)->dual(); pointIndexHit infoIntersection; label hitSurfaceIntersection = -1; @@ -801,6 +815,144 @@ void Foam::conformalVoronoiMesh::buildParallelInterface } +Foam::label Foam::conformalVoronoiMesh::removeProcessorBoundarySeeds +( + bool reinsertBoundPts +) +{ + label nFarPoints = 0; + + + + std::list<Vertex_handle> toRemove; + + for + ( + Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (vit->farPoint()) + { + //remove(vit); + toRemove.push_back(vit); + nFarPoints++; + } + } + + // This function removes the points in the iterator range and then + // retriangulates. + timeCheck("Start Removing Seeded Points " + name(toRemove.size())); + + remove_cluster(toRemove.begin(), toRemove.end()); + + + // Need to do this to make sure the triangulation is well-behaved + if (reinsertBoundPts) + { + reinsertBoundingPoints(); + } + + + +// DynamicList<Foam::point> toAdd; +// DynamicList<label> indices; +// DynamicList<label> types; +// +// for +// ( +// Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); +// vit != finite_vertices_end(); +// ++vit +// ) +// { +// if (!vit->farPoint()) +// { +// toAdd.append(topoint(vit->point())); +// indices.append(vit->index()); +// types.append(vit->type()); +// +// nFarPoints++; +// } +// } +// +// this->clear(); +// +// // Need to do this to make sure the triangulation is well-behaved +// if (reinsertBoundPts) +// { +// reinsertBoundingPoints(); +// } +// +// forAll(toAdd, pI) +// { +// insertPoint(toAdd[pI], indices[pI], types[pI]); +// } + + + timeCheck("End Removing Seeded Points"); + + return nFarPoints; +} + + +void Foam::conformalVoronoiMesh::seedProcessorBoundarySurfaces +( + bool seedProcessors +) +{ + //removeProcessorBoundarySeeds(false); + + // Loop over processor patch faces and insert a point in the centre of the + // face + const fvMesh& mesh = decomposition_().mesh(); + const polyBoundaryMesh& bMesh = mesh.boundaryMesh(); + + DynamicList<Foam::point> pts; + DynamicList<label> indices; + DynamicList<label> types; + + label nFarPoints = 0; + + const scalar normalDistance = 5.0; + const scalar pert = 0.1*(rndGen_.scalar01() - 0.5); + + forAll(bMesh, patchI) + { + const polyPatch& patch = bMesh[patchI]; + + if (!seedProcessors && isA<processorPolyPatch>(patch)) + { + continue; + } + + forAll(patch, faceI) + { + if (faceI % 1 == 0) + { + const face& f = patch[faceI]; + + pts.append + ( + f.centre(mesh.points()) + + pert*normalDistance*f.normal(mesh.points()) + ); + indices.append(nFarPoints++); + types.append(Vb::vtFar); + } + } + } + + insertPoints(pts, indices, types, false); + + reduce(nFarPoints, sumOp<label>()); + + Info<< " Inserted " << nFarPoints + << " far points into the mesh." << endl; +} + + void Foam::conformalVoronoiMesh::buildParallelInterface ( List<labelHashSet>& referralVertices, @@ -835,22 +987,88 @@ void Foam::conformalVoronoiMesh::buildParallelInterface timeCheck("After buildParallelInterfaceAll"); } - if (initialEdgeReferral) - { - // Used as an initial pass to localise the vertex referring - find - // vertices whose dual edges pierce nearby processor volumes and refer - // them to establish a sensible boundary interface region before - // running a circumsphere assessment. - buildParallelInterfaceIntersection - ( - referralVertices, - receivedVertices, - outputName - ); + // Reject points that are not near the boundary from the subsequent + // searches - timeCheck("After buildParallelInterfaceIntersection"); - } +// label nearProcCount = 0; +// label notNearProcCount = 0; +// boundBox quickRejectionBox(decomposition_().procBounds()); +// +//// Pout<< "Processor boundBox: " << quickRejectionBox << endl; +// +// quickRejectionBox.inflate(-0.1); +// +// OFstream str("rejectionBox_" + name(Pstream::myProcNo()) + ".obj"); +// +// meshTools::writeOBJ +// ( +// str, +// boundBox::faces(), +// quickRejectionBox.points() +// ); +// +// Pout<< "Inflated rejection boundBox: " << quickRejectionBox << endl; + +// for +// ( +// Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); +// vit != finite_vertices_end(); +// vit++ +// ) +// { +// if (vit->real() && !vit->nearProcBoundary()) +// { +// const Foam::point& pt = topoint(vit->point()); +// const scalar range = targetCellSize(pt); +// +//// if +//// ( +//// decomposition_().overlapsThisProcessor +//// ( +//// pt, +//// range +//// ) +//// ) +// if (!quickRejectionBox.contains(pt)) +// { +// vit->setNearProcBoundary(); +// nearProcCount++; +// } +// else +// { +// //vit->setNearProcBoundary(); +// notNearProcCount++; +// } +// } +// } +// +// reduce(nearProcCount, sumOp<label>()); +// reduce(notNearProcCount, sumOp<label>()); +// +// timeCheck +// ( +// "End of potential intersection search. " +// + name(nearProcCount) + " are near a processor boundary. " +// + name(notNearProcCount) + " are not." +// ); + +// if (initialEdgeReferral) +// { +// // Used as an initial pass to localise the vertex referring - find +// // vertices whose dual edges pierce nearby processor volumes and refer +// // them to establish a sensible boundary interface region before +// // running a circumsphere assessment. +// +// buildParallelInterfaceIntersection +// ( +// referralVertices, +// receivedVertices, +// outputName +// ); +// +// timeCheck("After buildParallelInterfaceIntersection"); +// } buildParallelInterfaceInfluence ( @@ -860,6 +1078,56 @@ void Foam::conformalVoronoiMesh::buildParallelInterface ); timeCheck("After buildParallelInterface"); + + // Check all referred vertices are actually used on the processor. + label nUnusedReferred = numberOfUnusedReferredPoints(); + + reduce(nUnusedReferred, sumOp<label>()); + + Info<< " Number of referred points that are not used : " + << nUnusedReferred << " (approximate)" << endl; +} + + +Foam::label Foam::conformalVoronoiMesh::numberOfUnusedReferredPoints() const +{ + label nUnusedPoints = 0; + + for + ( + Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); + vit != finite_vertices_end(); + ++vit + ) + { + if (vit->referred()) + { + std::list<Vertex_handle> adjVertices; + finite_adjacent_vertices(vit, std::back_inserter(adjVertices)); + + bool isUsed = false; + + for + ( + std::list<Vertex_handle>::iterator adjVit = adjVertices.begin(); + adjVit != adjVertices.end(); + ++adjVit + ) + { + if ((*adjVit)->real()) + { + isUsed = true; + } + } + + if (!isUsed) + { + nUnusedPoints++; + } + } + } + + return nUnusedPoints; } @@ -880,7 +1148,7 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceAll ( Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); - vit++ + ++vit ) { if (!vit->farPoint()) @@ -966,7 +1234,10 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceIntersection // If either Delaunay cell at the end of the Dual edge is infinite, // skip. - if (!is_infinite(c1) && !is_infinite(c2)) + if + ( + !is_infinite(c1) && !is_infinite(c2) + ) { // The Delaunauy cells at either end of the dual edge need to be // real, i.e. all vertices form part of the internal or boundary @@ -977,12 +1248,14 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceIntersection && c2->internalOrBoundaryDualVertex() ) { - Foam::point a = topoint(dual(c1)); - Foam::point b = topoint(dual(c2)); + const Foam::point& a = c1->dual(); + const Foam::point& b = c2->dual(); // Only if the dual edge cuts the boundary of this processor is // it going to be counted. - if (decomposition_().findLineAny(a, b).hit()) + pointIndexHit info = decomposition_().findLineAny(a, b); + + if (info.hit()) { dE0.append(a); dE1.append(b); @@ -995,11 +1268,22 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceIntersection fIOuter++; } + reduce(fIOuter, sumOp<label>()); + + timeCheck + ( + "End of actual intersection search over " + + name(fIOuter) + + " faces." + ); + // Preform intersections in both directions, as there is no sense // associated with the Dual edge List<List<pointIndexHit> > intersectionForward(intersectsProc(dE0, dE1)); List<List<pointIndexHit> > intersectionReverse(intersectsProc(dE1, dE0)); + timeCheck("End of find processor intersection"); + // Reset counter fIOuter = 0; @@ -1175,13 +1459,58 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceInfluence DynamicList<Foam::point> circumcentre; DynamicList<scalar> circumradiusSqr; - PackedBoolList testCellInfluence(number_of_cells(), false); // Index outer (all) Delaunauy cells for whether they are potential // overlaps, index (inner) the list of tests an results. label cIInner = 0; label cIOuter = 0; + + label cellIndexCount = 0; + for + ( + Delaunay::Finite_cells_iterator cit = finite_cells_begin(); + cit != finite_cells_end(); + ++cit + ) + { + cit->cellIndex() = cellIndexCount++; + } + + timeCheck("End of cell Indexing"); + + labelList testCellInfluence(number_of_cells(), 0); + + label nQuickRejections = 0; + + for + ( + Delaunay::Finite_cells_iterator cit = finite_cells_begin(); + cit != finite_cells_end(); + ++cit + ) + { + const Foam::point& cc = cit->dual(); + + const scalar crSqr = magSqr(cc - topoint(cit->vertex(0)->point())); + + if + ( + decomposition_().tree().quickCircumsphereRejection + ( + cc, + crSqr, + decomposition_().octreeNearestDistances() + ) + ) + { + nQuickRejections++; + testCellInfluence[cit->cellIndex()] = -1; + } + } + + timeCheck("End of octreeNearestDistances calculation"); + for ( Delaunay::Finite_cells_iterator cit = finite_cells_begin(); @@ -1196,14 +1525,15 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceInfluence // The Delaunay cells to assess have to be real, i.e. all vertices form // part of the internal or any part of the boundary definition - if (cit->real()) + if + ( + (testCellInfluence[cit->cellIndex()] == 0) + && (cit->real() || cit->hasFarPoint()) + ) { - Foam::point cc(topoint(dual(cit))); + const Foam::point& cc = cit->dual(); - scalar crSqr - ( - magSqr(cc - topoint(cit->vertex(0)->point())) - ); + const scalar crSqr = magSqr(cc - topoint(cit->vertex(0)->point())); // Only if the circumsphere overlaps the boundary of this processor // is there a chance of it overlapping others @@ -1212,7 +1542,7 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceInfluence circumcentre.append(cc); circumradiusSqr.append(crSqr); - testCellInfluence[cIOuter] = true; + testCellInfluence[cit->cellIndex()] = 1; } } @@ -1221,6 +1551,9 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceInfluence timeCheck("End of testing cell influence"); + Pout<< "Number of quick rejections = " << nQuickRejections << endl; + Pout<< "Number of influences = " << circumcentre.size() << endl; + // Increasing the circumspheres to increase the overlaps and compensate for // floating point errors missing some referrals labelListList circumsphereOverlaps @@ -1242,7 +1575,7 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceInfluence ) { // Pre-tested circumsphere potential influence - if (testCellInfluence[cIOuter]) + if (testCellInfluence[cit->cellIndex()] == 1) { const labelList& citOverlaps = circumsphereOverlaps[cIInner]; @@ -1289,6 +1622,70 @@ void Foam::conformalVoronoiMesh::buildParallelInterfaceInfluence cIOuter++; } + +// label nFarPoints = removeProcessorBoundarySeeds(true); +// +// reduce(nFarPoints, sumOp<label>()); +// +// Info<< " Removed " << nFarPoints +// << " far points from the mesh." << endl; + + +// seedProcessorBoundarySurfaces(false); + +// cIInner = 0; +// cIOuter = 0; + + + // Relying on the order of iteration of cells being the same as before +// for +// ( +// Delaunay::Finite_cells_iterator cit = finite_cells_begin(); +// cit != finite_cells_end(); +// ++cit +// ) +// { +// // Pre-tested circumsphere potential influence +// if (testCellInfluence[cIOuter]) +// { +// const labelList& citOverlaps = circumsphereOverlaps[cIInner]; +// +// forAll(citOverlaps, cOI) +// { +// label procI = citOverlaps[cOI]; +// +// recursiveCircumsphereSearch +// ( +// cit, +// procI, +// referralVertices, +// checkedCells, +// parallelInfluencePoints, +// parallelInfluenceIndices, +// targetProcessor +// ); +// } +// +// cIInner++; +// } +// +// cIOuter++; +// } + +// for +// ( +// Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); +// vit != finite_vertices_end(); +// ++vit +// ) +// { +// if (vit->referred()) +// { +// //Pout << "REMOVE: " << topoint(vit->point()) << endl; +// remove(vit); +// } +// } + referVertices ( targetProcessor, @@ -1344,6 +1741,8 @@ void Foam::conformalVoronoiMesh::referVertices ); } + timeCheck("Start of referVertices " + stageName + " insertion."); + for (label procI = 0; procI < Pstream::nProcs(); procI++) { const labelList& constructMap = pointMap.constructMap()[procI]; @@ -1397,7 +1796,7 @@ void Foam::conformalVoronoiMesh::dualCellLargestSurfaceProtrusion hitSurfaceLargest = -1; std::list<Facet> facets; - incident_facets(vit, std::back_inserter(facets)); + finite_incident_facets(vit, std::back_inserter(facets)); const Foam::point vert = topoint(vit->point()); @@ -1410,52 +1809,45 @@ void Foam::conformalVoronoiMesh::dualCellLargestSurfaceProtrusion ++fit ) { - if + const Foam::point edgeMid = + 0.5 + *( + fit->first->dual() + + fit->first->neighbor(fit->second)->dual() + ); + + pointIndexHit surfHit; + label hitSurface; + + geometryToConformTo_.findSurfaceAnyIntersection ( - !is_infinite(fit->first) - && !is_infinite(fit->first->neighbor(fit->second)) - ) - { - const Foam::point edgeMid = - 0.5 - *( - topoint(dual(fit->first)) - + topoint(dual(fit->first->neighbor(fit->second))) - ); + vert, + edgeMid, + surfHit, + hitSurface + ); - pointIndexHit surfHit; - label hitSurface; + if (surfHit.hit()) + { + vectorField norm(1); - geometryToConformTo_.findSurfaceAnyIntersection + allGeometry_[hitSurface].getNormal ( - vert, - edgeMid, - surfHit, - hitSurface + List<pointIndexHit>(1, surfHit), + norm ); - if (surfHit.hit()) - { - vectorField norm(1); - - allGeometry_[hitSurface].getNormal - ( - List<pointIndexHit>(1, surfHit), - norm - ); - - const vector& n = norm[0]; + const vector& n = norm[0]; - const scalar normalProtrusionDistance = - (edgeMid - surfHit.hitPoint()) & n; + const scalar normalProtrusionDistance = + (edgeMid - surfHit.hitPoint()) & n; - if (normalProtrusionDistance > maxProtrusionDistance) - { - surfHitLargest = surfHit; - hitSurfaceLargest = hitSurface; + if (normalProtrusionDistance > maxProtrusionDistance) + { + surfHitLargest = surfHit; + hitSurfaceLargest = hitSurface; - maxProtrusionDistance = normalProtrusionDistance; - } + maxProtrusionDistance = normalProtrusionDistance; } } } @@ -1489,9 +1881,9 @@ void Foam::conformalVoronoiMesh::dualCellLargestSurfaceIncursion hitSurfaceLargest = -1; std::list<Facet> facets; - incident_facets(vit, std::back_inserter(facets)); + finite_incident_facets(vit, std::back_inserter(facets)); - Foam::point vert(topoint(vit->point())); + const Foam::point vert = topoint(vit->point()); scalar minIncursionDistance = -maxSurfaceProtrusion(vert); @@ -1502,57 +1894,50 @@ void Foam::conformalVoronoiMesh::dualCellLargestSurfaceIncursion ++fit ) { - if + const Foam::point edgeMid = + 0.5 + *( + fit->first->dual() + + fit->first->neighbor(fit->second)->dual() + ); + + pointIndexHit surfHit; + label hitSurface; + + geometryToConformTo_.findSurfaceAnyIntersection ( - !is_infinite(fit->first) - && !is_infinite(fit->first->neighbor(fit->second)) - ) - { - Foam::point edgeMid = - 0.5 - *( - topoint(dual(fit->first)) - + topoint(dual(fit->first->neighbor(fit->second))) - ); + vert, + edgeMid, + surfHit, + hitSurface + ); - pointIndexHit surfHit; - label hitSurface; + if (surfHit.hit()) + { + vectorField norm(1); - geometryToConformTo_.findSurfaceAnyIntersection + allGeometry_[hitSurface].getNormal ( - vert, - edgeMid, - surfHit, - hitSurface + List<pointIndexHit>(1, surfHit), + norm ); - if (surfHit.hit()) - { - vectorField norm(1); - - allGeometry_[hitSurface].getNormal - ( - List<pointIndexHit>(1, surfHit), - norm - ); - - const vector& n = norm[0]; + const vector& n = norm[0]; - scalar normalIncursionDistance = - (edgeMid - surfHit.hitPoint()) & n; + scalar normalIncursionDistance = + (edgeMid - surfHit.hitPoint()) & n; - if (normalIncursionDistance < minIncursionDistance) - { - surfHitLargest = surfHit; - hitSurfaceLargest = hitSurface; + if (normalIncursionDistance < minIncursionDistance) + { + surfHitLargest = surfHit; + hitSurfaceLargest = hitSurface; - minIncursionDistance = normalIncursionDistance; + minIncursionDistance = normalIncursionDistance; - // Info<< nl << "# Incursion: " << endl; - // meshTools::writeOBJ(Info, vert); - // meshTools::writeOBJ(Info, edgeMid); - // Info<< "l Na Nb" << endl; - } + // Info<< nl << "# Incursion: " << endl; + // meshTools::writeOBJ(Info, vert); + // meshTools::writeOBJ(Info, edgeMid); + // Info<< "l Na Nb" << endl; } } } @@ -1948,6 +2333,35 @@ bool Foam::conformalVoronoiMesh::appendToEdgeLocationTree } +Foam::List<Foam::pointIndexHit> +Foam::conformalVoronoiMesh::nearestFeatureEdgeLocations +( + const Foam::point& pt +) const +{ + const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt); + + labelList elems + = edgeLocationTreePtr_().findSphere(pt, exclusionRangeSqr); + + DynamicList<pointIndexHit> dynPointHit; + + forAll(elems, elemI) + { + label index = elems[elemI]; + + const Foam::point& pointI + = edgeLocationTreePtr_().shapes().shapePoints()[index]; + + pointIndexHit nearHit(true, pointI, index); + + dynPointHit.append(nearHit); + } + + return dynPointHit; +} + + bool Foam::conformalVoronoiMesh::pointIsNearFeatureEdgeLocation ( const Foam::point& pt @@ -2009,103 +2423,77 @@ bool Foam::conformalVoronoiMesh::nearFeatureEdgeLocation DynamicList<Foam::point>& existingEdgeLocations ) const { - const Foam::point pt = pHit.hitPoint(); + Foam::point pt = pHit.hitPoint(); const scalar exclusionRangeSqr = featureEdgeExclusionDistanceSqr(pt); - pointIndexHit info; - - bool closeToFeatureEdge = pointIsNearFeatureEdgeLocation(pt, info); + bool closeToFeatureEdge = pointIsNearFeatureEdgeLocation(pt); - if (!closeToFeatureEdge) - { - appendToEdgeLocationTree(pt, existingEdgeLocations); - } - else + if (closeToFeatureEdge) { - // Check if the edge location that the new edge location is near to - // "might" be on a different edge. If so, add it anyway. - pointIndexHit edgeHit; - label featureHit = -1; + List<pointIndexHit> nearHits = nearestFeatureEdgeLocations(pt); - geometryToConformTo_.findEdgeNearest - ( - pt, - exclusionRangeSqr, - edgeHit, - featureHit - ); + forAll(nearHits, elemI) + { + pointIndexHit& info = nearHits[elemI]; - const extendedFeatureEdgeMesh& eMesh - = geometryToConformTo_.features()[featureHit]; + // Check if the edge location that the new edge location is near to + // "might" be on a different edge. If so, add it anyway. + pointIndexHit edgeHit; + label featureHit = -1; - const vector& edgeDir = eMesh.edgeDirections()[edgeHit.index()]; + geometryToConformTo_.findEdgeNearest + ( + pt, + exclusionRangeSqr, + edgeHit, + featureHit + ); - const vector lineBetweenPoints = pt - info.hitPoint(); + const extendedFeatureEdgeMesh& eMesh + = geometryToConformTo_.features()[featureHit]; - const scalar cosAngle = vectorTools::cosPhi(edgeDir, lineBetweenPoints); + const vector& edgeDir = eMesh.edgeDirections()[edgeHit.index()]; - // Allow the point to be added if it is almost at right angles to the - // other point. Also check it is not the same point. -// Info<< cosAngle<< " " -// << radToDeg(acos(cosAngle)) << " " -// << searchConeAngle << " " -// << radToDeg(acos(searchConeAngle)) << endl; - if - ( - mag(cosAngle) < searchConeAngle - && mag(lineBetweenPoints) > SMALL - ) - { - closeToFeatureEdge = false; - appendToEdgeLocationTree(pt, existingEdgeLocations); - } - } + const vector lineBetweenPoints = pt - info.hitPoint(); - return closeToFeatureEdge; + const scalar cosAngle + = vectorTools::cosPhi(edgeDir, lineBetweenPoints); - // Searching for the nearest point in existingEdgeLocations using the - // indexedOctree + // Allow the point to be added if it is almost at right angles to + // the other point. Also check it is not the same point. + // Info<< cosAngle<< " " + // << radToDeg(acos(cosAngle)) << " " + // << searchConeAngle << " " + // << radToDeg(acos(searchConeAngle)) << endl; - // Average the points... -// if (info.hit()) -// { -// Foam::point newPt = 0.5*(info.hitPoint() + pt); -// -// pHit.setPoint(newPt); -// -// //boolList toRemove(existingEdgeLocations.size(), false); -// -// forAll(existingEdgeLocations, pI) -// { -// if (pI == info.index()) -// { -// //toRemove[pI] = true; -// edgeLocationTree.remove(pI); -// } -// } -//// -//// pointField newExistingEdgeLocations(existingEdgeLocations.size()); -//// -//// label count = 0; -//// forAll(existingEdgeLocations, pI) -//// { -//// if (toRemove[pI] == false) -//// { -//// newExistingEdgeLocations[count++] = -//// existingEdgeLocations[pI]; -//// } -//// } -//// -//// newExistingEdgeLocations.resize(count); -//// -//// existingEdgeLocations = newExistingEdgeLocations; -//// -//// existingEdgeLocations.append(newPt); -// -// return !info.hit(); -// } + if + ( + mag(cosAngle) < searchConeAngle + && ( + mag(lineBetweenPoints) + > cvMeshControls().pointPairDistanceCoeff()*targetCellSize(pt) + ) + ) + { + pt = edgeHit.hitPoint(); + pHit.setPoint(pt); + closeToFeatureEdge = false; + } + else + { + closeToFeatureEdge = true; + break; + } + } + } + + if (!closeToFeatureEdge) + { + appendToEdgeLocationTree(pt, existingEdgeLocations); + } + return closeToFeatureEdge; } @@ -2265,12 +2653,6 @@ void Foam::conformalVoronoiMesh::addSurfaceAndEdgeHits featuresHit ); - // Gather edge locations but do not add them to newEdgeLocations inside - // the loop as they will prevent nearby edge locations of different - // types being conformed to. - - DynamicList<Foam::point> currentEdgeLocations; - forAll(edHitsByFeature, i) { const label featureHit = featuresHit[i]; @@ -2281,39 +2663,43 @@ void Foam::conformalVoronoiMesh::addSurfaceAndEdgeHits { pointIndexHit& edHit = edHits[eHitI]; - if (!nearFeaturePt(edHit.hitPoint()) && keepSurfacePoint) + if (edHit.hit()) { - if - ( - magSqr(edHit.hitPoint() - surfHitI.hitPoint()) - < surfacePtReplaceDistCoeffSqr*cellSizeSqr - ) + if (!nearFeaturePt(edHit.hitPoint())) { - // If the point is within a given distance of a feature - // edge, give control to edge control points instead, - // this will prevent "pits" forming. + if + ( + magSqr(edHit.hitPoint() - surfHitI.hitPoint()) + < surfacePtReplaceDistCoeffSqr*cellSizeSqr + ) + { + // If the point is within a given distance of a + // feature edge, give control to edge control points + // instead, this will prevent "pits" forming. - keepSurfacePoint = false; + keepSurfacePoint = false; - // NEED TO REMOVE FROM THE SURFACE TREE... - } + // NEED TO REMOVE FROM THE SURFACE TREE... + surfacePtLocationTreePtr_().remove + ( + existingSurfacePtLocations.size() + ); + } - if - ( - !nearFeatureEdgeLocation + if ( - edHit, - existingEdgeLocations + !nearFeatureEdgeLocation + ( + edHit, + existingEdgeLocations + ) ) - ) - { - // Do not place edge control points too close to a - // feature point or existing edge control points - - featureEdgeHits.append(edHit); - featureEdgeFeaturesHit.append(featureHit); - - currentEdgeLocations.append(edHit.hitPoint()); + { + // Do not place edge control points too close to a + // feature point or existing edge control points + featureEdgeHits.append(edHit); + featureEdgeFeaturesHit.append(featureHit); + } } } } @@ -2322,7 +2708,6 @@ void Foam::conformalVoronoiMesh::addSurfaceAndEdgeHits if (keepSurfacePoint) { surfaceHits.append(surfHitI); - hitSurfaces.append(hitSurfaceI); } } diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C index ab7ce33f8563760f144c6aff33f6893a1a7e0078..89afb87134a98ce7b7c9c5ec37afe4764ed4f4b2 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C @@ -125,7 +125,7 @@ void Foam::conformalVoronoiMesh::drawDelaunayCell os << "# cell index: " << label(c->cellIndex()) << endl; os << "# circumradius " - << mag(topoint(dual(c)) - topoint(c->vertex(0)->point())) + << mag(c->dual() - topoint(c->vertex(0)->point())) << endl; for (int i = 0; i < 4; i++) @@ -144,7 +144,7 @@ void Foam::conformalVoronoiMesh::drawDelaunayCell os << "# cicumcentre " << endl; - meshTools::writeOBJ(os, topoint(dual(c))); + meshTools::writeOBJ(os, c->dual()); os << "l " << 1 + offset << " " << 5 + offset << endl; } @@ -167,7 +167,7 @@ void Foam::conformalVoronoiMesh::writePoints ++vit ) { - if (!internalOnly || vit->internalOrBoundaryPoint()) + if (!internalOnly || vit->internalPoint()) { meshTools::writeOBJ(str, topoint(vit->point())); } @@ -241,7 +241,7 @@ void Foam::conformalVoronoiMesh::writeProcessorInterface { if (!cit->farCell()) { - points[cit->cellIndex()] = topoint(dual(cit)); + points[cit->cellIndex()] = cit->dual(); } } diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell.H index 7ab4f10853427619285ce87430f1ccf14cd31e42..5fc7e970b1131c78607d13f71c91ff3b90aeb276 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCell.H @@ -51,6 +51,7 @@ SourceFiles #include "Swap.H" #include "InfoProxy.H" #include "tetCell.H" +#include "typeInfo.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -154,6 +155,8 @@ public: inline int cellIndex() const; + inline const Foam::point& dual(); + inline bool farCell() const; inline int& filterCount(); @@ -163,6 +166,11 @@ public: //- Is the Delaunay cell real, i.e. any real vertex inline bool real() const; + //- Does the Delaunay cell have a far point + inline bool hasFarPoint() const; + + inline bool hasInternalPoint() const; + //- Does the Dual vertex form part of a processor patch inline bool parallelDualVertex() const; @@ -190,6 +198,8 @@ public: // least one Delaunay vertex outside and at least one inside inline bool boundaryDualVertex() const; + inline bool nearProcBoundary() const; + // Info diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCellI.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCellI.H index 5fbd378f9d9a220845245127070d9624f2ac9bba..6450b01908a44149dbde6d8abc6d8e927f6083b1 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCellI.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedCellI.H @@ -86,6 +86,24 @@ int CGAL::indexedCell<Gt, Cb>::cellIndex() const } +template<class Gt, class Cb> +const Foam::point& CGAL::indexedCell<Gt, Cb>::dual() +{ +#ifdef CGAL_INEXACT + return reinterpret_cast<const Foam::point&>(this->circumcenter()); +#else + const typename Gt::Point_3& P = this->circumcenter(); + + return + ( + CGAL::to_double(P.x()), + CGAL::to_double(P.y()), + CGAL::to_double(P.z()) + ); +#endif +} + + template<class Gt, class Cb> inline bool CGAL::indexedCell<Gt, Cb>::farCell() const { @@ -112,10 +130,45 @@ inline bool CGAL::indexedCell<Gt, Cb>::real() const { return ( - this->vertex(0)->real() - || this->vertex(1)->real() - || this->vertex(2)->real() - || this->vertex(3)->real() + ( + this->vertex(0)->real() + || this->vertex(1)->real() + || this->vertex(2)->real() + || this->vertex(3)->real() + ) + && + !( + this->vertex(0)->farPoint() + || this->vertex(1)->farPoint() + || this->vertex(2)->farPoint() + || this->vertex(3)->farPoint() + ) + ); +} + + +template<class Gt, class Cb> +inline bool CGAL::indexedCell<Gt, Cb>::hasFarPoint() const +{ + return + ( + this->vertex(0)->farPoint() + || this->vertex(1)->farPoint() + || this->vertex(2)->farPoint() + || this->vertex(3)->farPoint() + ); +} + + +template<class Gt, class Cb> +inline bool CGAL::indexedCell<Gt, Cb>::hasInternalPoint() const +{ + return + ( + this->vertex(0)->internalPoint() + || this->vertex(1)->internalPoint() + || this->vertex(2)->internalPoint() + || this->vertex(3)->internalPoint() ); } @@ -285,4 +338,17 @@ inline bool CGAL::indexedCell<Gt, Cb>::boundaryDualVertex() const } +template<class Gt, class Cb> +inline bool CGAL::indexedCell<Gt, Cb>::nearProcBoundary() const +{ + return + ( + this->vertex(0)->nearProcBoundary() + || this->vertex(1)->nearProcBoundary() + || this->vertex(2)->nearProcBoundary() + || this->vertex(3)->nearProcBoundary() + ); +} + + // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * // diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.C b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.C index 9ad21f92feade712950e9aed5d5cb6d1a21a3eaf..2173e7f5fa7b6be6a0469b004a46e9148f4195f7 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.C +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.C @@ -29,7 +29,6 @@ License \*---------------------------------------------------------------------------*/ #include "indexedVertex.H" -//#include "conformalVoronoiMesh.H" #include "point.H" // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * // diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.H index 246020fd172bbeb127089dc9bcc085c0aa7908e2..525c2156e82b60682ca93eb20d44fc4d34d051d7 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertex.H @@ -45,6 +45,7 @@ SourceFiles #include <CGAL/Triangulation_3.h> #include "tensor.H" #include "InfoProxy.H" +#include "point.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -101,6 +102,8 @@ class indexedVertex //- Specify whether the vertex is fixed or movable. bool vertexFixed_; + bool nearProcBoundary_; + public: @@ -198,6 +201,12 @@ public: //- Set the point to be near the boundary inline void setNearBoundary(); + //- Is point internal and near a proc boundary + inline bool nearProcBoundary() const; + + //- Set the point to be near a proc boundary + inline void setNearProcBoundary(); + //- Either master or slave of pointPair. inline bool pairPoint() const; @@ -227,7 +236,7 @@ public: inline bool isVertexFixed() const; //- Fix the vertex so that it can't be moved - inline void setVertexFixed() const; + inline void setVertexFixed(); // inline void operator=(const Delaunay::Finite_vertices_iterator vit) // { diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertexI.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertexI.H index c02ec4df2009489efa9fe91221a666b9f9ae0050..1e225eaa2ed02a2674b57a713fbc142f05d451b4 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertexI.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformalVoronoiMesh/indexedVertexI.H @@ -38,7 +38,8 @@ inline CGAL::indexedVertex<Gt, Vb>::indexedVertex() type_(vtInternal), alignment_(), targetCellSize_(0.0), - vertexFixed_(false) + vertexFixed_(false), + nearProcBoundary_(false) {} @@ -50,7 +51,8 @@ inline CGAL::indexedVertex<Gt, Vb>::indexedVertex(const Point& p) type_(vtInternal), alignment_(), targetCellSize_(0.0), - vertexFixed_(false) + vertexFixed_(false), + nearProcBoundary_(false) {} @@ -67,7 +69,8 @@ inline CGAL::indexedVertex<Gt, Vb>::indexedVertex type_(type), alignment_(), targetCellSize_(0.0), - vertexFixed_(false) + vertexFixed_(false), + nearProcBoundary_(false) {} @@ -79,7 +82,8 @@ inline CGAL::indexedVertex<Gt, Vb>::indexedVertex(const Point& p, Cell_handle f) type_(vtInternal), alignment_(), targetCellSize_(0.0), - vertexFixed_(false) + vertexFixed_(false), + nearProcBoundary_(false) {} @@ -91,7 +95,8 @@ inline CGAL::indexedVertex<Gt, Vb>::indexedVertex(Cell_handle f) type_(vtInternal), alignment_(), targetCellSize_(0.0), - vertexFixed_(false) + vertexFixed_(false), + nearProcBoundary_(false) {} @@ -251,6 +256,20 @@ inline void CGAL::indexedVertex<Gt, Vb>::setNearBoundary() } +template<class Gt, class Vb> +inline bool CGAL::indexedVertex<Gt, Vb>::nearProcBoundary() const +{ + return nearProcBoundary_; +} + + +template<class Gt, class Vb> +inline void CGAL::indexedVertex<Gt, Vb>::setNearProcBoundary() +{ + nearProcBoundary_ = true; +} + + template<class Gt, class Vb> inline bool CGAL::indexedVertex<Gt, Vb>::pairPoint() const { @@ -331,7 +350,7 @@ inline bool CGAL::indexedVertex<Gt, Vb>::isVertexFixed() const template<class Gt, class Vb> -inline void CGAL::indexedVertex<Gt, Vb>::setVertexFixed() const +inline void CGAL::indexedVertex<Gt, Vb>::setVertexFixed() { vertexFixed_ = true; } diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H index d8e5fd016616633358be21ac667efdac3eab22bf..ce56a977aa8e676c6f30f655a2730a90f2e4c3d8 100644 --- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H +++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/conformationSurfaces/conformationSurfaces.H @@ -285,7 +285,9 @@ public: ) const; //- Find the nearest points on each feature edge that is within - // a given distance from the sample point + // a given distance from the sample point. Will need to check for + // a hit or a miss because near edges may not have a nearest point + // on them which is perpendicular to the sample point. void findAllNearestEdges ( const point& sample, diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/files b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..a0fcd8f0bf85d8c5624f026c6cae568cd63f7251 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/files @@ -0,0 +1,6 @@ +cvMeshSurfaceSimplify.C + +MarchingCubes/MarchingCubes.cpp +MarchingCubes/ply.c + +EXE = $(FOAM_APPBIN)/cvMeshSurfaceSimplify diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/options b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..1711b9ba615e3d9a77ea1e005fc6dc392a93a06e --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/options @@ -0,0 +1,17 @@ +include $(GENERAL_RULES)/CGAL + +EXE_INC = \ + -IMarchingCubes \ + -I../conformalVoronoiMesh/lnInclude \ + -I$(LIB_SRC)/edgeMesh/lnInclude \ + -I$(LIB_SRC)/triSurface/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + $(CGAL_LIBS) \ + -lconformalVoronoiMesh \ + -ldecompositionMethods -L$(FOAM_LIBBIN)/dummy -lscotchDecomp \ + -ledgeMesh \ + -ltriSurface \ + -lmeshTools \ + -ldynamicMesh diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/LookUpTable.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/LookUpTable.h new file mode 100755 index 0000000000000000000000000000000000000000..5529346954a3fb59076c85d2edaf980978f4a245 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/LookUpTable.h @@ -0,0 +1,2322 @@ +/** + * @file LookUpTable.h + * @author Thomas Lewiner <thomas.lewiner@polytechnique.org> + * @author Math Dept, PUC-Rio + * @version 0.2 + * @date 12/08/2002 + * + * @brief LookUpTable for the MarchingCubes 33 Algorithm + */ +//________________________________________________ + + + +#ifndef _LOOKUPTABLE_H_ +#define _LOOKUPTABLE_H_ + + + + + +//_____________________________________________________________________________ +/** + * \brief case mapping + * For each of the possible vertex states listed in this table there is a + * specific triangulation of the edge intersection points. The table lists + * all of them in the form of 0-5 edge triples with the list terminated by + * the invalid value -1. For example: case[3] list the 2 triangles + * formed when cube[0] and cube[1] are inside of the surface, but the rest of + * the cube is not. + * + * Cube description: + * 7 ________ 6 _____6__ ________ + * /| /| 7/| /| /| /| + * / | / | / | /5 | / 6 / | + * 4 /_______ / | /__4____ / 10 /_______3/ | + * | | |5 | | 11 | | | | | 2 | + * | 3|__|_____|2 | |__|__2__| | 4 |__|_____| + * | / | / 8 3/ 9 / | / | / + * | / | / | / | /1 | / 5 / + * |/_______|/ |/___0___|/ |/_1_____|/ + * 0 1 0 1 + */ +//----------------------------------------------------------------------------- +static const char cases[256][2] = { +/* 0: */ { 0, -1 }, +/* 1: 0, */ { 1, 0 }, +/* 2: 1, */ { 1, 1 }, +/* 3: 0, 1, */ { 2, 0 }, +/* 4: 2, */ { 1, 2 }, +/* 5: 0, 2, */ { 3, 0 }, +/* 6: 1, 2, */ { 2, 3 }, +/* 7: 0, 1, 2, */ { 5, 0 }, +/* 8: 3, */ { 1, 3 }, +/* 9: 0, 3, */ { 2, 1 }, +/* 10: 1, 3, */ { 3, 3 }, +/* 11: 0, 1, 3, */ { 5, 1 }, +/* 12: 2, 3, */ { 2, 5 }, +/* 13: 0, 2, 3, */ { 5, 4 }, +/* 14: 1, 2, 3, */ { 5, 9 }, +/* 15: 0, 1, 2, 3, */ { 8, 0 }, +/* 16: 4, */ { 1, 4 }, +/* 17: 0, 4, */ { 2, 2 }, +/* 18: 1, 4, */ { 3, 4 }, +/* 19: 0, 1, 4, */ { 5, 2 }, +/* 20: 2, 4, */ { 4, 2 }, +/* 21: 0, 2, 4, */ { 6, 2 }, +/* 22: 1, 2, 4, */ { 6, 9 }, +/* 23: 0, 1, 2, 4, */ { 11, 0 }, +/* 24: 3, 4, */ { 3, 8 }, +/* 25: 0, 3, 4, */ { 5, 5 }, +/* 26: 1, 3, 4, */ { 7, 3 }, +/* 27: 0, 1, 3, 4, */ { 9, 1 }, +/* 28: 2, 3, 4, */ { 6, 16 }, +/* 29: 0, 2, 3, 4, */ { 14, 3 }, +/* 30: 1, 2, 3, 4, */ { 12, 12 }, +/* 31: 0, 1, 2, 3, 4, */ { 5, 24 }, +/* 32: 5, */ { 1, 5 }, +/* 33: 0, 5, */ { 3, 1 }, +/* 34: 1, 5, */ { 2, 4 }, +/* 35: 0, 1, 5, */ { 5, 3 }, +/* 36: 2, 5, */ { 3, 6 }, +/* 37: 0, 2, 5, */ { 7, 0 }, +/* 38: 1, 2, 5, */ { 5, 10 }, +/* 39: 0, 1, 2, 5, */ { 9, 0 }, +/* 40: 3, 5, */ { 4, 3 }, +/* 41: 0, 3, 5, */ { 6, 4 }, +/* 42: 1, 3, 5, */ { 6, 11 }, +/* 43: 0, 1, 3, 5, */ { 14, 1 }, +/* 44: 2, 3, 5, */ { 6, 17 }, +/* 45: 0, 2, 3, 5, */ { 12, 4 }, +/* 46: 1, 2, 3, 5, */ { 11, 6 }, +/* 47: 0, 1, 2, 3, 5, */ { 5, 25 }, +/* 48: 4, 5, */ { 2, 8 }, +/* 49: 0, 4, 5, */ { 5, 7 }, +/* 50: 1, 4, 5, */ { 5, 12 }, +/* 51: 0, 1, 4, 5, */ { 8, 1 }, +/* 52: 2, 4, 5, */ { 6, 18 }, +/* 53: 0, 2, 4, 5, */ { 12, 5 }, +/* 54: 1, 2, 4, 5, */ { 14, 7 }, +/* 55: 0, 1, 2, 4, 5, */ { 5, 28 }, +/* 56: 3, 4, 5, */ { 6, 21 }, +/* 57: 0, 3, 4, 5, */ { 11, 4 }, +/* 58: 1, 3, 4, 5, */ { 12, 15 }, +/* 59: 0, 1, 3, 4, 5, */ { 5, 30 }, +/* 60: 2, 3, 4, 5, */ { 10, 5 }, +/* 61: 0, 2, 3, 4, 5, */ { 6, 32 }, +/* 62: 1, 2, 3, 4, 5, */ { 6, 39 }, +/* 63: 0, 1, 2, 3, 4, 5, */ { 2, 12 }, +/* 64: 6, */ { 1, 6 }, +/* 65: 0, 6, */ { 4, 0 }, +/* 66: 1, 6, */ { 3, 5 }, +/* 67: 0, 1, 6, */ { 6, 0 }, +/* 68: 2, 6, */ { 2, 6 }, +/* 69: 0, 2, 6, */ { 6, 3 }, +/* 70: 1, 2, 6, */ { 5, 11 }, +/* 71: 0, 1, 2, 6, */ { 14, 0 }, +/* 72: 3, 6, */ { 3, 9 }, +/* 73: 0, 3, 6, */ { 6, 5 }, +/* 74: 1, 3, 6, */ { 7, 4 }, +/* 75: 0, 1, 3, 6, */ { 12, 1 }, +/* 76: 2, 3, 6, */ { 5, 14 }, +/* 77: 0, 2, 3, 6, */ { 11, 3 }, +/* 78: 1, 2, 3, 6, */ { 9, 4 }, +/* 79: 0, 1, 2, 3, 6, */ { 5, 26 }, +/* 80: 4, 6, */ { 3, 10 }, +/* 81: 0, 4, 6, */ { 6, 6 }, +/* 82: 1, 4, 6, */ { 7, 5 }, +/* 83: 0, 1, 4, 6, */ { 12, 2 }, +/* 84: 2, 4, 6, */ { 6, 19 }, +/* 85: 0, 2, 4, 6, */ { 10, 1 }, +/* 86: 1, 2, 4, 6, */ { 12, 13 }, +/* 87: 0, 1, 2, 4, 6, */ { 6, 24 }, +/* 88: 3, 4, 6, */ { 7, 7 }, +/* 89: 0, 3, 4, 6, */ { 12, 9 }, +/* 90: 1, 3, 4, 6, */ { 13, 1 }, +/* 91: 0, 1, 3, 4, 6, */ { 7, 9 }, +/* 92: 2, 3, 4, 6, */ { 12, 20 }, +/* 93: 0, 2, 3, 4, 6, */ { 6, 33 }, +/* 94: 1, 2, 3, 4, 6, */ { 7, 13 }, +/* 95: 0, 1, 2, 3, 4, 6, */ { 3, 12 }, +/* 96: 5, 6, */ { 2, 10 }, +/* 97: 0, 5, 6, */ { 6, 7 }, +/* 98: 1, 5, 6, */ { 5, 13 }, +/* 99: 0, 1, 5, 6, */ { 11, 2 }, +/* 100: 2, 5, 6, */ { 5, 16 }, +/* 101: 0, 2, 5, 6, */ { 12, 7 }, +/* 102: 1, 2, 5, 6, */ { 8, 3 }, +/* 103: 0, 1, 2, 5, 6, */ { 5, 29 }, +/* 104: 3, 5, 6, */ { 6, 22 }, +/* 105: 0, 3, 5, 6, */ { 10, 2 }, +/* 106: 1, 3, 5, 6, */ { 12, 17 }, +/* 107: 0, 1, 3, 5, 6, */ { 6, 27 }, +/* 108: 2, 3, 5, 6, */ { 14, 9 }, +/* 109: 0, 2, 3, 5, 6, */ { 6, 34 }, +/* 110: 1, 2, 3, 5, 6, */ { 5, 39 }, +/* 111: 0, 1, 2, 3, 5, 6, */ { 2, 14 }, +/* 112: 4, 5, 6, */ { 5, 20 }, +/* 113: 0, 4, 5, 6, */ { 14, 5 }, +/* 114: 1, 4, 5, 6, */ { 9, 5 }, +/* 115: 0, 1, 4, 5, 6, */ { 5, 32 }, +/* 116: 2, 4, 5, 6, */ { 11, 10 }, +/* 117: 0, 2, 4, 5, 6, */ { 6, 35 }, +/* 118: 1, 2, 4, 5, 6, */ { 5, 41 }, +/* 119: 0, 1, 2, 4, 5, 6, */ { 2, 16 }, +/* 120: 3, 4, 5, 6, */ { 12, 23 }, +/* 121: 0, 3, 4, 5, 6, */ { 6, 37 }, +/* 122: 1, 3, 4, 5, 6, */ { 7, 14 }, +/* 123: 0, 1, 3, 4, 5, 6, */ { 3, 16 }, +/* 124: 2, 3, 4, 5, 6, */ { 6, 46 }, +/* 125: 0, 2, 3, 4, 5, 6, */ { 4, 6 }, +/* 126: 1, 2, 3, 4, 5, 6, */ { 3, 21 }, +/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 1, 8 }, +/* 128: 7, */ { 1, 7 }, +/* 129: 0, 7, */ { 3, 2 }, +/* 130: 1, 7, */ { 4, 1 }, +/* 131: 0, 1, 7, */ { 6, 1 }, +/* 132: 2, 7, */ { 3, 7 }, +/* 133: 0, 2, 7, */ { 7, 1 }, +/* 134: 1, 2, 7, */ { 6, 10 }, +/* 135: 0, 1, 2, 7, */ { 12, 0 }, +/* 136: 3, 7, */ { 2, 7 }, +/* 137: 0, 3, 7, */ { 5, 6 }, +/* 138: 1, 3, 7, */ { 6, 12 }, +/* 139: 0, 1, 3, 7, */ { 11, 1 }, +/* 140: 2, 3, 7, */ { 5, 15 }, +/* 141: 0, 2, 3, 7, */ { 9, 2 }, +/* 142: 1, 2, 3, 7, */ { 14, 6 }, +/* 143: 0, 1, 2, 3, 7, */ { 5, 27 }, +/* 144: 4, 7, */ { 2, 9 }, +/* 145: 0, 4, 7, */ { 5, 8 }, +/* 146: 1, 4, 7, */ { 6, 13 }, +/* 147: 0, 1, 4, 7, */ { 14, 2 }, +/* 148: 2, 4, 7, */ { 6, 20 }, +/* 149: 0, 2, 4, 7, */ { 12, 6 }, +/* 150: 1, 2, 4, 7, */ { 10, 3 }, +/* 151: 0, 1, 2, 4, 7, */ { 6, 25 }, +/* 152: 3, 4, 7, */ { 5, 18 }, +/* 153: 0, 3, 4, 7, */ { 8, 2 }, +/* 154: 1, 3, 4, 7, */ { 12, 16 }, +/* 155: 0, 1, 3, 4, 7, */ { 5, 31 }, +/* 156: 2, 3, 4, 7, */ { 11, 9 }, +/* 157: 0, 2, 3, 4, 7, */ { 5, 34 }, +/* 158: 1, 2, 3, 4, 7, */ { 6, 40 }, +/* 159: 0, 1, 2, 3, 4, 7, */ { 2, 13 }, +/* 160: 5, 7, */ { 3, 11 }, +/* 161: 0, 5, 7, */ { 7, 2 }, +/* 162: 1, 5, 7, */ { 6, 14 }, +/* 163: 0, 1, 5, 7, */ { 12, 3 }, +/* 164: 2, 5, 7, */ { 7, 6 }, +/* 165: 0, 2, 5, 7, */ { 13, 0 }, +/* 166: 1, 2, 5, 7, */ { 12, 14 }, +/* 167: 0, 1, 2, 5, 7, */ { 7, 8 }, +/* 168: 3, 5, 7, */ { 6, 23 }, +/* 169: 0, 3, 5, 7, */ { 12, 10 }, +/* 170: 1, 3, 5, 7, */ { 10, 4 }, +/* 171: 0, 1, 3, 5, 7, */ { 6, 28 }, +/* 172: 2, 3, 5, 7, */ { 12, 21 }, +/* 173: 0, 2, 3, 5, 7, */ { 7, 10 }, +/* 174: 1, 2, 3, 5, 7, */ { 6, 41 }, +/* 175: 0, 1, 2, 3, 5, 7, */ { 3, 13 }, +/* 176: 4, 5, 7, */ { 5, 21 }, +/* 177: 0, 4, 5, 7, */ { 9, 3 }, +/* 178: 1, 4, 5, 7, */ { 11, 8 }, +/* 179: 0, 1, 4, 5, 7, */ { 5, 33 }, +/* 180: 2, 4, 5, 7, */ { 12, 22 }, +/* 181: 0, 2, 4, 5, 7, */ { 7, 11 }, +/* 182: 1, 2, 4, 5, 7, */ { 6, 42 }, +/* 183: 0, 1, 2, 4, 5, 7, */ { 3, 14 }, +/* 184: 3, 4, 5, 7, */ { 14, 11 }, +/* 185: 0, 3, 4, 5, 7, */ { 5, 36 }, +/* 186: 1, 3, 4, 5, 7, */ { 6, 44 }, +/* 187: 0, 1, 3, 4, 5, 7, */ { 2, 17 }, +/* 188: 2, 3, 4, 5, 7, */ { 6, 47 }, +/* 189: 0, 2, 3, 4, 5, 7, */ { 3, 18 }, +/* 190: 1, 2, 3, 4, 5, 7, */ { 4, 7 }, +/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 1, 9 }, +/* 192: 6, 7, */ { 2, 11 }, +/* 193: 0, 6, 7, */ { 6, 8 }, +/* 194: 1, 6, 7, */ { 6, 15 }, +/* 195: 0, 1, 6, 7, */ { 10, 0 }, +/* 196: 2, 6, 7, */ { 5, 17 }, +/* 197: 0, 2, 6, 7, */ { 12, 8 }, +/* 198: 1, 2, 6, 7, */ { 11, 7 }, +/* 199: 0, 1, 2, 6, 7, */ { 6, 26 }, +/* 200: 3, 6, 7, */ { 5, 19 }, +/* 201: 0, 3, 6, 7, */ { 14, 4 }, +/* 202: 1, 3, 6, 7, */ { 12, 18 }, +/* 203: 0, 1, 3, 6, 7, */ { 6, 29 }, +/* 204: 2, 3, 6, 7, */ { 8, 4 }, +/* 205: 0, 2, 3, 6, 7, */ { 5, 35 }, +/* 206: 1, 2, 3, 6, 7, */ { 5, 40 }, +/* 207: 0, 1, 2, 3, 6, 7, */ { 2, 15 }, +/* 208: 4, 6, 7, */ { 5, 22 }, +/* 209: 0, 4, 6, 7, */ { 11, 5 }, +/* 210: 1, 4, 6, 7, */ { 12, 19 }, +/* 211: 0, 1, 4, 6, 7, */ { 6, 30 }, +/* 212: 2, 4, 6, 7, */ { 14, 10 }, +/* 213: 0, 2, 4, 6, 7, */ { 6, 36 }, +/* 214: 1, 2, 4, 6, 7, */ { 6, 43 }, +/* 215: 0, 1, 2, 4, 6, 7, */ { 4, 4 }, +/* 216: 3, 4, 6, 7, */ { 9, 7 }, +/* 217: 0, 3, 4, 6, 7, */ { 5, 37 }, +/* 218: 1, 3, 4, 6, 7, */ { 7, 15 }, +/* 219: 0, 1, 3, 4, 6, 7, */ { 3, 17 }, +/* 220: 2, 3, 4, 6, 7, */ { 5, 44 }, +/* 221: 0, 2, 3, 4, 6, 7, */ { 2, 19 }, +/* 222: 1, 2, 3, 4, 6, 7, */ { 3, 22 }, +/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 1, 10 }, +/* 224: 5, 6, 7, */ { 5, 23 }, +/* 225: 0, 5, 6, 7, */ { 12, 11 }, +/* 226: 1, 5, 6, 7, */ { 14, 8 }, +/* 227: 0, 1, 5, 6, 7, */ { 6, 31 }, +/* 228: 2, 5, 6, 7, */ { 9, 6 }, +/* 229: 0, 2, 5, 6, 7, */ { 7, 12 }, +/* 230: 1, 2, 5, 6, 7, */ { 5, 42 }, +/* 231: 0, 1, 2, 5, 6, 7, */ { 3, 15 }, +/* 232: 3, 5, 6, 7, */ { 11, 11 }, +/* 233: 0, 3, 5, 6, 7, */ { 6, 38 }, +/* 234: 1, 3, 5, 6, 7, */ { 6, 45 }, +/* 235: 0, 1, 3, 5, 6, 7, */ { 4, 5 }, +/* 236: 2, 3, 5, 6, 7, */ { 5, 45 }, +/* 237: 0, 2, 3, 5, 6, 7, */ { 3, 19 }, +/* 238: 1, 2, 3, 5, 6, 7, */ { 2, 21 }, +/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 1, 11 }, +/* 240: 4, 5, 6, 7, */ { 8, 5 }, +/* 241: 0, 4, 5, 6, 7, */ { 5, 38 }, +/* 242: 1, 4, 5, 6, 7, */ { 5, 43 }, +/* 243: 0, 1, 4, 5, 6, 7, */ { 2, 18 }, +/* 244: 2, 4, 5, 6, 7, */ { 5, 46 }, +/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 20 }, +/* 246: 1, 2, 4, 5, 6, 7, */ { 2, 22 }, +/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 1, 12 }, +/* 248: 3, 4, 5, 6, 7, */ { 5, 47 }, +/* 249: 0, 3, 4, 5, 6, 7, */ { 2, 20 }, +/* 250: 1, 3, 4, 5, 6, 7, */ { 3, 23 }, +/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 13 }, +/* 252: 2, 3, 4, 5, 6, 7, */ { 2, 23 }, +/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 1, 14 }, +/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 1, 15 }, +/* 255: 0, 1, 2, 3, 4, 5, 6, 7, */ { 0, -1 } +}; +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 1 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling1[16][3] = { +/* 1: 0, */ { 0, 8, 3 }, +/* 2: 1, */ { 0, 1, 9 }, +/* 4: 2, */ { 1, 2, 10 }, +/* 8: 3, */ { 3, 11, 2 }, +/* 16: 4, */ { 4, 7, 8 }, +/* 32: 5, */ { 9, 5, 4 }, +/* 64: 6, */ { 10, 6, 5 }, +/* 128: 7, */ { 7, 6, 11 }, +/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 7, 11, 6 }, +/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 10, 5, 6 }, +/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 9, 4, 5 }, +/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 4, 8, 7 }, +/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 3, 2, 11 }, +/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 10, 2 }, +/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 0, 9, 1 }, +/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 0, 3, 8 } +}; +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling2[24][6] = { +/* 3: 0, 1, */ { 1, 8, 3, 9, 8, 1 }, +/* 9: 0, 3, */ { 0, 11, 2, 8, 11, 0 }, +/* 17: 0, 4, */ { 4, 3, 0, 7, 3, 4 }, +/* 6: 1, 2, */ { 9, 2, 10, 0, 2, 9 }, +/* 34: 1, 5, */ { 0, 5, 4, 1, 5, 0 }, +/* 12: 2, 3, */ { 3, 10, 1, 11, 10, 3 }, +/* 68: 2, 6, */ { 1, 6, 5, 2, 6, 1 }, +/* 136: 3, 7, */ { 7, 2, 3, 6, 2, 7 }, +/* 48: 4, 5, */ { 9, 7, 8, 5, 7, 9 }, +/* 144: 4, 7, */ { 6, 8, 4, 11, 8, 6 }, +/* 96: 5, 6, */ { 10, 4, 9, 6, 4, 10 }, +/* 192: 6, 7, */ { 11, 5, 10, 7, 5, 11 }, +/* 63: 0, 1, 2, 3, 4, 5, */ { 11, 10, 5, 7, 11, 5 }, +/* 159: 0, 1, 2, 3, 4, 7, */ { 10, 9, 4, 6, 10, 4 }, +/* 111: 0, 1, 2, 3, 5, 6, */ { 6, 4, 8, 11, 6, 8 }, +/* 207: 0, 1, 2, 3, 6, 7, */ { 9, 8, 7, 5, 9, 7 }, +/* 119: 0, 1, 2, 4, 5, 6, */ { 7, 3, 2, 6, 7, 2 }, +/* 187: 0, 1, 3, 4, 5, 7, */ { 1, 5, 6, 2, 1, 6 }, +/* 243: 0, 1, 4, 5, 6, 7, */ { 3, 1, 10, 11, 3, 10 }, +/* 221: 0, 2, 3, 4, 6, 7, */ { 0, 4, 5, 1, 0, 5 }, +/* 249: 0, 3, 4, 5, 6, 7, */ { 9, 10, 2, 0, 9, 2 }, +/* 238: 1, 2, 3, 5, 6, 7, */ { 4, 0, 3, 7, 4, 3 }, +/* 246: 1, 2, 4, 5, 6, 7, */ { 0, 2, 11, 8, 0, 11 }, +/* 252: 2, 3, 4, 5, 6, 7, */ { 1, 3, 8, 9, 1, 8 } +}; +//_____________________________________________________________________________ + +//_____________________________________________________________________________ +/** + * \brief test table for case 3 + * One face to test + * When the test on the specified face is positive : 4 first triangles + * When the test on the specified face is negative : 2 last triangles + * + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char test3[24] = { +/* 5: 0, 2, */ 5, +/* 33: 0, 5, */ 1, +/* 129: 0, 7, */ 4, +/* 10: 1, 3, */ 5, +/* 18: 1, 4, */ 1, +/* 66: 1, 6, */ 2, +/* 36: 2, 5, */ 2, +/* 132: 2, 7, */ 3, +/* 24: 3, 4, */ 4, +/* 72: 3, 6, */ 3, +/* 80: 4, 6, */ 6, +/* 160: 5, 7, */ 6, +/* 95: 0, 1, 2, 3, 4, 6, */ -6, +/* 175: 0, 1, 2, 3, 5, 7, */ -6, +/* 183: 0, 1, 2, 4, 5, 7, */ -3, +/* 231: 0, 1, 2, 5, 6, 7, */ -4, +/* 123: 0, 1, 3, 4, 5, 6, */ -3, +/* 219: 0, 1, 3, 4, 6, 7, */ -2, +/* 189: 0, 2, 3, 4, 5, 7, */ -2, +/* 237: 0, 2, 3, 5, 6, 7, */ -1, +/* 245: 0, 2, 4, 5, 6, 7, */ -5, +/* 126: 1, 2, 3, 4, 5, 6, */ -4, +/* 222: 1, 2, 3, 4, 6, 7, */ -1, +/* 250: 1, 3, 4, 5, 6, 7, */ -5 +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 3.1 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling3_1[24][6] = { +/* 5: 0, 2, */ { 0, 8, 3, 1, 2, 10 }, +/* 33: 0, 5, */ { 9, 5, 4, 0, 8, 3 }, +/* 129: 0, 7, */ { 3, 0, 8, 11, 7, 6 }, +/* 10: 1, 3, */ { 1, 9, 0, 2, 3, 11 }, +/* 18: 1, 4, */ { 0, 1, 9, 8, 4, 7 }, +/* 66: 1, 6, */ { 9, 0, 1, 5, 10, 6 }, +/* 36: 2, 5, */ { 1, 2, 10, 9, 5, 4 }, +/* 132: 2, 7, */ { 10, 1, 2, 6, 11, 7 }, +/* 24: 3, 4, */ { 8, 4, 7, 3, 11, 2 }, +/* 72: 3, 6, */ { 2, 3, 11, 10, 6, 5 }, +/* 80: 4, 6, */ { 5, 10, 6, 4, 7, 8 }, +/* 160: 5, 7, */ { 4, 9, 5, 7, 6, 11 }, +/* 95: 0, 1, 2, 3, 4, 6, */ { 5, 9, 4, 11, 6, 7 }, +/* 175: 0, 1, 2, 3, 5, 7, */ { 6, 10, 5, 8, 7, 4 }, +/* 183: 0, 1, 2, 4, 5, 7, */ { 11, 3, 2, 5, 6, 10 }, +/* 231: 0, 1, 2, 5, 6, 7, */ { 7, 4, 8, 2, 11, 3 }, +/* 123: 0, 1, 3, 4, 5, 6, */ { 2, 1, 10, 7, 11, 6 }, +/* 219: 0, 1, 3, 4, 6, 7, */ { 10, 2, 1, 4, 5, 9 }, +/* 189: 0, 2, 3, 4, 5, 7, */ { 1, 0, 9, 6, 10, 5 }, +/* 237: 0, 2, 3, 5, 6, 7, */ { 9, 1, 0, 7, 4, 8 }, +/* 245: 0, 2, 4, 5, 6, 7, */ { 0, 9, 1, 11, 3, 2 }, +/* 126: 1, 2, 3, 4, 5, 6, */ { 8, 0, 3, 6, 7, 11 }, +/* 222: 1, 2, 3, 4, 6, 7, */ { 4, 5, 9, 3, 8, 0 }, +/* 250: 1, 3, 4, 5, 6, 7, */ { 3, 8, 0, 10, 2, 1 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 3.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling3_2[24][12] = { +/* 5: 0, 2, */ { 10, 3, 2, 10, 8, 3, 10, 1, 0, 8, 10, 0 }, +/* 33: 0, 5, */ { 3, 4, 8, 3, 5, 4, 3, 0, 9, 5, 3, 9 }, +/* 129: 0, 7, */ { 6, 8, 7, 6, 0, 8, 6, 11, 3, 0, 6, 3 }, +/* 10: 1, 3, */ { 11, 0, 3, 11, 9, 0, 11, 2, 1, 9, 11, 1 }, +/* 18: 1, 4, */ { 7, 9, 4, 7, 1, 9, 7, 8, 0, 1, 7, 0 }, +/* 66: 1, 6, */ { 6, 1, 10, 6, 0, 1, 9, 0, 6, 9, 6, 5 }, +/* 36: 2, 5, */ { 4, 10, 5, 4, 2, 10, 4, 9, 1, 2, 4, 1 }, +/* 132: 2, 7, */ { 7, 2, 11, 7, 1, 2, 7, 6, 10, 1, 7, 10 }, +/* 24: 3, 4, */ { 2, 7, 11, 2, 4, 7, 2, 3, 8, 4, 2, 8 }, +/* 72: 3, 6, */ { 5, 11, 6, 5, 3, 11, 5, 10, 2, 3, 5, 2 }, +/* 80: 4, 6, */ { 8, 6, 7, 8, 10, 6, 8, 4, 5, 10, 8, 5 }, +/* 160: 5, 7, */ { 11, 5, 6, 11, 9, 5, 11, 7, 4, 9, 11, 4 }, +/* 95: 0, 1, 2, 3, 4, 6, */ { 6, 5, 11, 5, 9, 11, 4, 7, 11, 4, 11, 9 }, +/* 175: 0, 1, 2, 3, 5, 7, */ { 7, 6, 8, 6, 10, 8, 5, 4, 8, 5, 8, 10 }, +/* 183: 0, 1, 2, 4, 5, 7, */ { 6, 11, 5, 11, 3, 5, 2, 10, 5, 2, 5, 3 }, +/* 231: 0, 1, 2, 5, 6, 7, */ { 11, 7, 2, 7, 4, 2, 8, 3, 2, 8, 2, 4 }, +/* 123: 0, 1, 3, 4, 5, 6, */ { 11, 2, 7, 2, 1, 7, 10, 6, 7, 10, 7, 1 }, +/* 219: 0, 1, 3, 4, 6, 7, */ { 5, 10, 4, 10, 2, 4, 1, 9, 4, 1, 4, 2 }, +/* 189: 0, 2, 3, 4, 5, 7, */ { 10, 1, 6, 1, 0, 6, 6, 0, 9, 5, 6, 9 }, +/* 237: 0, 2, 3, 5, 6, 7, */ { 4, 9, 7, 9, 1, 7, 0, 8, 7, 0, 7, 1 }, +/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 0, 11, 0, 9, 11, 1, 2, 11, 1, 11, 9 }, +/* 126: 1, 2, 3, 4, 5, 6, */ { 7, 8, 6, 8, 0, 6, 3, 11, 6, 3, 6, 0 }, +/* 222: 1, 2, 3, 4, 6, 7, */ { 8, 4, 3, 4, 5, 3, 9, 0, 3, 9, 3, 5 }, +/* 250: 1, 3, 4, 5, 6, 7, */ { 2, 3, 10, 3, 8, 10, 0, 1, 10, 0, 10, 8 } +}; +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +/** + * \brief test table for case 4 + * Interior to test + * When the test on the interior is negative : 2 first triangles + * When the test on the interior is positive : 6 last triangles + * + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char test4[8] = { +/* 65: 0, 6, */ 7, +/* 130: 1, 7, */ 7, +/* 20: 2, 4, */ 7, +/* 40: 3, 5, */ 7, +/* 215: 0, 1, 2, 4, 6, 7, */ -7, +/* 235: 0, 1, 3, 5, 6, 7, */ -7, +/* 125: 0, 2, 3, 4, 5, 6, */ -7, +/* 190: 1, 2, 3, 4, 5, 7, */ -7 +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 4.1 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling4_1[8][6] = { +/* 65: 0, 6, */ { 0, 8, 3, 5, 10, 6 }, +/* 130: 1, 7, */ { 0, 1, 9, 11, 7, 6 }, +/* 20: 2, 4, */ { 1, 2, 10, 8, 4, 7 }, +/* 40: 3, 5, */ { 9, 5, 4, 2, 3, 11 }, +/* 215: 0, 1, 2, 4, 6, 7, */ { 4, 5, 9, 11, 3, 2 }, +/* 235: 0, 1, 3, 5, 6, 7, */ { 10, 2, 1, 7, 4, 8 }, +/* 125: 0, 2, 3, 4, 5, 6, */ { 9, 1, 0, 6, 7, 11 }, +/* 190: 1, 2, 3, 4, 5, 7, */ { 3, 8, 0, 6, 10, 5 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 4.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling4_2[8][18] = { +/* 65: 0, 6, */ { 8, 5, 0, 5, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 5 }, +/* 130: 1, 7, */ { 9, 6, 1, 6, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 6 }, +/* 20: 2, 4, */ { 10, 7, 2, 7, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 7 }, +/* 40: 3, 5, */ { 11, 4, 3, 4, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 4 }, +/* 215: 0, 1, 2, 4, 6, 7, */ { 3, 4, 11, 5, 11, 4, 11, 5, 2, 9, 2, 5, 2, 9, 3, 4, 3, 9 }, +/* 235: 0, 1, 3, 5, 6, 7, */ { 2, 7, 10, 4, 10, 7, 10, 4, 1, 8, 1, 4, 1, 8, 2, 7, 2, 8 }, +/* 125: 0, 2, 3, 4, 5, 6, */ { 1, 6, 9, 7, 9, 6, 9, 7, 0, 11, 0, 7, 0, 11, 1, 6, 1, 11 }, +/* 190: 1, 2, 3, 4, 5, 7, */ { 0, 5, 8, 6, 8, 5, 8, 6, 3, 10, 3, 6, 3, 10, 0, 5, 0, 10 } +}; +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 5 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling5[48][9] = { +/* 7: 0, 1, 2, */ { 2, 8, 3, 2, 10, 8, 10, 9, 8 }, +/* 11: 0, 1, 3, */ { 1, 11, 2, 1, 9, 11, 9, 8, 11 }, +/* 19: 0, 1, 4, */ { 4, 1, 9, 4, 7, 1, 7, 3, 1 }, +/* 35: 0, 1, 5, */ { 8, 5, 4, 8, 3, 5, 3, 1, 5 }, +/* 13: 0, 2, 3, */ { 0, 10, 1, 0, 8, 10, 8, 11, 10 }, +/* 25: 0, 3, 4, */ { 11, 4, 7, 11, 2, 4, 2, 0, 4 }, +/* 137: 0, 3, 7, */ { 7, 0, 8, 7, 6, 0, 6, 2, 0 }, +/* 49: 0, 4, 5, */ { 9, 3, 0, 9, 5, 3, 5, 7, 3 }, +/* 145: 0, 4, 7, */ { 3, 6, 11, 3, 0, 6, 0, 4, 6 }, +/* 14: 1, 2, 3, */ { 3, 9, 0, 3, 11, 9, 11, 10, 9 }, +/* 38: 1, 2, 5, */ { 5, 2, 10, 5, 4, 2, 4, 0, 2 }, +/* 70: 1, 2, 6, */ { 9, 6, 5, 9, 0, 6, 0, 2, 6 }, +/* 50: 1, 4, 5, */ { 0, 7, 8, 0, 1, 7, 1, 5, 7 }, +/* 98: 1, 5, 6, */ { 10, 0, 1, 10, 6, 0, 6, 4, 0 }, +/* 76: 2, 3, 6, */ { 6, 3, 11, 6, 5, 3, 5, 1, 3 }, +/* 140: 2, 3, 7, */ { 10, 7, 6, 10, 1, 7, 1, 3, 7 }, +/* 100: 2, 5, 6, */ { 1, 4, 9, 1, 2, 4, 2, 6, 4 }, +/* 196: 2, 6, 7, */ { 11, 1, 2, 11, 7, 1, 7, 5, 1 }, +/* 152: 3, 4, 7, */ { 8, 2, 3, 8, 4, 2, 4, 6, 2 }, +/* 200: 3, 6, 7, */ { 2, 5, 10, 2, 3, 5, 3, 7, 5 }, +/* 112: 4, 5, 6, */ { 7, 10, 6, 7, 8, 10, 8, 9, 10 }, +/* 176: 4, 5, 7, */ { 6, 9, 5, 6, 11, 9, 11, 8, 9 }, +/* 208: 4, 6, 7, */ { 5, 8, 4, 5, 10, 8, 10, 11, 8 }, +/* 224: 5, 6, 7, */ { 4, 11, 7, 4, 9, 11, 9, 10, 11 }, +/* 31: 0, 1, 2, 3, 4, */ { 4, 7, 11, 4, 11, 9, 9, 11, 10 }, +/* 47: 0, 1, 2, 3, 5, */ { 5, 4, 8, 5, 8, 10, 10, 8, 11 }, +/* 79: 0, 1, 2, 3, 6, */ { 6, 5, 9, 6, 9, 11, 11, 9, 8 }, +/* 143: 0, 1, 2, 3, 7, */ { 7, 6, 10, 7, 10, 8, 8, 10, 9 }, +/* 55: 0, 1, 2, 4, 5, */ { 2, 10, 5, 2, 5, 3, 3, 5, 7 }, +/* 103: 0, 1, 2, 5, 6, */ { 8, 3, 2, 8, 2, 4, 4, 2, 6 }, +/* 59: 0, 1, 3, 4, 5, */ { 11, 2, 1, 11, 1, 7, 7, 1, 5 }, +/* 155: 0, 1, 3, 4, 7, */ { 1, 9, 4, 1, 4, 2, 2, 4, 6 }, +/* 115: 0, 1, 4, 5, 6, */ { 10, 6, 7, 10, 7, 1, 1, 7, 3 }, +/* 179: 0, 1, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 5, 3, 1 }, +/* 157: 0, 2, 3, 4, 7, */ { 10, 1, 0, 10, 0, 6, 6, 0, 4 }, +/* 205: 0, 2, 3, 6, 7, */ { 0, 8, 7, 0, 7, 1, 1, 7, 5 }, +/* 185: 0, 3, 4, 5, 7, */ { 9, 5, 6, 9, 6, 0, 0, 6, 2 }, +/* 217: 0, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 4, 2, 0 }, +/* 241: 0, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 11, 9, 10 }, +/* 110: 1, 2, 3, 5, 6, */ { 3, 11, 6, 3, 6, 0, 0, 6, 4 }, +/* 206: 1, 2, 3, 6, 7, */ { 9, 0, 3, 9, 3, 5, 5, 3, 7 }, +/* 118: 1, 2, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 6, 0, 2 }, +/* 230: 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 2, 4, 0 }, +/* 242: 1, 4, 5, 6, 7, */ { 0, 1, 10, 0, 10, 8, 8, 10, 11 }, +/* 220: 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 3, 5, 1 }, +/* 236: 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 7, 1, 3 }, +/* 244: 2, 4, 5, 6, 7, */ { 1, 2, 11, 1, 11, 9, 9, 11, 8 }, +/* 248: 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 10, 8, 9 } +}; +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +/** + * \brief test table for case 6 + * 1 face to test + eventually the interior + * When the test on the specified face is positive : 5 first triangles + * When the test on the specified face is negative : + * - if the test on the interior is negative : 3 middle triangles + * - if the test on the interior is positive : 8 last triangles + * The support edge for the interior test is marked as the 3rd column. + * + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char test6[48][3] = { +/* 67: 0, 1, 6, */ { 2, 7, 10 }, +/* 131: 0, 1, 7, */ { 4, 7, 11 }, +/* 21: 0, 2, 4, */ { 5, 7, 1 }, +/* 69: 0, 2, 6, */ { 5, 7, 3 }, +/* 41: 0, 3, 5, */ { 1, 7, 9 }, +/* 73: 0, 3, 6, */ { 3, 7, 10 }, +/* 81: 0, 4, 6, */ { 6, 7, 5 }, +/* 97: 0, 5, 6, */ { 1, 7, 8 }, +/* 193: 0, 6, 7, */ { 4, 7, 8 }, +/* 22: 1, 2, 4, */ { 1, 7, 8 }, +/* 134: 1, 2, 7, */ { 3, 7, 11 }, +/* 42: 1, 3, 5, */ { 5, 7, 2 }, +/* 138: 1, 3, 7, */ { 5, 7, 0 }, +/* 146: 1, 4, 7, */ { 1, 7, 9 }, +/* 162: 1, 5, 7, */ { 6, 7, 6 }, +/* 194: 1, 6, 7, */ { 2, 7, 9 }, +/* 28: 2, 3, 4, */ { 4, 7, 8 }, +/* 44: 2, 3, 5, */ { 2, 7, 9 }, +/* 52: 2, 4, 5, */ { 2, 7, 10 }, +/* 84: 2, 4, 6, */ { 6, 7, 7 }, +/* 148: 2, 4, 7, */ { 3, 7, 10 }, +/* 56: 3, 4, 5, */ { 4, 7, 11 }, +/* 104: 3, 5, 6, */ { 3, 7, 11 }, +/* 168: 3, 5, 7, */ { 6, 7, 4 }, +/* 87: 0, 1, 2, 4, 6, */ { -6, -7, 4 }, +/* 151: 0, 1, 2, 4, 7, */ { -3, -7, 11 }, +/* 199: 0, 1, 2, 6, 7, */ { -4, -7, 11 }, +/* 107: 0, 1, 3, 5, 6, */ { -3, -7, 10 }, +/* 171: 0, 1, 3, 5, 7, */ { -6, -7, 7 }, +/* 203: 0, 1, 3, 6, 7, */ { -2, -7, 10 }, +/* 211: 0, 1, 4, 6, 7, */ { -2, -7, 9 }, +/* 227: 0, 1, 5, 6, 7, */ { -4, -7, 8 }, +/* 61: 0, 2, 3, 4, 5, */ { -2, -7, 9 }, +/* 93: 0, 2, 3, 4, 6, */ { -6, -7, 6 }, +/* 109: 0, 2, 3, 5, 6, */ { -1, -7, 9 }, +/* 117: 0, 2, 4, 5, 6, */ { -5, -7, 0 }, +/* 213: 0, 2, 4, 6, 7, */ { -5, -7, 2 }, +/* 121: 0, 3, 4, 5, 6, */ { -3, -7, 11 }, +/* 233: 0, 3, 5, 6, 7, */ { -1, -7, 8 }, +/* 62: 1, 2, 3, 4, 5, */ { -4, -7, 8 }, +/* 158: 1, 2, 3, 4, 7, */ { -1, -7, 8 }, +/* 174: 1, 2, 3, 5, 7, */ { -6, -7, 5 }, +/* 182: 1, 2, 4, 5, 7, */ { -3, -7, 10 }, +/* 214: 1, 2, 4, 6, 7, */ { -1, -7, 9 }, +/* 186: 1, 3, 4, 5, 7, */ { -5, -7, 3 }, +/* 234: 1, 3, 5, 6, 7, */ { -5, -7, 1 }, +/* 124: 2, 3, 4, 5, 6, */ { -4, -7, 11 }, +/* 188: 2, 3, 4, 5, 7, */ { -2, -7, 10 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 6.1.1 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling6_1_1[48][9] = { +/* 67: 0, 1, 6, */ { 6, 5, 10, 3, 1, 8, 9, 8, 1 }, +/* 131: 0, 1, 7, */ { 11, 7, 6, 9, 3, 1, 3, 9, 8 }, +/* 21: 0, 2, 4, */ { 1, 2, 10, 7, 0, 4, 0, 7, 3 }, +/* 69: 0, 2, 6, */ { 3, 0, 8, 5, 2, 6, 2, 5, 1 }, +/* 41: 0, 3, 5, */ { 5, 4, 9, 2, 0, 11, 8, 11, 0 }, +/* 73: 0, 3, 6, */ { 10, 6, 5, 8, 2, 0, 2, 8, 11 }, +/* 81: 0, 4, 6, */ { 10, 6, 5, 0, 4, 3, 7, 3, 4 }, +/* 97: 0, 5, 6, */ { 3, 0, 8, 6, 4, 10, 9, 10, 4 }, +/* 193: 0, 6, 7, */ { 8, 3, 0, 10, 7, 5, 7, 10, 11 }, +/* 22: 1, 2, 4, */ { 8, 4, 7, 10, 0, 2, 0, 10, 9 }, +/* 134: 1, 2, 7, */ { 7, 6, 11, 0, 2, 9, 10, 9, 2 }, +/* 42: 1, 3, 5, */ { 2, 3, 11, 4, 1, 5, 1, 4, 0 }, +/* 138: 1, 3, 7, */ { 0, 1, 9, 6, 3, 7, 3, 6, 2 }, +/* 146: 1, 4, 7, */ { 9, 0, 1, 11, 4, 6, 4, 11, 8 }, +/* 162: 1, 5, 7, */ { 11, 7, 6, 1, 5, 0, 4, 0, 5 }, +/* 194: 1, 6, 7, */ { 0, 1, 9, 7, 5, 11, 10, 11, 5 }, +/* 28: 2, 3, 4, */ { 4, 7, 8, 1, 3, 10, 11, 10, 3 }, +/* 44: 2, 3, 5, */ { 9, 5, 4, 11, 1, 3, 1, 11, 10 }, +/* 52: 2, 4, 5, */ { 10, 1, 2, 8, 5, 7, 5, 8, 9 }, +/* 84: 2, 4, 6, */ { 8, 4, 7, 2, 6, 1, 5, 1, 6 }, +/* 148: 2, 4, 7, */ { 1, 2, 10, 4, 6, 8, 11, 8, 6 }, +/* 56: 3, 4, 5, */ { 2, 3, 11, 5, 7, 9, 8, 9, 7 }, +/* 104: 3, 5, 6, */ { 11, 2, 3, 9, 6, 4, 6, 9, 10 }, +/* 168: 3, 5, 7, */ { 9, 5, 4, 3, 7, 2, 6, 2, 7 }, +/* 87: 0, 1, 2, 4, 6, */ { 4, 5, 9, 2, 7, 3, 7, 2, 6 }, +/* 151: 0, 1, 2, 4, 7, */ { 3, 2, 11, 4, 6, 9, 10, 9, 6 }, +/* 199: 0, 1, 2, 6, 7, */ { 11, 3, 2, 9, 7, 5, 7, 9, 8 }, +/* 107: 0, 1, 3, 5, 6, */ { 10, 2, 1, 8, 6, 4, 6, 8, 11 }, +/* 171: 0, 1, 3, 5, 7, */ { 7, 4, 8, 1, 6, 2, 6, 1, 5 }, +/* 203: 0, 1, 3, 6, 7, */ { 2, 1, 10, 7, 5, 8, 9, 8, 5 }, +/* 211: 0, 1, 4, 6, 7, */ { 4, 5, 9, 3, 1, 11, 10, 11, 1 }, +/* 227: 0, 1, 5, 6, 7, */ { 8, 7, 4, 10, 3, 1, 3, 10, 11 }, +/* 61: 0, 2, 3, 4, 5, */ { 9, 1, 0, 11, 5, 7, 5, 11, 10 }, +/* 93: 0, 2, 3, 4, 6, */ { 6, 7, 11, 0, 5, 1, 5, 0, 4 }, +/* 109: 0, 2, 3, 5, 6, */ { 1, 0, 9, 6, 4, 11, 8, 11, 4 }, +/* 117: 0, 2, 4, 5, 6, */ { 9, 1, 0, 7, 3, 6, 2, 6, 3 }, +/* 213: 0, 2, 4, 6, 7, */ { 11, 3, 2, 5, 1, 4, 0, 4, 1 }, +/* 121: 0, 3, 4, 5, 6, */ { 11, 6, 7, 9, 2, 0, 2, 9, 10 }, +/* 233: 0, 3, 5, 6, 7, */ { 7, 4, 8, 2, 0, 10, 9, 10, 0 }, +/* 62: 1, 2, 3, 4, 5, */ { 0, 3, 8, 5, 7, 10, 11, 10, 7 }, +/* 158: 1, 2, 3, 4, 7, */ { 8, 0, 3, 10, 4, 6, 4, 10, 9 }, +/* 174: 1, 2, 3, 5, 7, */ { 5, 6, 10, 3, 4, 0, 4, 3, 7 }, +/* 182: 1, 2, 4, 5, 7, */ { 5, 6, 10, 0, 2, 8, 11, 8, 2 }, +/* 214: 1, 2, 4, 6, 7, */ { 9, 4, 5, 11, 0, 2, 0, 11, 8 }, +/* 186: 1, 3, 4, 5, 7, */ { 8, 0, 3, 6, 2, 5, 1, 5, 2 }, +/* 234: 1, 3, 5, 6, 7, */ { 10, 2, 1, 4, 0, 7, 3, 7, 0 }, +/* 124: 2, 3, 4, 5, 6, */ { 6, 7, 11, 1, 3, 9, 8, 9, 3 }, +/* 188: 2, 3, 4, 5, 7, */ { 10, 5, 6, 8, 1, 3, 1, 8, 9 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 6.1.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling6_1_2[48][27] = { + /* 67: 0, 1, 6, */ { 1, 12, 3, 12, 10, 3, 6, 3, 10, 3, 6, 8, 5, 8, 6, 8, 5, 12, 12, 9, 8, 1, 9, 12, 12, 5, 10 }, + /* 131: 0, 1, 7, */ { 1, 12, 3, 1, 11, 12, 11, 1, 6, 9, 6, 1, 6, 9, 7, 12, 7, 9, 9, 8, 12, 12, 8, 3, 11, 7, 12 }, + /* 21: 0, 2, 4, */ { 4, 12, 0, 4, 1, 12, 1, 4, 10, 7, 10, 4, 10, 7, 2, 12, 2, 7, 7, 3, 12, 12, 3, 0, 1, 2, 12 }, + /* 69: 0, 2, 6, */ { 6, 12, 2, 6, 3, 12, 3, 6, 8, 5, 8, 6, 8, 5, 0, 12, 0, 5, 5, 1, 12, 12, 1, 2, 3, 0, 12 }, + /* 41: 0, 3, 5, */ { 0, 12, 2, 12, 9, 2, 5, 2, 9, 2, 5, 11, 4, 11, 5, 11, 4, 12, 12, 8, 11, 0, 8, 12, 12, 4, 9 }, + /* 73: 0, 3, 6, */ { 0, 12, 2, 0, 10, 12, 10, 0, 5, 8, 5, 0, 5, 8, 6, 12, 6, 8, 8, 11, 12, 12, 11, 2, 10, 6, 12 }, + /* 81: 0, 4, 6, */ { 4, 12, 0, 12, 5, 0, 10, 0, 5, 0, 10, 3, 6, 3, 10, 3, 6, 12, 12, 7, 3, 4, 7, 12, 12, 6, 5 }, + /* 97: 0, 5, 6, */ { 4, 12, 6, 12, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 12, 12, 9, 10, 4, 9, 12, 12, 0, 8 }, + /* 193: 0, 6, 7, */ { 5, 12, 7, 5, 8, 12, 8, 5, 0, 10, 0, 5, 0, 10, 3, 12, 3, 10, 10, 11, 12, 12, 11, 7, 8, 3, 12 }, + /* 22: 1, 2, 4, */ { 2, 12, 0, 2, 8, 12, 8, 2, 7, 10, 7, 2, 7, 10, 4, 12, 4, 10, 10, 9, 12, 12, 9, 0, 8, 4, 12 }, + /* 134: 1, 2, 7, */ { 2, 12, 0, 12, 11, 0, 7, 0, 11, 0, 7, 9, 6, 9, 7, 9, 6, 12, 12, 10, 9, 2, 10, 12, 12, 6, 11 }, + /* 42: 1, 3, 5, */ { 5, 12, 1, 5, 2, 12, 2, 5, 11, 4, 11, 5, 11, 4, 3, 12, 3, 4, 4, 0, 12, 12, 0, 1, 2, 3, 12 }, + /* 138: 1, 3, 7, */ { 7, 12, 3, 7, 0, 12, 0, 7, 9, 6, 9, 7, 9, 6, 1, 12, 1, 6, 6, 2, 12, 12, 2, 3, 0, 1, 12 }, + /* 146: 1, 4, 7, */ { 6, 12, 4, 6, 9, 12, 9, 6, 1, 11, 1, 6, 1, 11, 0, 12, 0, 11, 11, 8, 12, 12, 8, 4, 9, 0, 12 }, + /* 162: 1, 5, 7, */ { 5, 12, 1, 12, 6, 1, 11, 1, 6, 1, 11, 0, 7, 0, 11, 0, 7, 12, 12, 4, 0, 5, 4, 12, 12, 7, 6 }, + /* 194: 1, 6, 7, */ { 5, 12, 7, 12, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 12, 12, 10, 11, 5, 10, 12, 12, 1, 9 }, + /* 28: 2, 3, 4, */ { 3, 12, 1, 12, 8, 1, 4, 1, 8, 1, 4, 10, 7, 10, 4, 10, 7, 12, 12, 11, 10, 3, 11, 12, 12, 7, 8 }, + /* 44: 2, 3, 5, */ { 3, 12, 1, 3, 9, 12, 9, 3, 4, 11, 4, 3, 4, 11, 5, 12, 5, 11, 11, 10, 12, 12, 10, 1, 9, 5, 12 }, + /* 52: 2, 4, 5, */ { 7, 12, 5, 7, 10, 12, 10, 7, 2, 8, 2, 7, 2, 8, 1, 12, 1, 8, 8, 9, 12, 12, 9, 5, 10, 1, 12 }, + /* 84: 2, 4, 6, */ { 6, 12, 2, 12, 7, 2, 8, 2, 7, 2, 8, 1, 4, 1, 8, 1, 4, 12, 12, 5, 1, 6, 5, 12, 12, 4, 7 }, + /* 148: 2, 4, 7, */ { 6, 12, 4, 12, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 12, 12, 11, 8, 6, 11, 12, 12, 2, 10 }, + /* 56: 3, 4, 5, */ { 7, 12, 5, 12, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 12, 12, 8, 9, 7, 8, 12, 12, 3, 11 }, + /* 104: 3, 5, 6, */ { 4, 12, 6, 4, 11, 12, 11, 4, 3, 9, 3, 4, 3, 9, 2, 12, 2, 9, 9, 10, 12, 12, 10, 6, 11, 2, 12 }, + /* 168: 3, 5, 7, */ { 7, 12, 3, 12, 4, 3, 9, 3, 4, 3, 9, 2, 5, 2, 9, 2, 5, 12, 12, 6, 2, 7, 6, 12, 12, 5, 4 }, + /* 87: 0, 1, 2, 4, 6, */ { 3, 12, 7, 3, 4, 12, 4, 3, 9, 2, 9, 3, 9, 2, 5, 12, 5, 2, 2, 6, 12, 12, 6, 7, 4, 5, 12 }, + /* 151: 0, 1, 2, 4, 7, */ { 6, 12, 4, 12, 11, 4, 3, 4, 11, 4, 3, 9, 2, 9, 3, 9, 2, 12, 12, 10, 9, 6, 10, 12, 12, 2, 11 }, + /* 199: 0, 1, 2, 6, 7, */ { 5, 12, 7, 5, 11, 12, 11, 5, 2, 9, 2, 5, 2, 9, 3, 12, 3, 9, 9, 8, 12, 12, 8, 7, 11, 3, 12 }, + /* 107: 0, 1, 3, 5, 6, */ { 4, 12, 6, 4, 10, 12, 10, 4, 1, 8, 1, 4, 1, 8, 2, 12, 2, 8, 8, 11, 12, 12, 11, 6, 10, 2, 12 }, + /* 171: 0, 1, 3, 5, 7, */ { 2, 12, 6, 2, 7, 12, 7, 2, 8, 1, 8, 2, 8, 1, 4, 12, 4, 1, 1, 5, 12, 12, 5, 6, 7, 4, 12 }, + /* 203: 0, 1, 3, 6, 7, */ { 5, 12, 7, 12, 10, 7, 2, 7, 10, 7, 2, 8, 1, 8, 2, 8, 1, 12, 12, 9, 8, 5, 9, 12, 12, 1, 10 }, + /* 211: 0, 1, 4, 6, 7, */ { 1, 12, 3, 12, 9, 3, 4, 3, 9, 3, 4, 11, 5, 11, 4, 11, 5, 12, 12, 10, 11, 1, 10, 12, 12, 5, 9 }, + /* 227: 0, 1, 5, 6, 7, */ { 1, 12, 3, 1, 8, 12, 8, 1, 4, 10, 4, 1, 4, 10, 7, 12, 7, 10, 10, 11, 12, 12, 11, 3, 8, 7, 12 }, + /* 61: 0, 2, 3, 4, 5, */ { 7, 12, 5, 7, 9, 12, 9, 7, 0, 11, 0, 7, 0, 11, 1, 12, 1, 11, 11, 10, 12, 12, 10, 5, 9, 1, 12 }, + /* 93: 0, 2, 3, 4, 6, */ { 1, 12, 5, 1, 6, 12, 6, 1, 11, 0, 11, 1, 11, 0, 7, 12, 7, 0, 0, 4, 12, 12, 4, 5, 6, 7, 12 }, + /* 109: 0, 2, 3, 5, 6, */ { 4, 12, 6, 12, 9, 6, 1, 6, 9, 6, 1, 11, 0, 11, 1, 11, 0, 12, 12, 8, 11, 4, 8, 12, 12, 0, 9 }, + /* 117: 0, 2, 4, 5, 6, */ { 3, 12, 7, 12, 0, 7, 9, 7, 0, 7, 9, 6, 1, 6, 9, 6, 1, 12, 12, 2, 6, 3, 2, 12, 12, 1, 0 }, + /* 213: 0, 2, 4, 6, 7, */ { 1, 12, 5, 12, 2, 5, 11, 5, 2, 5, 11, 4, 3, 4, 11, 4, 3, 12, 12, 0, 4, 1, 0, 12, 12, 3, 2 }, + /* 121: 0, 3, 4, 5, 6, */ { 0, 12, 2, 0, 11, 12, 11, 0, 7, 9, 7, 0, 7, 9, 6, 12, 6, 9, 9, 10, 12, 12, 10, 2, 11, 6, 12 }, + /* 233: 0, 3, 5, 6, 7, */ { 0, 12, 2, 12, 8, 2, 7, 2, 8, 2, 7, 10, 4, 10, 7, 10, 4, 12, 12, 9, 10, 0, 9, 12, 12, 4, 8 }, + /* 62: 1, 2, 3, 4, 5, */ { 7, 12, 5, 12, 8, 5, 0, 5, 8, 5, 0, 10, 3, 10, 0, 10, 3, 12, 12, 11, 10, 7, 11, 12, 12, 3, 8 }, + /* 158: 1, 2, 3, 4, 7, */ { 6, 12, 4, 6, 8, 12, 8, 6, 3, 10, 3, 6, 3, 10, 0, 12, 0, 10, 10, 9, 12, 12, 9, 4, 8, 0, 12 }, + /* 174: 1, 2, 3, 5, 7, */ { 0, 12, 4, 0, 5, 12, 5, 0, 10, 3, 10, 0, 10, 3, 6, 12, 6, 3, 3, 7, 12, 12, 7, 4, 5, 6, 12 }, + /* 182: 1, 2, 4, 5, 7, */ { 2, 12, 0, 12, 10, 0, 5, 0, 10, 0, 5, 8, 6, 8, 5, 8, 6, 12, 12, 11, 8, 2, 11, 12, 12, 6, 10 }, + /* 214: 1, 2, 4, 6, 7, */ { 2, 12, 0, 2, 9, 12, 9, 2, 5, 11, 5, 2, 5, 11, 4, 12, 4, 11, 11, 8, 12, 12, 8, 0, 9, 4, 12 }, + /* 186: 1, 3, 4, 5, 7, */ { 2, 12, 6, 12, 3, 6, 8, 6, 3, 6, 8, 5, 0, 5, 8, 5, 0, 12, 12, 1, 5, 2, 1, 12, 12, 0, 3 }, + /* 234: 1, 3, 5, 6, 7, */ { 0, 12, 4, 12, 1, 4, 10, 4, 1, 4, 10, 7, 2, 7, 10, 7, 2, 12, 12, 3, 7, 0, 3, 12, 12, 2, 1 }, + /* 124: 2, 3, 4, 5, 6, */ { 3, 12, 1, 12, 11, 1, 6, 1, 11, 1, 6, 9, 7, 9, 6, 9, 7, 12, 12, 8, 9, 3, 8, 12, 12, 7, 11 }, + /* 188: 2, 3, 4, 5, 7, */ { 3, 12, 1, 3, 10, 12, 10, 3, 6, 8, 6, 3, 6, 8, 5, 12, 5, 8, 8, 9, 12, 12, 9, 1, 10, 5, 12 }, +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 6.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling6_2[48][15] = { +/* 67: 0, 1, 6, */ { 1, 10, 3, 6, 3, 10, 3, 6, 8, 5, 8, 6, 8, 5, 9 }, +/* 131: 0, 1, 7, */ { 1, 11, 3, 11, 1, 6, 9, 6, 1, 6, 9, 7, 8, 7, 9 }, +/* 21: 0, 2, 4, */ { 4, 1, 0, 1, 4, 10, 7, 10, 4, 10, 7, 2, 3, 2, 7 }, +/* 69: 0, 2, 6, */ { 6, 3, 2, 3, 6, 8, 5, 8, 6, 8, 5, 0, 1, 0, 5 }, +/* 41: 0, 3, 5, */ { 0, 9, 2, 5, 2, 9, 2, 5, 11, 4, 11, 5, 11, 4, 8 }, +/* 73: 0, 3, 6, */ { 0, 10, 2, 10, 0, 5, 8, 5, 0, 5, 8, 6, 11, 6, 8 }, +/* 81: 0, 4, 6, */ { 4, 5, 0, 10, 0, 5, 0, 10, 3, 6, 3, 10, 3, 6, 7 }, +/* 97: 0, 5, 6, */ { 4, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 9 }, +/* 193: 0, 6, 7, */ { 5, 8, 7, 8, 5, 0, 10, 0, 5, 0, 10, 3, 11, 3, 10 }, +/* 22: 1, 2, 4, */ { 2, 8, 0, 8, 2, 7, 10, 7, 2, 7, 10, 4, 9, 4, 10 }, +/* 134: 1, 2, 7, */ { 2, 11, 0, 7, 0, 11, 0, 7, 9, 6, 9, 7, 9, 6, 10 }, +/* 42: 1, 3, 5, */ { 5, 2, 1, 2, 5, 11, 4, 11, 5, 11, 4, 3, 0, 3, 4 }, +/* 138: 1, 3, 7, */ { 7, 0, 3, 0, 7, 9, 6, 9, 7, 9, 6, 1, 2, 1, 6 }, +/* 146: 1, 4, 7, */ { 6, 9, 4, 9, 6, 1, 11, 1, 6, 1, 11, 0, 8, 0, 11 }, +/* 162: 1, 5, 7, */ { 5, 6, 1, 11, 1, 6, 1, 11, 0, 7, 0, 11, 0, 7, 4 }, +/* 194: 1, 6, 7, */ { 5, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 10 }, +/* 28: 2, 3, 4, */ { 3, 8, 1, 4, 1, 8, 1, 4, 10, 7, 10, 4, 10, 7, 11 }, +/* 44: 2, 3, 5, */ { 3, 9, 1, 9, 3, 4, 11, 4, 3, 4, 11, 5, 10, 5, 11 }, +/* 52: 2, 4, 5, */ { 7, 10, 5, 10, 7, 2, 8, 2, 7, 2, 8, 1, 9, 1, 8 }, +/* 84: 2, 4, 6, */ { 6, 7, 2, 8, 2, 7, 2, 8, 1, 4, 1, 8, 1, 4, 5 }, +/* 148: 2, 4, 7, */ { 6, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 11 }, +/* 56: 3, 4, 5, */ { 7, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 8 }, +/* 104: 3, 5, 6, */ { 4, 11, 6, 11, 4, 3, 9, 3, 4, 3, 9, 2, 10, 2, 9 }, +/* 168: 3, 5, 7, */ { 7, 4, 3, 9, 3, 4, 3, 9, 2, 5, 2, 9, 2, 5, 6 }, +/* 87: 0, 1, 2, 4, 6, */ { 3, 4, 7, 4, 3, 9, 2, 9, 3, 9, 2, 5, 6, 5, 2 }, +/* 151: 0, 1, 2, 4, 7, */ { 6, 11, 4, 3, 4, 11, 4, 3, 9, 2, 9, 3, 9, 2, 10 }, +/* 199: 0, 1, 2, 6, 7, */ { 5, 11, 7, 11, 5, 2, 9, 2, 5, 2, 9, 3, 8, 3, 9 }, +/* 107: 0, 1, 3, 5, 6, */ { 4, 10, 6, 10, 4, 1, 8, 1, 4, 1, 8, 2, 11, 2, 8 }, +/* 171: 0, 1, 3, 5, 7, */ { 2, 7, 6, 7, 2, 8, 1, 8, 2, 8, 1, 4, 5, 4, 1 }, +/* 203: 0, 1, 3, 6, 7, */ { 5, 10, 7, 2, 7, 10, 7, 2, 8, 1, 8, 2, 8, 1, 9 }, +/* 211: 0, 1, 4, 6, 7, */ { 1, 9, 3, 4, 3, 9, 3, 4, 11, 5, 11, 4, 11, 5, 10 }, +/* 227: 0, 1, 5, 6, 7, */ { 1, 8, 3, 8, 1, 4, 10, 4, 1, 4, 10, 7, 11, 7, 10 }, +/* 61: 0, 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 0, 11, 0, 7, 0, 11, 1, 10, 1, 11 }, +/* 93: 0, 2, 3, 4, 6, */ { 1, 6, 5, 6, 1, 11, 0, 11, 1, 11, 0, 7, 4, 7, 0 }, +/* 109: 0, 2, 3, 5, 6, */ { 4, 9, 6, 1, 6, 9, 6, 1, 11, 0, 11, 1, 11, 0, 8 }, +/* 117: 0, 2, 4, 5, 6, */ { 3, 0, 7, 9, 7, 0, 7, 9, 6, 1, 6, 9, 6, 1, 2 }, +/* 213: 0, 2, 4, 6, 7, */ { 1, 2, 5, 11, 5, 2, 5, 11, 4, 3, 4, 11, 4, 3, 0 }, +/* 121: 0, 3, 4, 5, 6, */ { 0, 11, 2, 11, 0, 7, 9, 7, 0, 7, 9, 6, 10, 6, 9 }, +/* 233: 0, 3, 5, 6, 7, */ { 0, 8, 2, 7, 2, 8, 2, 7, 10, 4, 10, 7, 10, 4, 9 }, +/* 62: 1, 2, 3, 4, 5, */ { 7, 8, 5, 0, 5, 8, 5, 0, 10, 3, 10, 0, 10, 3, 11 }, +/* 158: 1, 2, 3, 4, 7, */ { 6, 8, 4, 8, 6, 3, 10, 3, 6, 3, 10, 0, 9, 0, 10 }, +/* 174: 1, 2, 3, 5, 7, */ { 0, 5, 4, 5, 0, 10, 3, 10, 0, 10, 3, 6, 7, 6, 3 }, +/* 182: 1, 2, 4, 5, 7, */ { 2, 10, 0, 5, 0, 10, 0, 5, 8, 6, 8, 5, 8, 6, 11 }, +/* 214: 1, 2, 4, 6, 7, */ { 2, 9, 0, 9, 2, 5, 11, 5, 2, 5, 11, 4, 8, 4, 11 }, +/* 186: 1, 3, 4, 5, 7, */ { 2, 3, 6, 8, 6, 3, 6, 8, 5, 0, 5, 8, 5, 0, 1 }, +/* 234: 1, 3, 5, 6, 7, */ { 0, 1, 4, 10, 4, 1, 4, 10, 7, 2, 7, 10, 7, 2, 3 }, +/* 124: 2, 3, 4, 5, 6, */ { 3, 11, 1, 6, 1, 11, 1, 6, 9, 7, 9, 6, 9, 7, 8 }, +/* 188: 2, 3, 4, 5, 7, */ { 3, 10, 1, 10, 3, 6, 8, 6, 3, 6, 8, 5, 9, 5, 8 } +}; +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +/** + * \brief test table for case 7 + * 3 faces to test + eventually the interior + * When the tests on the 3 specified faces are positive : + * - if the test on the interior is positive : 5 first triangles + * - if the test on the interior is negative : 9 next triangles + * When the tests on the first and the second specified faces are positive : 9 next triangles + * When the tests on the first and the third specified faces are positive : 9 next triangles + * When the tests on the second and the third specified faces are positive : 9 next triangles + * When the test on the first specified face is positive : 5 next triangles + * When the test on the second specified face is positive : 5 next triangles + * When the test on the third specified face is positive : 5 next triangles + * When the tests on the 3 specified faces are negative : 3 last triangles + * The support edge for the interior test is marked as the 5th column. + * + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char test7[16][5] = { +/* 37: 0, 2, 5, */ { 1, 2, 5, 7, 1 }, +/* 133: 0, 2, 7, */ { 3, 4, 5, 7, 3 }, +/* 161: 0, 5, 7, */ { 4, 1, 6, 7, 4 }, +/* 26: 1, 3, 4, */ { 4, 1, 5, 7, 0 }, +/* 74: 1, 3, 6, */ { 2, 3, 5, 7, 2 }, +/* 82: 1, 4, 6, */ { 1, 2, 6, 7, 5 }, +/* 164: 2, 5, 7, */ { 2, 3, 6, 7, 6 }, +/* 88: 3, 4, 6, */ { 3, 4, 6, 7, 7 }, +/* 167: 0, 1, 2, 5, 7, */ { -3, -4, -6, -7, 7 }, +/* 91: 0, 1, 3, 4, 6, */ { -2, -3, -6, -7, 6 }, +/* 173: 0, 2, 3, 5, 7, */ { -1, -2, -6, -7, 5 }, +/* 181: 0, 2, 4, 5, 7, */ { -2, -3, -5, -7, 2 }, +/* 229: 0, 2, 5, 6, 7, */ { -4, -1, -5, -7, 0 }, +/* 94: 1, 2, 3, 4, 6, */ { -4, -1, -6, -7, 4 }, +/* 122: 1, 3, 4, 5, 6, */ { -3, -4, -5, -7, 3 }, +/* 218: 1, 3, 4, 6, 7, */ { -1, -2, -5, -7, 1 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 7.1 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling7_1[16][9] = { +/* 37: 0, 2, 5, */ { 9, 5, 4, 10, 1, 2, 8, 3, 0 }, +/* 133: 0, 2, 7, */ { 11, 7, 6, 8, 3, 0, 10, 1, 2 }, +/* 161: 0, 5, 7, */ { 3, 0, 8, 5, 4, 9, 7, 6, 11 }, +/* 26: 1, 3, 4, */ { 8, 4, 7, 9, 0, 1, 11, 2, 3 }, +/* 74: 1, 3, 6, */ { 10, 6, 5, 11, 2, 3, 9, 0, 1 }, +/* 82: 1, 4, 6, */ { 0, 1, 9, 6, 5, 10, 4, 7, 8 }, +/* 164: 2, 5, 7, */ { 1, 2, 10, 7, 6, 11, 5, 4, 9 }, +/* 88: 3, 4, 6, */ { 2, 3, 11, 4, 7, 8, 6, 5, 10 }, +/* 167: 0, 1, 2, 5, 7, */ { 11, 3, 2, 8, 7, 4, 10, 5, 6 }, +/* 91: 0, 1, 3, 4, 6, */ { 10, 2, 1, 11, 6, 7, 9, 4, 5 }, +/* 173: 0, 2, 3, 5, 7, */ { 9, 1, 0, 10, 5, 6, 8, 7, 4 }, +/* 181: 0, 2, 4, 5, 7, */ { 5, 6, 10, 3, 2, 11, 1, 0, 9 }, +/* 229: 0, 2, 5, 6, 7, */ { 7, 4, 8, 1, 0, 9, 3, 2, 11 }, +/* 94: 1, 2, 3, 4, 6, */ { 8, 0, 3, 9, 4, 5, 11, 6, 7 }, +/* 122: 1, 3, 4, 5, 6, */ { 6, 7, 11, 0, 3, 8, 2, 1, 10 }, +/* 218: 1, 3, 4, 6, 7, */ { 4, 5, 9, 2, 1, 10, 0, 3, 8 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 7.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling7_2[16][3][15] = { +/* 37: 0, 2, 5, */ { + /* 1,0 */ { 1, 2, 10, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 }, + /* 0,1 */ { 3, 0, 8, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 }, + /* 1,1 */ { 9, 5, 4, 0, 10, 1, 10, 0, 8, 10, 8, 2, 3, 2, 8 } +}, +/* 133: 0, 2, 7, */ { + /* 1,0 */ { 3, 0, 8, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 }, + /* 0,1 */ { 1, 2, 10, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 }, + /* 1,1 */ { 11, 7, 6, 2, 8, 3, 8, 2, 10, 8, 10, 0, 1, 0, 10 } +}, +/* 161: 0, 5, 7, */ { + /* 1,0 */ { 9, 5, 4, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 }, + /* 0,1 */ { 11, 7, 6, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 }, + /* 1,1 */ { 3, 0, 8, 4, 9, 7, 11, 7, 9, 5, 11, 9, 11, 5, 6 } +}, +/* 26: 1, 3, 4, */ { + /* 1,0 */ { 0, 1, 9, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 }, + /* 0,1 */ { 2, 3, 11, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 }, + /* 1,1 */ { 8, 4, 7, 3, 9, 0, 9, 3, 11, 9, 11, 1, 2, 1, 11 } +}, +/* 74: 1, 3, 6, */ { + /* 1,0 */ { 2, 3, 11, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 }, + /* 0,1 */ { 0, 1, 9, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 }, + /* 1,1 */ { 6, 5, 10, 1, 11, 2, 11, 1, 9, 11, 9, 3, 0, 3, 9 } +}, +/* 82: 1, 4, 6, */ { + /* 1,0 */ { 6, 5, 10, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 }, + /* 0,1 */ { 8, 4, 7, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 }, + /* 1,1 */ { 0, 1, 9, 5, 10, 4, 8, 4, 10, 6, 8, 10, 8, 6, 7 } +}, +/* 164: 2, 5, 7, */ { + /* 1,0 */ { 11, 7, 6, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 }, + /* 0,1 */ { 9, 5, 4, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 }, + /* 1,1 */ { 1, 2, 10, 6, 11, 5, 9, 5, 11, 7, 9, 11, 9, 7, 4 } +}, +/* 88: 3, 4, 6, */ { + /* 1,0 */ { 8, 4, 7, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 }, + /* 0,1 */ { 6, 5, 10, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 }, + /* 1,1 */ { 2, 3, 11, 7, 8, 6, 10, 6, 8, 4, 10, 8, 10, 4, 5 } +}, +/* 167: 0, 1, 2, 5, 7, */ { + /* 1,0 */ { 7, 4, 8, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 }, + /* 0,1 */ { 10, 5, 6, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 }, + /* 1,1 */ { 11, 3, 2, 6, 8, 7, 8, 6, 10, 8, 10, 4, 5, 4, 10 } +}, +/* 91: 0, 1, 3, 4, 6, */ { + /* 1,0 */ { 6, 7, 11, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 }, + /* 0,1 */ { 4, 5, 9, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 }, + /* 1,1 */ { 10, 2, 1, 5, 11, 6, 11, 5, 9, 11, 9, 7, 4, 7, 9 } +}, +/* 173: 0, 2, 3, 5, 7, */ { + /* 1,0 */ { 10, 5, 6, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 }, + /* 0,1 */ { 7, 4, 8, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 }, + /* 1,1 */ { 9, 1, 0, 4, 10, 5, 10, 4, 8, 10, 8, 6, 7, 6, 8 } +}, +/* 181: 0, 2, 4, 5, 7, */ { + /* 1,0 */ { 11, 3, 2, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 }, + /* 0,1 */ { 9, 1, 0, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 }, + /* 1,1 */ { 10, 5, 6, 2, 11, 1, 9, 1, 11, 3, 9, 11, 9, 3, 0 } +}, +/* 229: 0, 2, 5, 6, 7, */ { + /* 1,0 */ { 9, 1, 0, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 }, + /* 0,1 */ { 11, 3, 2, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 }, + /* 1,1 */ { 7, 4, 8, 0, 9, 3, 11, 3, 9, 1, 11, 9, 11, 1, 2 } +}, +/* 94: 1, 2, 3, 4, 6, */ { + /* 1,0 */ { 4, 5, 9, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 }, + /* 0,1 */ { 6, 7, 11, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 }, + /* 1,1 */ { 8, 0, 3, 7, 9, 4, 9, 7, 11, 9, 11, 5, 6, 5, 11 } +}, +/* 122: 1, 3, 4, 5, 6, */ { + /* 1,0 */ { 8, 0, 3, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 }, + /* 0,1 */ { 10, 2, 1, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 }, + /* 1,1 */ { 6, 7, 11, 3, 8, 2, 10, 2, 8, 0, 10, 8, 10, 0, 1 } +}, +/* 218: 1, 3, 4, 6, 7, */ { + /* 1,0 */ { 10, 2, 1, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 }, + /* 0,1 */ { 8, 0, 3, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 }, + /* 1,1 */ { 4, 5, 9, 1, 10, 0, 8, 0, 10, 2, 8, 10, 8, 2, 3 } } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 7.3 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling7_3[16][3][27] = { +/* 37: 0, 2, 5, */ { + /* 1,0 */ { 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 }, + /* 0,1 */ { 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 }, + /* 1,1 */ { 5, 4, 12, 10, 5, 12, 2, 10, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 } +}, +/* 133: 0, 2, 7, */ { + /* 1,0 */ { 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 }, + /* 0,1 */ { 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 }, + /* 1,1 */ { 7, 6, 12, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 } +}, +/* 161: 0, 5, 7, */ { + /* 1,0 */ { 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12 }, + /* 0,1 */ { 3, 0, 12, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12, 8, 7, 12, 0, 8, 12 }, + /* 1,1 */ { 12, 3, 0, 12, 0, 9, 12, 9, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 } +}, +/* 26: 1, 3, 4, */ { + /* 1,0 */ { 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 }, + /* 0,1 */ { 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 8, 12, 8, 4 }, + /* 1,1 */ { 4, 7, 12, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 8, 0, 12, 7, 8, 12 } +}, +/* 74: 1, 3, 6, */ { + /* 1,0 */ { 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 }, + /* 0,1 */ { 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 10, 12, 10, 6 }, + /* 1,1 */ { 6, 5, 12, 11, 6, 12, 3, 11, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12 } +}, +/* 82: 1, 4, 6, */ { + /* 1,0 */ { 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12 }, + /* 0,1 */ { 0, 1, 12, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12, 9, 4, 12, 1, 9, 12 }, + /* 1,1 */ { 12, 0, 1, 12, 1, 10, 12, 10, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 } +}, +/* 164: 2, 5, 7, */ { + /* 1,0 */ { 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12 }, + /* 0,1 */ { 1, 2, 12, 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 6, 11, 12, 5, 6, 12, 10, 5, 12, 2, 10, 12 }, + /* 1,1 */ { 12, 1, 2, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 } +}, +/* 88: 3, 4, 6, */ { + /* 1,0 */ { 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12 }, + /* 0,1 */ { 2, 3, 12, 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 7, 8, 12, 6, 7, 12, 11, 6, 12, 3, 11, 12 }, + /* 1,1 */ { 12, 2, 3, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 } +}, +/* 167: 0, 1, 2, 5, 7, */ { + /* 1,0 */ { 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4 }, + /* 0,1 */ { 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 7, 12, 7, 6, 12, 6, 11, 12, 11, 3 }, + /* 1,1 */ { 3, 2, 12, 8, 3, 12, 4, 8, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 } +}, +/* 91: 0, 1, 3, 4, 6, */ { + /* 1,0 */ { 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7 }, + /* 0,1 */ { 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 6, 12, 6, 5, 12, 5, 10, 12, 10, 2 }, + /* 1,1 */ { 2, 1, 12, 11, 2, 12, 7, 11, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 } +}, +/* 173: 0, 2, 3, 5, 7, */ { + /* 1,0 */ { 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6 }, + /* 0,1 */ { 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 5, 12, 5, 4, 12, 4, 9, 12, 9, 1 }, + /* 1,1 */ { 1, 0, 12, 10, 1, 12, 6, 10, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 } +}, +/* 181: 0, 2, 4, 5, 7, */ { + /* 1,0 */ { 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 }, + /* 0,1 */ { 5, 6, 12, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 10, 1, 12, 6, 10, 12 }, + /* 1,1 */ { 12, 5, 6, 12, 6, 11, 12, 11, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5 } +}, +/* 229: 0, 2, 5, 6, 7, */ { + /* 1,0 */ { 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 2, 11, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12 }, + /* 0,1 */ { 7, 4, 12, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 8, 3, 12, 4, 8, 12 }, + /* 1,1 */ { 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 8, 12, 8, 7 } +}, +/* 94: 1, 2, 3, 4, 6, */ { + /* 1,0 */ { 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5 }, + /* 0,1 */ { 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 4, 12, 4, 7, 12, 7, 8, 12, 8, 0 }, + /* 1,1 */ { 0, 3, 12, 9, 0, 12, 5, 9, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 } +}, +/* 122: 1, 3, 4, 5, 6, */ { + /* 1,0 */ { 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 }, + /* 0,1 */ { 6, 7, 12, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 }, + /* 1,1 */ { 12, 6, 7, 12, 7, 8, 12, 8, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 } +}, +/* 218: 1, 3, 4, 6, 7, */ { + /* 1,0 */ { 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12 }, + /* 0,1 */ { 4, 5, 12, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 }, + /* 1,1 */ { 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 } } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 7.4.1 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling7_4_1[16][15] = { +/* 37: 0, 2, 5, */ { 3, 4, 8, 4, 3, 10, 2, 10, 3, 4, 10, 5, 9, 1, 0 }, +/* 133: 0, 2, 7, */ { 1, 6, 10, 6, 1, 8, 0, 8, 1, 6, 8, 7, 11, 3, 2 }, +/* 161: 0, 5, 7, */ { 11, 3, 6, 9, 6, 3, 6, 9, 5, 0, 9, 3, 7, 4, 8 }, +/* 26: 1, 3, 4, */ { 2, 7, 11, 7, 2, 9, 1, 9, 2, 7, 9, 4, 8, 0, 3 }, +/* 74: 1, 3, 6, */ { 0, 5, 9, 5, 0, 11, 3, 11, 0, 5, 11, 6, 10, 2, 1 }, +/* 82: 1, 4, 6, */ { 8, 0, 7, 10, 7, 0, 7, 10, 6, 1, 10, 0, 4, 5, 9 }, +/* 164: 2, 5, 7, */ { 9, 1, 4, 11, 4, 1, 4, 11, 7, 2, 11, 1, 5, 6, 10 }, +/* 88: 3, 4, 6, */ { 10, 2, 5, 8, 5, 2, 5, 8, 4, 3, 8, 2, 6, 7, 11 }, +/* 167: 0, 1, 2, 5, 7, */ { 5, 2, 10, 2, 5, 8, 4, 8, 5, 2, 8, 3, 11, 7, 6 }, +/* 91: 0, 1, 3, 4, 6, */ { 4, 1, 9, 1, 4, 11, 7, 11, 4, 1, 11, 2, 10, 6, 5 }, +/* 173: 0, 2, 3, 5, 7, */ { 7, 0, 8, 0, 7, 10, 6, 10, 7, 0, 10, 1, 9, 5, 4 }, +/* 181: 0, 2, 4, 5, 7, */ { 9, 5, 0, 11, 0, 5, 0, 11, 3, 6, 11, 5, 1, 2, 10 }, +/* 229: 0, 2, 5, 6, 7, */ { 11, 7, 2, 9, 2, 7, 2, 9, 1, 4, 9, 7, 3, 0, 8 }, +/* 94: 1, 2, 3, 4, 6, */ { 6, 3, 11, 3, 6, 9, 5, 9, 6, 3, 9, 0, 8, 4, 7 }, +/* 122: 1, 3, 4, 5, 6, */ { 10, 6, 1, 8, 1, 6, 1, 8, 0, 7, 8, 6, 2, 3, 11 }, +/* 218: 1, 3, 4, 6, 7, */ { 8, 4, 3, 10, 3, 4, 3, 10, 2, 5, 10, 4, 0, 1, 9 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 7.4.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling7_4_2[16][27] = { +/* 37: 0, 2, 5, */ { 9, 4, 8, 4, 9, 5, 10, 5, 9, 1, 10, 9, 10, 1, 2, 0, 2, 1, 2, 0, 3, 8, 3, 0, 9, 8, 0 }, +/* 133: 0, 2, 7, */ { 11, 6, 10, 6, 11, 7, 8, 7, 11, 3, 8, 11, 8, 3, 0, 2, 0, 3, 0, 2, 1, 10, 1, 2, 11, 10, 2 }, +/* 161: 0, 5, 7, */ { 11, 3, 8, 0, 8, 3, 8, 0, 9, 8, 9, 4, 5, 4, 9, 4, 5, 7, 6, 7, 5, 7, 6, 11, 7, 11, 8 }, +/* 26: 1, 3, 4, */ { 8, 7, 11, 7, 8, 4, 9, 4, 8, 0, 9, 8, 9, 0, 1, 3, 1, 0, 1, 3, 2, 11, 2, 3, 8, 11, 3 }, +/* 74: 1, 3, 6, */ { 10, 5, 9, 5, 10, 6, 11, 6, 10, 2, 11, 10, 11, 2, 3, 1, 3, 2, 3, 1, 0, 9, 0, 1, 10, 9, 1 }, +/* 82: 1, 4, 6, */ { 8, 0, 9, 1, 9, 0, 9, 1, 10, 9, 10, 5, 6, 5, 10, 5, 6, 4, 7, 4, 6, 4, 7, 8, 4, 8, 9 }, +/* 164: 2, 5, 7, */ { 9, 1, 10, 2, 10, 1, 10, 2, 11, 10, 11, 6, 7, 6, 11, 6, 7, 5, 4, 5, 7, 5, 4, 9, 5, 9, 10 }, +/* 88: 3, 4, 6, */ { 10, 2, 11, 3, 11, 2, 11, 3, 8, 11, 8, 7, 4, 7, 8, 7, 4, 6, 5, 6, 4, 6, 5, 10, 6, 10, 11 }, +/* 167: 0, 1, 2, 5, 7, */ { 11, 2, 10, 2, 11, 3, 8, 3, 11, 7, 8, 11, 8, 7, 4, 6, 4, 7, 4, 6, 5, 10, 5, 6, 11, 10, 6 }, +/* 91: 0, 1, 3, 4, 6, */ { 10, 1, 9, 1, 10, 2, 11, 2, 10, 6, 11, 10, 11, 6, 7, 5, 7, 6, 7, 5, 4, 9, 4, 5, 10, 9, 5 }, +/* 173: 0, 2, 3, 5, 7, */ { 9, 0, 8, 0, 9, 1, 10, 1, 9, 5, 10, 9, 10, 5, 6, 4, 6, 5, 6, 4, 7, 8, 7, 4, 9, 8, 4 }, +/* 181: 0, 2, 4, 5, 7, */ { 9, 5, 10, 6, 10, 5, 10, 6, 11, 10, 11, 2, 3, 2, 11, 2, 3, 1, 0, 1, 3, 1, 0, 9, 1, 9, 10 }, +/* 229: 0, 2, 5, 6, 7, */ { 11, 7, 8, 4, 8, 7, 8, 4, 9, 8, 9, 0, 1, 0, 9, 0, 1, 3, 2, 3, 1, 3, 2, 11, 3, 11, 8 }, +/* 94: 1, 2, 3, 4, 6, */ { 8, 3, 11, 3, 8, 0, 9, 0, 8, 4, 9, 8, 9, 4, 5, 7, 5, 4, 5, 7, 6, 11, 6, 7, 8, 11, 7 }, +/* 122: 1, 3, 4, 5, 6, */ { 10, 6, 11, 7, 11, 6, 11, 7, 8, 11, 8, 3, 0, 3, 8, 3, 0, 2, 1, 2, 0, 2, 1, 10, 2, 10, 11 }, +/* 218: 1, 3, 4, 6, 7, */ { 8, 4, 9, 5, 9, 4, 9, 5, 10, 9, 10, 1, 2, 1, 10, 1, 2, 0, 3, 0, 2, 0, 3, 8, 0, 8, 9 } +}; +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 8 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling8[6][6] = { +/* 15: 0, 1, 2, 3, */ { 9, 8, 10, 10, 8, 11 }, +/* 51: 0, 1, 4, 5, */ { 1, 5, 3, 3, 5, 7 }, +/* 153: 0, 3, 4, 7, */ { 0, 4, 2, 4, 6, 2 }, +/* 102: 1, 2, 5, 6, */ { 0, 2, 4, 4, 2, 6 }, +/* 204: 2, 3, 6, 7, */ { 1, 3, 5, 3, 7, 5 }, +/* 240: 4, 5, 6, 7, */ { 9, 10, 8, 10, 11, 8 } +}; +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 9 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling9[8][12] = { +/* 39: 0, 1, 2, 5, */ { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8 }, +/* 27: 0, 1, 3, 4, */ { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1 }, +/* 141: 0, 2, 3, 7, */ { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8 }, +/* 177: 0, 4, 5, 7, */ { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5 }, +/* 78: 1, 2, 3, 6, */ { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9 }, +/* 114: 1, 4, 5, 6, */ { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0 }, +/* 228: 2, 5, 6, 7, */ { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2 }, +/* 216: 3, 4, 6, 7, */ { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4 } +}; +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +/** + * \brief test table for case 10 + * 2 faces to test + eventually the interior + * When the tests on both specified faces are positive : 4 middle triangles (1) + * When the test on the first specified face is positive : 8 first triangles + * When the test on the second specified face is positive : 8 next triangles + * When the tests on both specified faces are negative : + * - if the test on the interior is negative : 4 middle triangles + * - if the test on the interior is positive : 8 last triangles + * + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char test10[6][3] = { +/* 195: 0, 1, 6, 7, */ { 2, 4, 7 }, +/* 85: 0, 2, 4, 6, */ { 5, 6, 7 }, +/* 105: 0, 3, 5, 6, */ { 1, 3, 7 }, +/* 150: 1, 2, 4, 7, */ { 1, 3, 7 }, +/* 170: 1, 3, 5, 7, */ { 5, 6, 7 }, +/* 60: 2, 3, 4, 5, */ { 2, 4, 7 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 10.1.1 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling10_1_1[6][12] = { +/* 195: 0, 1, 6, 7, */ { 5, 10, 7, 11, 7, 10, 8, 1, 9, 1, 8, 3 }, +/* 85: 0, 2, 4, 6, */ { 1, 2, 5, 6, 5, 2, 4, 3, 0, 3, 4, 7 }, +/* 105: 0, 3, 5, 6, */ { 11, 0, 8, 0, 11, 2, 4, 9, 6, 10, 6, 9 }, +/* 150: 1, 2, 4, 7, */ { 9, 0, 10, 2, 10, 0, 6, 8, 4, 8, 6, 11 }, +/* 170: 1, 3, 5, 7, */ { 7, 2, 3, 2, 7, 6, 0, 1, 4, 5, 4, 1 }, +/* 60: 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 8, 10, 1, 11, 3, 11, 1 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 10.1.1 inverted + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling10_1_1_[6][12] = { +/* 195: 0, 1, 6, 7, */ { 5, 9, 7, 8, 7, 9, 11, 1, 10, 1, 11, 3 }, +/* 85: 0, 2, 4, 6, */ { 3, 2, 7, 6, 7, 2, 4, 1, 0, 1, 4, 5 }, +/* 105: 0, 3, 5, 6, */ { 10, 0, 9, 0, 10, 2, 4, 8, 6, 11, 6, 8 }, +/* 150: 1, 2, 4, 7, */ { 8, 0, 11, 2, 11, 0, 6, 9, 4, 9, 6, 10 }, +/* 170: 1, 3, 5, 7, */ { 5, 2, 1, 2, 5, 6, 0, 3, 4, 7, 4, 3 }, +/* 60: 2, 3, 4, 5, */ { 7, 10, 5, 10, 7, 11, 9, 1, 8, 3, 8, 1 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 10.1.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling10_1_2[6][24] = { +/* 195: 0, 1, 6, 7, */ { 3, 11, 7, 3, 7, 8, 9, 8, 7, 5, 9, 7, 9, 5, 10, 9, 10, 1, 3, 1, 10, 11, 3, 10 }, +/* 85: 0, 2, 4, 6, */ { 7, 6, 5, 7, 5, 4, 0, 4, 5, 1, 0, 5, 0, 1, 2, 0, 2, 3, 7, 3, 2, 6, 7, 2 }, +/* 105: 0, 3, 5, 6, */ { 11, 2, 10, 6, 11, 10, 11, 6, 4, 11, 4, 8, 0, 8, 4, 9, 0, 4, 0, 9, 10, 0, 10, 2 }, +/* 150: 1, 2, 4, 7, */ { 11, 2, 10, 11, 10, 6, 4, 6, 10, 9, 4, 10, 4, 9, 0, 4, 0, 8, 11, 8, 0, 2, 11, 0 }, +/* 170: 1, 3, 5, 7, */ { 7, 6, 5, 4, 7, 5, 7, 4, 0, 7, 0, 3, 2, 3, 0, 1, 2, 0, 2, 1, 5, 2, 5, 6 }, +/* 60: 2, 3, 4, 5, */ { 7, 8, 3, 11, 7, 3, 7, 11, 10, 7, 10, 5, 9, 5, 10, 1, 9, 10, 9, 1, 3, 9, 3, 8 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 10.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling10_2[6][24] = { +/* 195: 0, 1, 6, 7, */ { 12, 5, 9, 12, 9, 8, 12, 8, 3, 12, 3, 1, 12, 1, 10, 12, 10, 11, 12, 11, 7, 12, 7, 5 }, +/* 85: 0, 2, 4, 6, */ { 12, 1, 0, 12, 0, 4, 12, 4, 7, 12, 7, 3, 12, 3, 2, 12, 2, 6, 12, 6, 5, 12, 5, 1 }, +/* 105: 0, 3, 5, 6, */ { 4, 8, 12, 6, 4, 12, 10, 6, 12, 9, 10, 12, 0, 9, 12, 2, 0, 12, 11, 2, 12, 8, 11, 12 }, +/* 150: 1, 2, 4, 7, */ { 12, 9, 4, 12, 4, 6, 12, 6, 11, 12, 11, 8, 12, 8, 0, 12, 0, 2, 12, 2, 10, 12, 10, 9 }, +/* 170: 1, 3, 5, 7, */ { 0, 3, 12, 4, 0, 12, 5, 4, 12, 1, 5, 12, 2, 1, 12, 6, 2, 12, 7, 6, 12, 3, 7, 12 }, +/* 60: 2, 3, 4, 5, */ { 10, 5, 12, 11, 10, 12, 3, 11, 12, 1, 3, 12, 9, 1, 12, 8, 9, 12, 7, 8, 12, 5, 7, 12 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 10.2 inverted + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling10_2_[6][24] = { +/* 195: 0, 1, 6, 7, */ { 8, 7, 12, 9, 8, 12, 1, 9, 12, 3, 1, 12, 11, 3, 12, 10, 11, 12, 5, 10, 12, 7, 5, 12 }, +/* 85: 0, 2, 4, 6, */ { 4, 5, 12, 0, 4, 12, 3, 0, 12, 7, 3, 12, 6, 7, 12, 2, 6, 12, 1, 2, 12, 5, 1, 12 }, +/* 105: 0, 3, 5, 6, */ { 12, 11, 6, 12, 6, 4, 12, 4, 9, 12, 9, 10, 12, 10, 2, 12, 2, 0, 12, 0, 8, 12, 8, 11 }, +/* 150: 1, 2, 4, 7, */ { 6, 10, 12, 4, 6, 12, 8, 4, 12, 11, 8, 12, 2, 11, 12, 0, 2, 12, 9, 0, 12, 10, 9, 12 }, +/* 170: 1, 3, 5, 7, */ { 12, 7, 4, 12, 4, 0, 12, 0, 1, 12, 1, 5, 12, 5, 6, 12, 6, 2, 12, 2, 3, 12, 3, 7 }, +/* 60: 2, 3, 4, 5, */ { 12, 7, 11, 12, 11, 10, 12, 10, 1, 12, 1, 3, 12, 3, 8, 12, 8, 9, 12, 9, 5, 12, 5, 7 } +}; +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 11 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling11[12][12] = { +/* 23: 0, 1, 2, 4, */ { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4 }, +/* 139: 0, 1, 3, 7, */ { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6 }, +/* 99: 0, 1, 5, 6, */ { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10 }, +/* 77: 0, 2, 3, 6, */ { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6 }, +/* 57: 0, 3, 4, 5, */ { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11 }, +/* 209: 0, 4, 6, 7, */ { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0 }, +/* 46: 1, 2, 3, 5, */ { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3 }, +/* 198: 1, 2, 6, 7, */ { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7 }, +/* 178: 1, 4, 5, 7, */ { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11 }, +/* 156: 2, 3, 4, 7, */ { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1 }, +/* 116: 2, 4, 5, 6, */ { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7 }, +/* 232: 3, 5, 6, 7, */ { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9 } +}; +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +/** + * \brief test table for case 12 + * 2 faces to test + eventually the interior + * When the tests on both specified faces are positive : 4 middle triangles (1) + * When the test on the first specified face is positive : 8 first triangles + * When the test on the second specified face is positive : 8 next triangles + * When the tests on both specified faces are negative : + * - if the test on the interior is negative : 4 middle triangles + * - if the test on the interior is positive : 8 last triangles + * The support edge for the interior test is marked as the 4th column. + * + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char test12[24][4] = { +/* 135: 0, 1, 2, 7, */ { 4, 3, 7, 11 }, +/* 75: 0, 1, 3, 6, */ { 3, 2, 7, 10 }, +/* 83: 0, 1, 4, 6, */ { 2, 6, 7, 5 }, +/* 163: 0, 1, 5, 7, */ { 6, 4, 7, 7 }, +/* 45: 0, 2, 3, 5, */ { 2, 1, 7, 9 }, +/* 53: 0, 2, 4, 5, */ { 5, 2, 7, 1 }, +/* 149: 0, 2, 4, 7, */ { 5, 3, 7, 2 }, +/* 101: 0, 2, 5, 6, */ { 5, 1, 7, 0 }, +/* 197: 0, 2, 6, 7, */ { 5, 4, 7, 3 }, +/* 89: 0, 3, 4, 6, */ { 6, 3, 7, 6 }, +/* 169: 0, 3, 5, 7, */ { 1, 6, 7, 4 }, +/* 225: 0, 5, 6, 7, */ { 1, 4, 7, 8 }, +/* 30: 1, 2, 3, 4, */ { 4, 1, 7, 8 }, +/* 86: 1, 2, 4, 6, */ { 6, 1, 7, 4 }, +/* 166: 1, 2, 5, 7, */ { 3, 6, 7, 6 }, +/* 58: 1, 3, 4, 5, */ { 4, 5, 7, 3 }, +/* 154: 1, 3, 4, 7, */ { 1, 5, 7, 0 }, +/* 106: 1, 3, 5, 6, */ { 3, 5, 7, 2 }, +/* 202: 1, 3, 6, 7, */ { 2, 5, 7, 1 }, +/* 210: 1, 4, 6, 7, */ { 1, 2, 7, 9 }, +/* 92: 2, 3, 4, 6, */ { 4, 6, 7, 7 }, +/* 172: 2, 3, 5, 7, */ { 6, 2, 7, 5 }, +/* 180: 2, 4, 5, 7, */ { 2, 3, 7, 10 }, +/* 120: 3, 4, 5, 6, */ { 3, 4, 7, 11 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 12.1.1 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling12_1_1[24][12] = { +/* 135: 0, 1, 2, 7, */ { 7, 6, 11, 10, 3, 2, 3, 10, 8, 9, 8, 10 }, +/* 75: 0, 1, 3, 6, */ { 6, 5, 10, 9, 2, 1, 2, 9, 11, 8, 11, 9 }, +/* 83: 0, 1, 4, 6, */ { 10, 6, 5, 7, 9, 4, 9, 7, 1, 3, 1, 7 }, +/* 163: 0, 1, 5, 7, */ { 7, 6, 11, 4, 8, 5, 3, 5, 8, 5, 3, 1 }, +/* 45: 0, 2, 3, 5, */ { 5, 4, 9, 8, 1, 0, 1, 8, 10, 11, 10, 8 }, +/* 53: 0, 2, 4, 5, */ { 1, 2, 10, 0, 9, 3, 5, 3, 9, 3, 5, 7 }, +/* 149: 0, 2, 4, 7, */ { 10, 1, 2, 0, 11, 3, 11, 0, 6, 4, 6, 0 }, +/* 101: 0, 2, 5, 6, */ { 8, 3, 0, 2, 9, 1, 9, 2, 4, 6, 4, 2 }, +/* 197: 0, 2, 6, 7, */ { 3, 0, 8, 2, 11, 1, 7, 1, 11, 1, 7, 5 }, +/* 89: 0, 3, 4, 6, */ { 6, 5, 10, 7, 11, 4, 2, 4, 11, 4, 2, 0 }, +/* 169: 0, 3, 5, 7, */ { 9, 5, 4, 6, 8, 7, 8, 6, 0, 2, 0, 6 }, +/* 225: 0, 5, 6, 7, */ { 8, 3, 0, 7, 4, 11, 9, 11, 4, 11, 9, 10 }, +/* 30: 1, 2, 3, 4, */ { 4, 7, 8, 11, 0, 3, 0, 11, 9, 10, 9, 11 }, +/* 86: 1, 2, 4, 6, */ { 4, 7, 8, 5, 9, 6, 0, 6, 9, 6, 0, 2 }, +/* 166: 1, 2, 5, 7, */ { 11, 7, 6, 4, 10, 5, 10, 4, 2, 0, 2, 4 }, +/* 58: 1, 3, 4, 5, */ { 11, 2, 3, 1, 8, 0, 8, 1, 7, 5, 7, 1 }, +/* 154: 1, 3, 4, 7, */ { 0, 1, 9, 3, 8, 2, 4, 2, 8, 2, 4, 6 }, +/* 106: 1, 3, 5, 6, */ { 2, 3, 11, 1, 10, 0, 6, 0, 10, 0, 6, 4 }, +/* 202: 1, 3, 6, 7, */ { 9, 0, 1, 3, 10, 2, 10, 3, 5, 7, 5, 3 }, +/* 210: 1, 4, 6, 7, */ { 9, 0, 1, 4, 5, 8, 10, 8, 5, 8, 10, 11 }, +/* 92: 2, 3, 4, 6, */ { 8, 4, 7, 5, 11, 6, 11, 5, 3, 1, 3, 5 }, +/* 172: 2, 3, 5, 7, */ { 5, 4, 9, 6, 10, 7, 1, 7, 10, 7, 1, 3 }, +/* 180: 2, 4, 5, 7, */ { 10, 1, 2, 5, 6, 9, 11, 9, 6, 9, 11, 8 }, +/* 120: 3, 4, 5, 6, */ { 11, 2, 3, 6, 7, 10, 8, 10, 7, 10, 8, 9 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 12.1.1 inverted + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling12_1_1_[24][12] = { +/* 135: 0, 1, 2, 7, */ { 3, 2, 11, 10, 7, 6, 7, 10, 8, 9, 8, 10 }, +/* 75: 0, 1, 3, 6, */ { 2, 1, 10, 9, 6, 5, 6, 9, 11, 8, 11, 9 }, +/* 83: 0, 1, 4, 6, */ { 9, 4, 5, 7, 10, 6, 10, 7, 1, 3, 1, 7 }, +/* 163: 0, 1, 5, 7, */ { 7, 4, 8, 6, 11, 5, 3, 5, 11, 5, 3, 1 }, +/* 45: 0, 2, 3, 5, */ { 1, 0, 9, 8, 5, 4, 5, 8, 10, 11, 10, 8 }, +/* 53: 0, 2, 4, 5, */ { 1, 0, 9, 2, 10, 3, 5, 3, 10, 3, 5, 7 }, +/* 149: 0, 2, 4, 7, */ { 11, 3, 2, 0, 10, 1, 10, 0, 6, 4, 6, 0 }, +/* 101: 0, 2, 5, 6, */ { 9, 1, 0, 2, 8, 3, 8, 2, 4, 6, 4, 2 }, +/* 197: 0, 2, 6, 7, */ { 3, 2, 11, 0, 8, 1, 7, 1, 8, 1, 7, 5 }, +/* 89: 0, 3, 4, 6, */ { 6, 7, 11, 5, 10, 4, 2, 4, 10, 4, 2, 0 }, +/* 169: 0, 3, 5, 7, */ { 8, 7, 4, 6, 9, 5, 9, 6, 0, 2, 0, 6 }, +/* 225: 0, 5, 6, 7, */ { 8, 7, 4, 3, 0, 11, 9, 11, 0, 11, 9, 10 }, +/* 30: 1, 2, 3, 4, */ { 0, 3, 8, 11, 4, 7, 4, 11, 9, 10, 9, 11 }, +/* 86: 1, 2, 4, 6, */ { 4, 5, 9, 7, 8, 6, 0, 6, 8, 6, 0, 2 }, +/* 166: 1, 2, 5, 7, */ { 10, 5, 6, 4, 11, 7, 11, 4, 2, 0, 2, 4 }, +/* 58: 1, 3, 4, 5, */ { 8, 0, 3, 1, 11, 2, 11, 1, 7, 5, 7, 1 }, +/* 154: 1, 3, 4, 7, */ { 0, 3, 8, 1, 9, 2, 4, 2, 9, 2, 4, 6 }, +/* 106: 1, 3, 5, 6, */ { 2, 1, 10, 3, 11, 0, 6, 0, 11, 0, 6, 4 }, +/* 202: 1, 3, 6, 7, */ { 10, 2, 1, 3, 9, 0, 9, 3, 5, 7, 5, 3 }, +/* 210: 1, 4, 6, 7, */ { 9, 4, 5, 0, 1, 8, 10, 8, 1, 8, 10, 11 }, +/* 92: 2, 3, 4, 6, */ { 11, 6, 7, 5, 8, 4, 8, 5, 3, 1, 3, 5 }, +/* 172: 2, 3, 5, 7, */ { 5, 6, 10, 4, 9, 7, 1, 7, 9, 7, 1, 3 }, +/* 180: 2, 4, 5, 7, */ { 10, 5, 6, 1, 2, 9, 11, 9, 2, 9, 11, 8 }, +/* 120: 3, 4, 5, 6, */ { 11, 6, 7, 2, 3, 10, 8, 10, 3, 10, 8, 9 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 12.1.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling12_1_2[24][24] = { +/* 135: 0, 1, 2, 7, */ { 7, 3, 11, 3, 7, 8, 9, 8, 7, 6, 9, 7, 9, 6, 10, 2, 10, 6, 11, 2, 6, 2, 11, 3 }, +/* 75: 0, 1, 3, 6, */ { 6, 2, 10, 2, 6, 11, 8, 11, 6, 5, 8, 6, 8, 5, 9, 1, 9, 5, 10, 1, 5, 1, 10, 2 }, +/* 83: 0, 1, 4, 6, */ { 10, 9, 5, 9, 10, 1, 3, 1, 10, 6, 3, 10, 3, 6, 7, 4, 7, 6, 5, 4, 6, 4, 5, 9 }, +/* 163: 0, 1, 5, 7, */ { 7, 8, 11, 3, 11, 8, 11, 3, 1, 11, 1, 6, 5, 6, 1, 6, 5, 4, 6, 4, 7, 8, 7, 4 }, +/* 45: 0, 2, 3, 5, */ { 5, 1, 9, 1, 5, 10, 11, 10, 5, 4, 11, 5, 11, 4, 8, 0, 8, 4, 9, 0, 4, 0, 9, 1 }, +/* 53: 0, 2, 4, 5, */ { 1, 9, 10, 5, 10, 9, 10, 5, 7, 10, 7, 2, 3, 2, 7, 2, 3, 0, 2, 0, 1, 9, 1, 0 }, +/* 149: 0, 2, 4, 7, */ { 10, 11, 2, 11, 10, 6, 4, 6, 10, 1, 4, 10, 4, 1, 0, 3, 0, 1, 2, 3, 1, 3, 2, 11 }, +/* 101: 0, 2, 5, 6, */ { 8, 9, 0, 9, 8, 4, 6, 4, 8, 3, 6, 8, 6, 3, 2, 1, 2, 3, 0, 1, 3, 1, 0, 9 }, +/* 197: 0, 2, 6, 7, */ { 3, 11, 8, 7, 8, 11, 8, 7, 5, 8, 5, 0, 1, 0, 5, 0, 1, 2, 0, 2, 3, 11, 3, 2 }, +/* 89: 0, 3, 4, 6, */ { 6, 11, 10, 2, 10, 11, 10, 2, 0, 10, 0, 5, 4, 5, 0, 5, 4, 7, 5, 7, 6, 11, 6, 7 }, +/* 169: 0, 3, 5, 7, */ { 9, 8, 4, 8, 9, 0, 2, 0, 9, 5, 2, 9, 2, 5, 6, 7, 6, 5, 4, 7, 5, 7, 4, 8 }, +/* 225: 0, 5, 6, 7, */ { 8, 4, 0, 9, 0, 4, 0, 9, 10, 0, 10, 3, 11, 3, 10, 3, 11, 7, 3, 7, 8, 4, 8, 7 }, +/* 30: 1, 2, 3, 4, */ { 4, 0, 8, 0, 4, 9, 10, 9, 4, 7, 10, 4, 10, 7, 11, 3, 11, 7, 8, 3, 7, 3, 8, 0 }, +/* 86: 1, 2, 4, 6, */ { 4, 9, 8, 0, 8, 9, 8, 0, 2, 8, 2, 7, 6, 7, 2, 7, 6, 5, 7, 5, 4, 9, 4, 5 }, +/* 166: 1, 2, 5, 7, */ { 11, 10, 6, 10, 11, 2, 0, 2, 11, 7, 0, 11, 0, 7, 4, 5, 4, 7, 6, 5, 7, 5, 6, 10 }, +/* 58: 1, 3, 4, 5, */ { 11, 8, 3, 8, 11, 7, 5, 7, 11, 2, 5, 11, 5, 2, 1, 0, 1, 2, 3, 0, 2, 0, 3, 8 }, +/* 154: 1, 3, 4, 7, */ { 0, 8, 9, 4, 9, 8, 9, 4, 6, 9, 6, 1, 2, 1, 6, 1, 2, 3, 1, 3, 0, 8, 0, 3 }, +/* 106: 1, 3, 5, 6, */ { 2, 10, 11, 6, 11, 10, 11, 6, 4, 11, 4, 3, 0, 3, 4, 3, 0, 1, 3, 1, 2, 10, 2, 1 }, +/* 202: 1, 3, 6, 7, */ { 9, 10, 1, 10, 9, 5, 7, 5, 9, 0, 7, 9, 7, 0, 3, 2, 3, 0, 1, 2, 0, 2, 1, 10 }, +/* 210: 1, 4, 6, 7, */ { 9, 5, 1, 10, 1, 5, 1, 10, 11, 1, 11, 0, 8, 0, 11, 0, 8, 4, 0, 4, 9, 5, 9, 4 }, +/* 92: 2, 3, 4, 6, */ { 8, 11, 7, 11, 8, 3, 1, 3, 8, 4, 1, 8, 1, 4, 5, 6, 5, 4, 7, 6, 4, 6, 7, 11 }, +/* 172: 2, 3, 5, 7, */ { 5, 10, 9, 1, 9, 10, 9, 1, 3, 9, 3, 4, 7, 4, 3, 4, 7, 6, 4, 6, 5, 10, 5, 6 }, +/* 180: 2, 4, 5, 7, */ { 10, 6, 2, 11, 2, 6, 2, 11, 8, 2, 8, 1, 9, 1, 8, 1, 9, 5, 1, 5, 10, 6, 10, 5 }, +/* 120: 3, 4, 5, 6, */ { 11, 7, 3, 8, 3, 7, 3, 8, 9, 3, 9, 2, 10, 2, 9, 2, 10, 6, 2, 6, 11, 7, 11, 6 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 12.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling12_2[24][24] = { +/* 135: 0, 1, 2, 7, */ { 9, 8, 12, 10, 9, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12 }, +/* 75: 0, 1, 3, 6, */ { 8, 11, 12, 9, 8, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12 }, +/* 83: 0, 1, 4, 6, */ { 3, 1, 12, 7, 3, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 }, +/* 163: 0, 1, 5, 7, */ { 12, 3, 1, 12, 1, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 }, +/* 45: 0, 2, 3, 5, */ { 11, 10, 12, 8, 11, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12 }, +/* 53: 0, 2, 4, 5, */ { 12, 5, 7, 12, 7, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 }, +/* 149: 0, 2, 4, 7, */ { 4, 6, 12, 0, 4, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 }, +/* 101: 0, 2, 5, 6, */ { 6, 4, 12, 2, 6, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 }, +/* 197: 0, 2, 6, 7, */ { 12, 7, 5, 12, 5, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 }, +/* 89: 0, 3, 4, 6, */ { 12, 2, 0, 12, 0, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 }, +/* 169: 0, 3, 5, 7, */ { 2, 0, 12, 6, 2, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 }, +/* 225: 0, 5, 6, 7, */ { 12, 9, 10, 12, 10, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9 }, +/* 30: 1, 2, 3, 4, */ { 10, 9, 12, 11, 10, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12 }, +/* 86: 1, 2, 4, 6, */ { 12, 0, 2, 12, 2, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 }, +/* 166: 1, 2, 5, 7, */ { 0, 2, 12, 4, 0, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 }, +/* 58: 1, 3, 4, 5, */ { 5, 7, 12, 1, 5, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 }, +/* 154: 1, 3, 4, 7, */ { 12, 4, 6, 12, 6, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 }, +/* 106: 1, 3, 5, 6, */ { 12, 6, 4, 12, 4, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 }, +/* 202: 1, 3, 6, 7, */ { 7, 5, 12, 3, 7, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 }, +/* 210: 1, 4, 6, 7, */ { 12, 10, 11, 12, 11, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10 }, +/* 92: 2, 3, 4, 6, */ { 1, 3, 12, 5, 1, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 }, +/* 172: 2, 3, 5, 7, */ { 12, 1, 3, 12, 3, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 }, +/* 180: 2, 4, 5, 7, */ { 12, 11, 8, 12, 8, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11 }, +/* 120: 3, 4, 5, 6, */ { 12, 8, 9, 12, 9, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 12.2 inverted + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling12_2_[24][24] = { +/* 135: 0, 1, 2, 7, */ { 12, 2, 11, 12, 11, 7, 12, 7, 6, 12, 6, 10, 12, 10, 9, 12, 9, 8, 12, 8, 3, 12, 3, 2 }, +/* 75: 0, 1, 3, 6, */ { 12, 1, 10, 12, 10, 6, 12, 6, 5, 12, 5, 9, 12, 9, 8, 12, 8, 11, 12, 11, 2, 12, 2, 1 }, +/* 83: 0, 1, 4, 6, */ { 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 3, 12, 3, 1, 12, 1, 9, 12, 9, 4 }, +/* 163: 0, 1, 5, 7, */ { 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 1, 5, 12, 3, 1, 12, 11, 3, 12, 6, 11, 12 }, +/* 45: 0, 2, 3, 5, */ { 12, 0, 9, 12, 9, 5, 12, 5, 4, 12, 4, 8, 12, 8, 11, 12, 11, 10, 12, 10, 1, 12, 1, 0 }, +/* 53: 0, 2, 4, 5, */ { 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 7, 3, 12, 5, 7, 12, 10, 5, 12, 2, 10, 12 }, +/* 149: 0, 2, 4, 7, */ { 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 4, 12, 4, 6, 12, 6, 10, 12, 10, 1 }, +/* 101: 0, 2, 5, 6, */ { 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 6, 12, 6, 4, 12, 4, 8, 12, 8, 3 }, +/* 197: 0, 2, 6, 7, */ { 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 5, 1, 12, 7, 5, 12, 8, 7, 12, 0, 8, 12 }, +/* 89: 0, 3, 4, 6, */ { 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 0, 4, 12, 2, 0, 12, 10, 2, 12, 5, 10, 12 }, +/* 169: 0, 3, 5, 7, */ { 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 2, 12, 2, 0, 12, 0, 8, 12, 8, 7 }, +/* 225: 0, 5, 6, 7, */ { 8, 7, 12, 0, 8, 12, 3, 0, 12, 11, 3, 12, 10, 11, 12, 9, 10, 12, 4, 9, 12, 7, 4, 12 }, +/* 30: 1, 2, 3, 4, */ { 12, 7, 8, 12, 8, 0, 12, 0, 3, 12, 3, 11, 12, 11, 10, 12, 10, 9, 12, 9, 4, 12, 4, 7 }, +/* 86: 1, 2, 4, 6, */ { 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 2, 6, 12, 0, 2, 12, 8, 0, 12, 7, 8, 12 }, +/* 166: 1, 2, 5, 7, */ { 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 0, 12, 0, 2, 12, 2, 10, 12, 10, 5 }, +/* 58: 1, 3, 4, 5, */ { 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 5, 12, 5, 7, 12, 7, 8, 12, 8, 0 }, +/* 154: 1, 3, 4, 7, */ { 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 6, 2, 12, 4, 6, 12, 8, 4, 12, 3, 8, 12 }, +/* 106: 1, 3, 5, 6, */ { 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 4, 0, 12, 6, 4, 12, 10, 6, 12, 1, 10, 12 }, +/* 202: 1, 3, 6, 7, */ { 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 7, 12, 7, 5, 12, 5, 10, 12, 10, 2 }, +/* 210: 1, 4, 6, 7, */ { 9, 0, 12, 5, 9, 12, 4, 5, 12, 8, 4, 12, 11, 8, 12, 10, 11, 12, 1, 10, 12, 0, 1, 12 }, +/* 92: 2, 3, 4, 6, */ { 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 1, 12, 1, 3, 12, 3, 11, 12, 11, 6 }, +/* 172: 2, 3, 5, 7, */ { 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 3, 7, 12, 1, 3, 12, 9, 1, 12, 4, 9, 12 }, +/* 180: 2, 4, 5, 7, */ { 10, 1, 12, 6, 10, 12, 5, 6, 12, 9, 5, 12, 8, 9, 12, 11, 8, 12, 2, 11, 12, 1, 2, 12 }, +/* 120: 3, 4, 5, 6, */ { 11, 2, 12, 7, 11, 12, 6, 7, 12, 10, 6, 12, 9, 10, 12, 8, 9, 12, 3, 8, 12, 2, 3, 12 } +}; +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +/** + * \brief test table for case 13 + * All faces are to be tested + * + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13: face test */ +static const char test13[2][7] = { +/* 165: 0, 2, 5, 7, */ { 1,2,3,4,5,6,7 }, +/* 90: 1, 3, 4, 6, */ { 2,3,4,1,5,6,7 }, +}; + + + +//_____________________________________________________________________________ +/** + * \brief subconfiguration table for case 13 + * Hard-coded tests for the subconfiguration determination + * + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13: sub configs */ +static const char subconfig13[64] = { +/* 0: 0,0,0,0,0,0 */ 0, +/* 1: 1,0,0,0,0,0 */ 1, +/* 2: 0,1,0,0,0,0 */ 2, +/* 3: 1,1,0,0,0,0 */ 7, +/* 4: 0,0,1,0,0,0 */ 3, +/* 5: 1,0,1,0,0,0 */ -1, +/* 6: 0,1,1,0,0,0 */ 11, +/* 7: 1,1,1,0,0,0 */ -1, +/* 8: 0,0,0,1,0,0 */ 4, +/* 9: 1,0,0,1,0,0 */ 8, +/* 10: 0,1,0,1,0,0 */ -1, +/* 11: 1,1,0,1,0,0 */ -1, +/* 12: 0,0,1,1,0,0 */ 14, +/* 13: 1,0,1,1,0,0 */ -1, +/* 14: 0,1,1,1,0,0 */ -1, +/* 15: 1,1,1,1,0,0 */ -1, +/* 16: 0,0,0,0,1,0 */ 5, +/* 17: 1,0,0,0,1,0 */ 9, +/* 18: 0,1,0,0,1,0 */ 12, +/* 19: 1,1,0,0,1,0 */ 23, +/* 20: 0,0,1,0,1,0 */ 15, +/* 21: 1,0,1,0,1,0 */ -1, +/* 22: 0,1,1,0,1,0 */ 21, +/* 23: 1,1,1,0,1,0 */ 38, +/* 24: 0,0,0,1,1,0 */ 17, +/* 25: 1,0,0,1,1,0 */ 20, +/* 26: 0,1,0,1,1,0 */ -1, +/* 27: 1,1,0,1,1,0 */ 36, +/* 28: 0,0,1,1,1,0 */ 26, +/* 29: 1,0,1,1,1,0 */ 33, +/* 30: 0,1,1,1,1,0 */ 30, +/* 31: 1,1,1,1,1,0 */ 44, +/* 32: 0,0,0,0,0,1 */ 6, +/* 33: 1,0,0,0,0,1 */ 10, +/* 34: 0,1,0,0,0,1 */ 13, +/* 35: 1,1,0,0,0,1 */ 19, +/* 36: 0,0,1,0,0,1 */ 16, +/* 37: 1,0,1,0,0,1 */ -1, +/* 38: 0,1,1,0,0,1 */ 25, +/* 39: 1,1,1,0,0,1 */ 37, +/* 40: 0,0,0,1,0,1 */ 18, +/* 41: 1,0,0,1,0,1 */ 24, +/* 42: 0,1,0,1,0,1 */ -1, +/* 43: 1,1,0,1,0,1 */ 35, +/* 44: 0,0,1,1,0,1 */ 22, +/* 45: 1,0,1,1,0,1 */ 32, +/* 46: 0,1,1,1,0,1 */ 29, +/* 47: 1,1,1,1,0,1 */ 43, +/* 48: 0,0,0,0,1,1 */ -1, +/* 49: 1,0,0,0,1,1 */ -1, +/* 50: 0,1,0,0,1,1 */ -1, +/* 51: 1,1,0,0,1,1 */ 34, +/* 52: 0,0,1,0,1,1 */ -1, +/* 53: 1,0,1,0,1,1 */ -1, +/* 54: 0,1,1,0,1,1 */ 28, +/* 55: 1,1,1,0,1,1 */ 42, +/* 56: 0,0,0,1,1,1 */ -1, +/* 57: 1,0,0,1,1,1 */ 31, +/* 58: 0,1,0,1,1,1 */ -1, +/* 59: 1,1,0,1,1,1 */ 41, +/* 60: 0,0,1,1,1,1 */ 27, +/* 61: 1,0,1,1,1,1 */ 40, +/* 62: 0,1,1,1,1,1 */ 39, +/* 63: 1,1,1,1,1,1 */ 45, +}; + + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 13.1 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13.1 */ +static const char tiling13_1[2][12] = { +/* 165: 0, 2, 5, 7, */ { 11, 7, 6, 1, 2, 10, 8, 3, 0, 9, 5, 4 }, +/* 90: 1, 3, 4, 6, */ { 8, 4, 7, 2, 3, 11, 9, 0, 1, 10, 6, 5 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 13.1 inverted + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13.1 */ +static const char tiling13_1_[2][12] = { +/* 165: 0, 2, 5, 7, */ { 7, 4, 8, 11, 3, 2, 1, 0, 9, 5, 6, 10 }, +/* 90: 1, 3, 4, 6, */ { 6, 7, 11, 10, 2, 1, 0, 3, 8, 4, 5, 9 } +}; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 13.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13.2 */ +static const char tiling13_2[2][6][18] = { +/* 165: 0, 2, 5, 7, */ { + /* 1 */ { 1, 2, 10, 11, 7, 6, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 }, + /* 2 */ { 8, 3, 0, 11, 7, 6, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 }, + /* 3 */ { 9, 5, 4, 8, 3, 0, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 }, + /* 4 */ { 9, 5, 4, 1, 2, 10, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 }, + /* 5 */ { 9, 5, 4, 11, 7, 6, 0, 10, 1, 10, 0, 8, 10, 8, 2, 3, 2, 8 }, + /* 6 */ { 1, 2, 10, 3, 0, 8, 4, 9, 7, 11, 7, 9, 5, 11, 9, 11, 5, 6 } +}, +/* 90: 1, 3, 4, 6, */ { + /* 1 */ { 2, 3, 11, 8, 4, 7, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 }, + /* 2 */ { 9, 0, 1, 8, 4, 7, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 }, + /* 3 */ { 6, 5, 10, 9, 0, 1, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 }, + /* 4 */ { 6, 5, 10, 2, 3, 11, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 }, + /* 5 */ { 6, 5, 10, 8, 4, 7, 1, 11, 2, 11, 1, 9, 11, 9, 3, 0, 3, 9 }, + /* 6 */ { 2, 3, 11, 0, 1, 9, 5, 10, 4, 8, 4, 10, 6, 8, 10, 8, 6, 7 } +} }; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 13.2 inverted + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13.2 */ +static const char tiling13_2_[2][6][18] = { +/* 165: 0, 2, 5, 7, */ { + /* 1 */ { 10, 5, 6, 11, 3, 2, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 }, + /* 2 */ { 11, 3, 2, 7, 4, 8, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 }, + /* 3 */ { 1, 0, 9, 7, 4, 8, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 }, + /* 4 */ { 10, 5, 6, 1, 0, 9, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 }, + /* 5 */ { 10, 5, 6, 7, 4, 8, 2, 11, 1, 9, 1, 11, 3, 9, 11, 9, 3, 0 }, + /* 6 */ { 11, 3, 2, 9, 1, 0, 4, 10, 5, 10, 4, 8, 10, 8, 6, 7, 6, 8 } +}, +/* 90: 1, 3, 4, 6, */ { + /* 1 */ { 6, 7, 11, 8, 0, 3, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 }, + /* 2 */ { 8, 0, 3, 4, 5, 9, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 }, + /* 3 */ { 2, 1, 10, 4, 5, 9, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 }, + /* 4 */ { 6, 7, 11, 2, 1, 10, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 }, + /* 5 */ { 6, 7, 11, 4, 5, 9, 3, 8, 2, 10, 2, 8, 0, 10, 8, 10, 0, 1 }, + /* 6 */ { 8, 0, 3, 10, 2, 1, 5, 11, 6, 11, 5, 9, 11, 9, 7, 4, 7, 9 } +} }; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 13.3 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13.3 */ +static const char tiling13_3[2][12][30] = { +/* 165: 0, 2, 5, 7, */ { + /* 1,2 */ { 11, 7, 6, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 }, + /* 1,4 */ { 1, 2, 10, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12 }, + /* 1,5 */ { 11, 7, 6, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 }, + /* 1,6 */ { 1, 2, 10, 12, 3, 0, 12, 0, 9, 12, 9, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 }, + /* 2,3 */ { 8, 3, 0, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12 }, + /* 2,5 */ { 11, 7, 6, 5, 4, 12, 10, 5, 12, 2, 10, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 }, + /* 2,6 */ { 8, 3, 0, 1, 2, 12, 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 6, 11, 12, 5, 6, 12, 10, 5, 12, 2, 10, 12 }, + /* 3,4 */ { 9, 5, 4, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 }, + /* 3,5 */ { 9, 5, 4, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 }, + /* 3,6 */ { 8, 3, 0, 12, 1, 2, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 }, + /* 4,5 */ { 9, 5, 4, 7, 6, 12, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 }, + /* 4,6 */ { 1, 2, 10, 3, 0, 12, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12, 8, 7, 12, 0, 8, 12 } +}, +/* 90: 1, 3, 4, 6, */ { + /* 1,2 */ { 8, 4, 7, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 }, + /* 1,4 */ { 2, 3, 11, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12 }, + /* 1,5 */ { 8, 4, 7, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 10, 12, 10, 6 }, + /* 1,6 */ { 2, 3, 11, 12, 0, 1, 12, 1, 10, 12, 10, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 }, + /* 2,3 */ { 0, 1, 9, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12 }, + /* 2,5 */ { 8, 4, 7, 6, 5, 12, 11, 6, 12, 3, 11, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12 }, + /* 2,6 */ { 9, 0, 1, 2, 3, 12, 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 7, 8, 12, 6, 7, 12, 11, 6, 12, 3, 11, 12 }, + /* 3,4 */ { 6, 5, 10, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 }, + /* 3,5 */ { 6, 5, 10, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 8, 12, 8, 4 }, + /* 3,6 */ { 9, 0, 1, 12, 2, 3, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 }, + /* 4,5 */ { 6, 5, 10, 4, 7, 12, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 8, 0, 12, 7, 8, 12 }, + /* 4,6 */ { 2, 3, 11, 0, 1, 12, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12, 9, 4, 12, 1, 9, 12 } +} }; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 13.3, inverted + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13.3 */ +static const char tiling13_3_[2][12][30] = { +/* 165: 0, 2, 5, 7, */ { + /* 1,2 */ { 3, 2, 11, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 6, 10, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12 }, + /* 1,4 */ { 5, 6, 10, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2 }, + /* 1,5 */ { 10, 5, 6, 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 8, 12, 8, 7 }, + /* 1,6 */ { 11, 3, 2, 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 5, 12, 5, 4, 12, 4, 9, 12, 9, 1 }, + /* 2,3 */ { 7, 4, 8, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 }, + /* 2,5 */ { 7, 4, 8, 5, 6, 12, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 10, 1, 12, 6, 10, 12 }, + /* 2,6 */ { 11, 3, 2, 1, 0, 12, 10, 1, 12, 6, 10, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 }, + /* 3,4 */ { 1, 0, 9, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4 }, + /* 3,5 */ { 7, 4, 8, 12, 5, 6, 12, 6, 11, 12, 11, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5 }, + /* 3,6 */ { 1, 0, 9, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 7, 12, 7, 6, 12, 6, 11, 12, 11, 3 }, + /* 4,5 */ { 10, 5, 6, 7, 4, 12, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 8, 3, 12, 4, 8, 12 }, + /* 4,6 */ { 9, 1, 0, 3, 2, 12, 8, 3, 12, 4, 8, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 } +}, +/* 90: 1, 3, 4, 6, */ { + /* 1,2 */ { 0, 3, 8, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 7, 11, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12 }, + /* 1,4 */ { 11, 6, 7, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3 }, + /* 1,5 */ { 6, 7, 11, 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 }, + /* 1,6 */ { 8, 0, 3, 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 6, 12, 6, 5, 12, 5, 10, 12, 10, 2 }, + /* 2,3 */ { 4, 5, 9, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 }, + /* 2,5 */ { 4, 5, 9, 6, 7, 12, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 }, + /* 2,6 */ { 8, 0, 3, 2, 1, 12, 11, 2, 12, 7, 11, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 }, + /* 3,4 */ { 2, 1, 10, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5 }, + /* 3,5 */ { 4, 5, 9, 12, 6, 7, 12, 7, 8, 12, 8, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 }, + /* 3,6 */ { 2, 1, 10, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 4, 12, 4, 7, 12, 7, 8, 12, 8, 0 }, + /* 4,5 */ { 6, 7, 11, 4, 5, 12, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 }, + /* 4,6 */ { 10, 2, 1, 0, 3, 12, 9, 0, 12, 5, 9, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 } +} }; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 13.4 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13.4 */ +static const char tiling13_4[2][4][36] = { +/* 165: 0, 2, 5, 7, */ { +/* 1,2,6 */ { 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 }, +/* 1,4,5 */ { 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 }, +/* 2,3,5 */ { 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12 }, +/* 3,4,6 */ { 12, 0, 8, 12, 8, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 } +}, +/* 90: 1, 3, 4, 6, */ { +/* 1,2,6 */ { 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 }, +/* 1,4,5 */ { 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 }, +/* 2,3,5 */ { 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12 }, +/* 3,4,6 */ { 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 } +} }; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 13.5.1 + * The support edge for the interior test is marked as the 1st column. + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13.5.1 */ +static const char tiling13_5_1[2][4][18] = { +/* 165: 0, 2, 5, 7, */ { +/* 1,2,5 */ { 7, 6, 11, 1, 0, 9, 10, 3, 2, 3, 10, 5, 3, 5, 8, 4, 8, 5 }, +/* 1,4,6 */ { 1, 2, 10, 7, 4, 8, 3, 0, 11, 6, 11, 0, 9, 6, 0, 6, 9, 5 }, +/* 2,3,6 */ { 3, 0, 8, 5, 6, 10, 1, 2, 9, 4, 9, 2, 11, 4, 2, 4, 11, 7 }, +/* 3,4,5 */ { 5, 4, 9, 3, 2, 11, 8, 1, 0, 1, 8, 7, 1, 7, 10, 6, 10, 7 } +}, +/* 90: 1, 3, 4, 6, */ { +/* 1,2,5 */ { 4, 7, 8, 2, 1, 10, 11, 0, 3, 0, 11, 6, 0, 6, 9, 5, 9, 6 }, +/* 1,4,6 */ { 2, 3, 11, 4, 5, 9, 0, 1, 8, 7, 8, 1, 10, 7, 1, 7, 10, 6 }, +/* 2,3,6 */ { 0, 1, 9, 6, 7, 11, 2, 3, 10, 5, 10, 3, 8, 5, 3, 5, 8, 4 }, +/* 3,4,5 */ { 6, 5, 10, 0, 3, 8, 9, 2, 1, 2, 9, 4, 2, 4, 11, 7, 11, 4 } +} }; + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 13.5.2 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +/* 13.5.2 */ +static const char tiling13_5_2[2][4][30] = { +/* 165: 0, 2, 5, 7, */ { +/* 1,2,5 */ { 1, 0, 9, 7, 4, 8, 7, 8, 3, 7, 3, 11, 2, 11, 3, 11, 2, 10, 11, 10, 6, 5, 6, 10, 6, 5, 7, 4, 7, 5 }, +/* 1,4,6 */ { 7, 4, 8, 11, 3, 2, 6, 11, 2, 10, 6, 2, 6, 10, 5, 9, 5, 10, 1, 9, 10, 9, 1, 0, 2, 0, 1, 0, 2, 3 }, +/* 2,3,6 */ { 5, 6, 10, 9, 1, 0, 4, 9, 0, 8, 4, 0, 4, 8, 7, 11, 7, 8, 3, 11, 8, 11, 3, 2, 0, 2, 3, 2, 0, 1 }, +/* 3,4,5 */ { 3, 2, 11, 5, 6, 10, 5, 10, 1, 5, 1, 9, 0, 9, 1, 9, 0, 8, 9, 8, 4, 4, 8, 7, 4, 7, 5, 6, 5, 7 } +}, +/* 90: 1, 3, 4, 6, */ { +/* 1,2,5 */ { 2, 1, 10, 4, 5, 9, 4, 9, 0, 4, 0, 8, 3, 8, 0, 8, 3, 11, 8, 11, 7, 6, 7, 11, 7, 6, 4, 5, 4, 6 }, +/* 1,4,6 */ { 4, 5, 9, 8, 0, 3, 7, 8, 3, 11, 7, 3, 7, 11, 6, 10, 6, 11, 2, 10, 11, 10, 2, 1, 3, 1, 2, 1, 3, 0 }, +/* 2,3,6 */ { 6, 7, 11, 10, 2, 1, 5, 10, 1, 9, 5, 1, 5, 9, 4, 8, 4, 9, 0, 8, 9, 8, 0, 3, 1, 3, 0, 3, 1, 2 }, +/* 3,4,5 */ { 0, 3, 8, 6, 7, 11, 6, 11, 2, 6, 2, 10, 1, 10, 2, 10, 1, 9, 10, 9, 5, 5, 9, 4, 5, 4, 6, 7, 6, 4 } +} }; +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +/** + * \brief tiling table for case 14 + * For each of the case above, the specific triangulation of the edge + * intersection points is given. + * When a case is ambiguous, there is an auxiliary table that contains + * the face number to test and the tiling table contains the specific + * triangulations depending on the results + * A minus sign means to invert the result of the test. + */ +//----------------------------------------------------------------------------- +static const char tiling14[12][12] = { +/* 71: 0, 1, 2, 6, */ { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8 }, +/* 43: 0, 1, 3, 5, */ { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5 }, +/* 147: 0, 1, 4, 7, */ { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6 }, +/* 29: 0, 2, 3, 4, */ { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4 }, +/* 201: 0, 3, 6, 7, */ { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5 }, +/* 113: 0, 4, 5, 6, */ { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10 }, +/* 142: 1, 2, 3, 7, */ { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7 }, +/* 54: 1, 2, 4, 5, */ { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2 }, +/* 226: 1, 5, 6, 7, */ { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11 }, +/* 108: 2, 3, 5, 6, */ { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3 }, +/* 212: 2, 4, 6, 7, */ { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8 }, +/* 184: 3, 4, 5, 7, */ { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2 } +}; +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +/** + * \brief original Marching Cubes implementation + * For each of the possible vertex states listed in this table there is a + * specific triangulation of the edge intersection points. The table lists + * all of them in the form of 0-5 edge triples with the list terminated by + * the invalid value -1. For example: casesClassic[3] list the 2 triangles + * formed when cube[0] and cube[1] are inside of the surface, but the rest of + * the cube is not. + */ +//----------------------------------------------------------------------------- +static const char casesClassic[256][16] = { +/* 0: */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 1: 0, */ { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 2: 1, */ { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 3: 0, 1, */ { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 4: 2, */ { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 5: 0, 2, */ { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 6: 1, 2, */ { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 7: 0, 1, 2, */ { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, +/* 8: 3, */ { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 9: 0, 3, */ { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 10: 1, 3, */ { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 11: 0, 1, 3, */ { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, +/* 12: 2, 3, */ { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 13: 0, 2, 3, */ { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, +/* 14: 1, 2, 3, */ { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, +/* 15: 0, 1, 2, 3, */ { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 16: 4, */ { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 17: 0, 4, */ { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 18: 1, 4, */ { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 19: 0, 1, 4, */ { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, +/* 20: 2, 4, */ { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 21: 0, 2, 4, */ { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 }, +/* 22: 1, 2, 4, */ { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, +/* 23: 0, 1, 2, 4, */ { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, +/* 24: 3, 4, */ { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 25: 0, 3, 4, */ { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, +/* 26: 1, 3, 4, */ { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, +/* 27: 0, 1, 3, 4, */ { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 }, +/* 28: 2, 3, 4, */ { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 }, +/* 29: 0, 2, 3, 4, */ { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 }, +/* 30: 1, 2, 3, 4, */ { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, +/* 31: 0, 1, 2, 3, 4, */ { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, +/* 32: 5, */ { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 33: 0, 5, */ { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 34: 1, 5, */ { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 35: 0, 1, 5, */ { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, +/* 36: 2, 5, */ { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 37: 0, 2, 5, */ { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, +/* 38: 1, 2, 5, */ { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, +/* 39: 0, 1, 2, 5, */ { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 }, +/* 40: 3, 5, */ { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 41: 0, 3, 5, */ { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, +/* 42: 1, 3, 5, */ { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, +/* 43: 0, 1, 3, 5, */ { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 }, +/* 44: 2, 3, 5, */ { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, +/* 45: 0, 2, 3, 5, */ { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 }, +/* 46: 1, 2, 3, 5, */ { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, +/* 47: 0, 1, 2, 3, 5, */ { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, +/* 48: 4, 5, */ { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 49: 0, 4, 5, */ { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, +/* 50: 1, 4, 5, */ { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, +/* 51: 0, 1, 4, 5, */ { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 52: 2, 4, 5, */ { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 }, +/* 53: 0, 2, 4, 5, */ { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 }, +/* 54: 1, 2, 4, 5, */ { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, +/* 55: 0, 1, 2, 4, 5, */ { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, +/* 56: 3, 4, 5, */ { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, +/* 57: 0, 3, 4, 5, */ { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, +/* 58: 1, 3, 4, 5, */ { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 }, +/* 59: 0, 1, 3, 4, 5, */ { 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, +/* 60: 2, 3, 4, 5, */ { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 }, +/* 61: 0, 2, 3, 4, 5, */ { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 }, +/* 62: 1, 2, 3, 4, 5, */ { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 }, +/* 63: 0, 1, 2, 3, 4, 5, */ { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 64: 6, */ { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 65: 0, 6, */ { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 66: 1, 6, */ { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 67: 0, 1, 6, */ { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, +/* 68: 2, 6, */ { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 69: 0, 2, 6, */ { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 }, +/* 70: 1, 2, 6, */ { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, +/* 71: 0, 1, 2, 6, */ { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 }, +/* 72: 3, 6, */ { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 73: 0, 3, 6, */ { 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, +/* 74: 1, 3, 6, */ { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, +/* 75: 0, 1, 3, 6, */ { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 }, +/* 76: 2, 3, 6, */ { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, +/* 77: 0, 2, 3, 6, */ { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, +/* 78: 1, 2, 3, 6, */ { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 }, +/* 79: 0, 1, 2, 3, 6, */ { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, +/* 80: 4, 6, */ { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 81: 0, 4, 6, */ { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 }, +/* 82: 1, 4, 6, */ { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, +/* 83: 0, 1, 4, 6, */ { 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, +/* 84: 2, 4, 6, */ { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, +/* 85: 0, 2, 4, 6, */ { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 }, +/* 86: 1, 2, 4, 6, */ { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 }, +/* 87: 0, 1, 2, 4, 6, */ { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 }, +/* 88: 3, 4, 6, */ { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, +/* 89: 0, 3, 4, 6, */ { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, +/* 90: 1, 3, 4, 6, */ { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, +/* 91: 0, 1, 3, 4, 6, */ { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 }, +/* 92: 2, 3, 4, 6, */ { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, +/* 93: 0, 2, 3, 4, 6, */ { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 }, +/* 94: 1, 2, 3, 4, 6, */ { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 }, +/* 95: 0, 1, 2, 3, 4, 6, */ { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 }, +/* 96: 5, 6, */ { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 97: 0, 5, 6, */ { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 }, +/* 98: 1, 5, 6, */ { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, +/* 99: 0, 1, 5, 6, */ { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, +/* 100: 2, 5, 6, */ { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, +/* 101: 0, 2, 5, 6, */ { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 }, +/* 102: 1, 2, 5, 6, */ { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 103: 0, 1, 2, 5, 6, */ { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, +/* 104: 3, 5, 6, */ { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 }, +/* 105: 0, 3, 5, 6, */ { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 }, +/* 106: 1, 3, 5, 6, */ { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, +/* 107: 0, 1, 3, 5, 6, */ { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 }, +/* 108: 2, 3, 5, 6, */ { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 }, +/* 109: 0, 2, 3, 5, 6, */ { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 }, +/* 110: 1, 2, 3, 5, 6, */ { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, +/* 111: 0, 1, 2, 3, 5, 6, */ { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 112: 4, 5, 6, */ { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, +/* 113: 0, 4, 5, 6, */ { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 }, +/* 114: 1, 4, 5, 6, */ { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 }, +/* 115: 0, 1, 4, 5, 6, */ { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, +/* 116: 2, 4, 5, 6, */ { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, +/* 117: 0, 2, 4, 5, 6, */ { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 }, +/* 118: 1, 2, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, +/* 119: 0, 1, 2, 4, 5, 6, */ { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 120: 3, 4, 5, 6, */ { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, +/* 121: 0, 3, 4, 5, 6, */ { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 }, +/* 122: 1, 3, 4, 5, 6, */ { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 }, +/* 123: 0, 1, 3, 4, 5, 6, */ { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 }, +/* 124: 2, 3, 4, 5, 6, */ { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, +/* 125: 0, 2, 3, 4, 5, 6, */ { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 126: 1, 2, 3, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 }, +/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 128: 7, */ { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 129: 0, 7, */ { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 130: 1, 7, */ { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 131: 0, 1, 7, */ { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, +/* 132: 2, 7, */ { 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 133: 0, 2, 7, */ { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, +/* 134: 1, 2, 7, */ { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, +/* 135: 0, 1, 2, 7, */ { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 }, +/* 136: 3, 7, */ { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 137: 0, 3, 7, */ { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, +/* 138: 1, 3, 7, */ { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 }, +/* 139: 0, 1, 3, 7, */ { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 }, +/* 140: 2, 3, 7, */ { 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, +/* 141: 0, 2, 3, 7, */ { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 }, +/* 142: 1, 2, 3, 7, */ { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 }, +/* 143: 0, 1, 2, 3, 7, */ { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, +/* 144: 4, 7, */ { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 145: 0, 4, 7, */ { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, +/* 146: 1, 4, 7, */ { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, +/* 147: 0, 1, 4, 7, */ { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 }, +/* 148: 2, 4, 7, */ { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 }, +/* 149: 0, 2, 4, 7, */ { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 }, +/* 150: 1, 2, 4, 7, */ { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 }, +/* 151: 0, 1, 2, 4, 7, */ { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 }, +/* 152: 3, 4, 7, */ { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, +/* 153: 0, 3, 4, 7, */ { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 154: 1, 3, 4, 7, */ { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 }, +/* 155: 0, 1, 3, 4, 7, */ { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, +/* 156: 2, 3, 4, 7, */ { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 }, +/* 157: 0, 2, 3, 4, 7, */ { 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, +/* 158: 1, 2, 3, 4, 7, */ { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 }, +/* 159: 0, 1, 2, 3, 4, 7, */ { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 160: 5, 7, */ { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 161: 0, 5, 7, */ { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, +/* 162: 1, 5, 7, */ { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, +/* 163: 0, 1, 5, 7, */ { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 }, +/* 164: 2, 5, 7, */ { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, +/* 165: 0, 2, 5, 7, */ { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 }, +/* 166: 1, 2, 5, 7, */ { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 }, +/* 167: 0, 1, 2, 5, 7, */ { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 }, +/* 168: 3, 5, 7, */ { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 }, +/* 169: 0, 3, 5, 7, */ { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 }, +/* 170: 1, 3, 5, 7, */ { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 }, +/* 171: 0, 1, 3, 5, 7, */ { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 }, +/* 172: 2, 3, 5, 7, */ { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 }, +/* 173: 0, 2, 3, 5, 7, */ { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 }, +/* 174: 1, 2, 3, 5, 7, */ { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 }, +/* 175: 0, 1, 2, 3, 5, 7, */ { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 }, +/* 176: 4, 5, 7, */ { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, +/* 177: 0, 4, 5, 7, */ { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 }, +/* 178: 1, 4, 5, 7, */ { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 }, +/* 179: 0, 1, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, +/* 180: 2, 4, 5, 7, */ { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 }, +/* 181: 0, 2, 4, 5, 7, */ { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 }, +/* 182: 1, 2, 4, 5, 7, */ { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 }, +/* 183: 0, 1, 2, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 }, +/* 184: 3, 4, 5, 7, */ { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 }, +/* 185: 0, 3, 4, 5, 7, */ { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, +/* 186: 1, 3, 4, 5, 7, */ { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 }, +/* 187: 0, 1, 3, 4, 5, 7, */ { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 188: 2, 3, 4, 5, 7, */ { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 }, +/* 189: 0, 2, 3, 4, 5, 7, */ { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 }, +/* 190: 1, 2, 3, 4, 5, 7, */ { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 192: 6, 7, */ { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 193: 0, 6, 7, */ { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 }, +/* 194: 1, 6, 7, */ { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 }, +/* 195: 0, 1, 6, 7, */ { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 }, +/* 196: 2, 6, 7, */ { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, +/* 197: 0, 2, 6, 7, */ { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 }, +/* 198: 1, 2, 6, 7, */ { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 }, +/* 199: 0, 1, 2, 6, 7, */ { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 }, +/* 200: 3, 6, 7, */ { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, +/* 201: 0, 3, 6, 7, */ { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 }, +/* 202: 1, 3, 6, 7, */ { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 }, +/* 203: 0, 1, 3, 6, 7, */ { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 }, +/* 204: 2, 3, 6, 7, */ { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 205: 0, 2, 3, 6, 7, */ { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, +/* 206: 1, 2, 3, 6, 7, */ { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, +/* 207: 0, 1, 2, 3, 6, 7, */ { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 208: 4, 6, 7, */ { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, +/* 209: 0, 4, 6, 7, */ { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 }, +/* 210: 1, 4, 6, 7, */ { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 }, +/* 211: 0, 1, 4, 6, 7, */ { 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 }, +/* 212: 2, 4, 6, 7, */ { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 }, +/* 213: 0, 2, 4, 6, 7, */ { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 }, +/* 214: 1, 2, 4, 6, 7, */ { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 }, +/* 215: 0, 1, 2, 4, 6, 7, */ { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 216: 3, 4, 6, 7, */ { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 }, +/* 217: 0, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, +/* 218: 1, 3, 4, 6, 7, */ { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 }, +/* 219: 0, 1, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 }, +/* 220: 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, +/* 221: 0, 2, 3, 4, 6, 7, */ { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 222: 1, 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 }, +/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 224: 5, 6, 7, */ { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, +/* 225: 0, 5, 6, 7, */ { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 }, +/* 226: 1, 5, 6, 7, */ { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 }, +/* 227: 0, 1, 5, 6, 7, */ { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 }, +/* 228: 2, 5, 6, 7, */ { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 }, +/* 229: 0, 2, 5, 6, 7, */ { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 }, +/* 230: 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, +/* 231: 0, 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 }, +/* 232: 3, 5, 6, 7, */ { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 }, +/* 233: 0, 3, 5, 6, 7, */ { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 }, +/* 234: 1, 3, 5, 6, 7, */ { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 }, +/* 235: 0, 1, 3, 5, 6, 7, */ { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 236: 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, +/* 237: 0, 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 }, +/* 238: 1, 2, 3, 5, 6, 7, */ { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 240: 4, 5, 6, 7, */ { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 241: 0, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, +/* 242: 1, 4, 5, 6, 7, */ { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, +/* 243: 0, 1, 4, 5, 6, 7, */ { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 244: 2, 4, 5, 6, 7, */ { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, +/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 }, +/* 246: 1, 2, 4, 5, 6, 7, */ { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 248: 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, +/* 249: 0, 3, 4, 5, 6, 7, */ { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 250: 1, 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 }, +/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 252: 2, 3, 4, 5, 6, 7, */ { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +/* 255: 0, 1, 2, 3, 4, 5, 6, 7, */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } +}; +//_____________________________________________________________________________ + + + +#endif // _LOOKUPTABLE_H_ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/MarchingCubes.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/MarchingCubes.cpp new file mode 100755 index 0000000000000000000000000000000000000000..d9012f0405a2ea63c696e432250891477d75074e --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/MarchingCubes.cpp @@ -0,0 +1,1302 @@ +/** + * @file MarchingCubes.cpp + * @author Thomas Lewiner <thomas.lewiner@polytechnique.org> + * @author Math Dept, PUC-Rio + * @version 0.2 + * @date 12/08/2002 + * + * @brief MarchingCubes Algorithm + */ +//________________________________________________ + + +#if !defined(WIN32) || defined(__CYGWIN__) +#pragma implementation +#endif // WIN32 + +#include <math.h> +#include <time.h> +#include <memory.h> +#include <stdlib.h> +#include <float.h> +#include "MarchingCubes.h" +#include "ply.h" +#include "LookUpTable.h" + +// step size of the arrays of vertices and triangles +#define ALLOC_SIZE 65536 + +//_____________________________________________________________________________ +// print cube for debug +void MarchingCubes::print_cube() { printf( "\t%f %f %f %f %f %f %f %f\n", _cube[0], _cube[1], _cube[2], _cube[3], _cube[4], _cube[5], _cube[6], _cube[7]) ; } +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// Constructor +MarchingCubes::MarchingCubes( const int size_x /*= -1*/, const int size_y /*= -1*/, const int size_z /*= -1*/ ) : +//----------------------------------------------------------------------------- + _originalMC(false), + _ext_data (false), + _size_x (size_x), + _size_y (size_y), + _size_z (size_z), + _data ((real *)NULL), + _x_verts (( int *)NULL), + _y_verts (( int *)NULL), + _z_verts (( int *)NULL), + _nverts (0), + _ntrigs (0), + _Nverts (0), + _Ntrigs (0), + _vertices (( Vertex *)NULL), + _triangles ((Triangle*)NULL) +{} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// Destructor +MarchingCubes::~MarchingCubes() +//----------------------------------------------------------------------------- +{ + clean_all() ; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// main algorithm +void MarchingCubes::run( real iso ) +//----------------------------------------------------------------------------- +{ + clock_t time = clock() ; + + compute_intersection_points( iso ) ; + + for( _k = 0 ; _k < _size_z-1 ; _k++ ) + for( _j = 0 ; _j < _size_y-1 ; _j++ ) + for( _i = 0 ; _i < _size_x-1 ; _i++ ) + { + _lut_entry = 0 ; + for( int p = 0 ; p < 8 ; ++p ) + { + _cube[p] = get_data( _i+((p^(p>>1))&1), _j+((p>>1)&1), _k+((p>>2)&1) ) - iso ; + if( fabs( _cube[p] ) < FLT_EPSILON ) _cube[p] = FLT_EPSILON ; + if( _cube[p] > 0 ) _lut_entry += 1 << p ; + } +/* + if( ( _cube[0] = get_data( _i , _j , _k ) ) > 0 ) _lut_entry += 1 ; + if( ( _cube[1] = get_data(_i+1, _j , _k ) ) > 0 ) _lut_entry += 2 ; + if( ( _cube[2] = get_data(_i+1,_j+1, _k ) ) > 0 ) _lut_entry += 4 ; + if( ( _cube[3] = get_data( _i ,_j+1, _k ) ) > 0 ) _lut_entry += 8 ; + if( ( _cube[4] = get_data( _i , _j ,_k+1) ) > 0 ) _lut_entry += 16 ; + if( ( _cube[5] = get_data(_i+1, _j ,_k+1) ) > 0 ) _lut_entry += 32 ; + if( ( _cube[6] = get_data(_i+1,_j+1,_k+1) ) > 0 ) _lut_entry += 64 ; + if( ( _cube[7] = get_data( _i ,_j+1,_k+1) ) > 0 ) _lut_entry += 128 ; +*/ + process_cube( ) ; + } + + printf("Marching Cubes ran in %lf secs.\n", (double)(clock() - time)/CLOCKS_PER_SEC) ; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// init temporary structures (must set sizes before call) +void MarchingCubes::init_temps() +//----------------------------------------------------------------------------- +{ + if( !_ext_data ) + _data = new real [_size_x * _size_y * _size_z] ; + _x_verts = new int [_size_x * _size_y * _size_z] ; + _y_verts = new int [_size_x * _size_y * _size_z] ; + _z_verts = new int [_size_x * _size_y * _size_z] ; + + memset( _x_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ; + memset( _y_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ; + memset( _z_verts, -1, _size_x * _size_y * _size_z * sizeof( int ) ) ; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// init all structures (must set sizes before call) +void MarchingCubes::init_all () +//----------------------------------------------------------------------------- +{ + init_temps() ; + + _nverts = _ntrigs = 0 ; + _Nverts = _Ntrigs = ALLOC_SIZE ; + _vertices = new Vertex [_Nverts] ; + _triangles = new Triangle[_Ntrigs] ; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// clean temporary structures +void MarchingCubes::clean_temps() +//----------------------------------------------------------------------------- +{ + if( !_ext_data ) + delete [] _data; + delete [] _x_verts; + delete [] _y_verts; + delete [] _z_verts; + + if( !_ext_data ) + _data = (real*)NULL ; + _x_verts = (int*)NULL ; + _y_verts = (int*)NULL ; + _z_verts = (int*)NULL ; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// clean all structures +void MarchingCubes::clean_all() +//----------------------------------------------------------------------------- +{ + clean_temps() ; + delete [] _vertices ; + delete [] _triangles ; + _vertices = (Vertex *)NULL ; + _triangles = (Triangle *)NULL ; + _nverts = _ntrigs = 0 ; + _Nverts = _Ntrigs = 0 ; + + _size_x = _size_y = _size_z = -1 ; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +// Compute the intersection points +void MarchingCubes::compute_intersection_points( real iso ) +//----------------------------------------------------------------------------- +{ + for( _k = 0 ; _k < _size_z ; _k++ ) + for( _j = 0 ; _j < _size_y ; _j++ ) + for( _i = 0 ; _i < _size_x ; _i++ ) + { + _cube[0] = get_data( _i, _j, _k ) - iso ; + if( _i < _size_x - 1 ) _cube[1] = get_data(_i+1, _j , _k ) - iso ; + else _cube[1] = _cube[0] ; + + if( _j < _size_y - 1 ) _cube[3] = get_data( _i ,_j+1, _k ) - iso ; + else _cube[3] = _cube[0] ; + + if( _k < _size_z - 1 ) _cube[4] = get_data( _i , _j ,_k+1) - iso ; + else _cube[4] = _cube[0] ; + + if( fabs( _cube[0] ) < FLT_EPSILON ) _cube[0] = FLT_EPSILON ; + if( fabs( _cube[1] ) < FLT_EPSILON ) _cube[1] = FLT_EPSILON ; + if( fabs( _cube[3] ) < FLT_EPSILON ) _cube[3] = FLT_EPSILON ; + if( fabs( _cube[4] ) < FLT_EPSILON ) _cube[4] = FLT_EPSILON ; + + if( _cube[0] < 0 ) + { + if( _cube[1] > 0 ) set_x_vert( add_x_vertex( ), _i,_j,_k ) ; + if( _cube[3] > 0 ) set_y_vert( add_y_vertex( ), _i,_j,_k ) ; + if( _cube[4] > 0 ) set_z_vert( add_z_vertex( ), _i,_j,_k ) ; + } + else + { + if( _cube[1] < 0 ) set_x_vert( add_x_vertex( ), _i,_j,_k ) ; + if( _cube[3] < 0 ) set_y_vert( add_y_vertex( ), _i,_j,_k ) ; + if( _cube[4] < 0 ) set_z_vert( add_z_vertex( ), _i,_j,_k ) ; + } + } +} +//_____________________________________________________________________________ + + + + + +//_____________________________________________________________________________ +// Test a face +// if face>0 return true if the face contains a part of the surface +bool MarchingCubes::test_face( schar face ) +//----------------------------------------------------------------------------- +{ + real A,B,C,D ; + + switch( face ) + { + case -1 : case 1 : A = _cube[0] ; B = _cube[4] ; C = _cube[5] ; D = _cube[1] ; break ; + case -2 : case 2 : A = _cube[1] ; B = _cube[5] ; C = _cube[6] ; D = _cube[2] ; break ; + case -3 : case 3 : A = _cube[2] ; B = _cube[6] ; C = _cube[7] ; D = _cube[3] ; break ; + case -4 : case 4 : A = _cube[3] ; B = _cube[7] ; C = _cube[4] ; D = _cube[0] ; break ; + case -5 : case 5 : A = _cube[0] ; B = _cube[3] ; C = _cube[2] ; D = _cube[1] ; break ; + case -6 : case 6 : A = _cube[4] ; B = _cube[7] ; C = _cube[6] ; D = _cube[5] ; break ; + default : printf( "Invalid face code %d\n", face ) ; print_cube() ; A = B = C = D = 0 ; + }; + + if( fabs( A*C - B*D ) < FLT_EPSILON ) + return face >= 0 ; + return face * A * ( A*C - B*D ) >= 0 ; // face and A invert signs +} +//_____________________________________________________________________________ + + + + + +//_____________________________________________________________________________ +// Test the interior of a cube +// if s == 7, return true if the interior is empty +// if s ==-7, return false if the interior is empty +bool MarchingCubes::test_interior( schar s ) +//----------------------------------------------------------------------------- +{ + real t, At=0, Bt=0, Ct=0, Dt=0, a, b ; + char test = 0 ; + char edge = -1 ; // reference edge of the triangulation + + switch( _case ) + { + case 4 : + case 10 : + a = ( _cube[4] - _cube[0] ) * ( _cube[6] - _cube[2] ) - ( _cube[7] - _cube[3] ) * ( _cube[5] - _cube[1] ) ; + b = _cube[2] * ( _cube[4] - _cube[0] ) + _cube[0] * ( _cube[6] - _cube[2] ) + - _cube[1] * ( _cube[7] - _cube[3] ) - _cube[3] * ( _cube[5] - _cube[1] ) ; + t = - b / (2*a) ; + if( t<0 || t>1 ) return s>0 ; + + At = _cube[0] + ( _cube[4] - _cube[0] ) * t ; + Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; + Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ; + Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; + break ; + + case 6 : + case 7 : + case 12 : + case 13 : + switch( _case ) + { + case 6 : edge = test6 [_config][2] ; break ; + case 7 : edge = test7 [_config][4] ; break ; + case 12 : edge = test12[_config][3] ; break ; + case 13 : edge = tiling13_5_1[_config][_subconfig][0] ; break ; + } + switch( edge ) + { + case 0 : + t = _cube[0] / ( _cube[0] - _cube[1] ) ; + At = 0 ; + Bt = _cube[3] + ( _cube[2] - _cube[3] ) * t ; + Ct = _cube[7] + ( _cube[6] - _cube[7] ) * t ; + Dt = _cube[4] + ( _cube[5] - _cube[4] ) * t ; + break ; + case 1 : + t = _cube[1] / ( _cube[1] - _cube[2] ) ; + At = 0 ; + Bt = _cube[0] + ( _cube[3] - _cube[0] ) * t ; + Ct = _cube[4] + ( _cube[7] - _cube[4] ) * t ; + Dt = _cube[5] + ( _cube[6] - _cube[5] ) * t ; + break ; + case 2 : + t = _cube[2] / ( _cube[2] - _cube[3] ) ; + At = 0 ; + Bt = _cube[1] + ( _cube[0] - _cube[1] ) * t ; + Ct = _cube[5] + ( _cube[4] - _cube[5] ) * t ; + Dt = _cube[6] + ( _cube[7] - _cube[6] ) * t ; + break ; + case 3 : + t = _cube[3] / ( _cube[3] - _cube[0] ) ; + At = 0 ; + Bt = _cube[2] + ( _cube[1] - _cube[2] ) * t ; + Ct = _cube[6] + ( _cube[5] - _cube[6] ) * t ; + Dt = _cube[7] + ( _cube[4] - _cube[7] ) * t ; + break ; + case 4 : + t = _cube[4] / ( _cube[4] - _cube[5] ) ; + At = 0 ; + Bt = _cube[7] + ( _cube[6] - _cube[7] ) * t ; + Ct = _cube[3] + ( _cube[2] - _cube[3] ) * t ; + Dt = _cube[0] + ( _cube[1] - _cube[0] ) * t ; + break ; + case 5 : + t = _cube[5] / ( _cube[5] - _cube[6] ) ; + At = 0 ; + Bt = _cube[4] + ( _cube[7] - _cube[4] ) * t ; + Ct = _cube[0] + ( _cube[3] - _cube[0] ) * t ; + Dt = _cube[1] + ( _cube[2] - _cube[1] ) * t ; + break ; + case 6 : + t = _cube[6] / ( _cube[6] - _cube[7] ) ; + At = 0 ; + Bt = _cube[5] + ( _cube[4] - _cube[5] ) * t ; + Ct = _cube[1] + ( _cube[0] - _cube[1] ) * t ; + Dt = _cube[2] + ( _cube[3] - _cube[2] ) * t ; + break ; + case 7 : + t = _cube[7] / ( _cube[7] - _cube[4] ) ; + At = 0 ; + Bt = _cube[6] + ( _cube[5] - _cube[6] ) * t ; + Ct = _cube[2] + ( _cube[1] - _cube[2] ) * t ; + Dt = _cube[3] + ( _cube[0] - _cube[3] ) * t ; + break ; + case 8 : + t = _cube[0] / ( _cube[0] - _cube[4] ) ; + At = 0 ; + Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; + Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ; + Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; + break ; + case 9 : + t = _cube[1] / ( _cube[1] - _cube[5] ) ; + At = 0 ; + Bt = _cube[0] + ( _cube[4] - _cube[0] ) * t ; + Ct = _cube[3] + ( _cube[7] - _cube[3] ) * t ; + Dt = _cube[2] + ( _cube[6] - _cube[2] ) * t ; + break ; + case 10 : + t = _cube[2] / ( _cube[2] - _cube[6] ) ; + At = 0 ; + Bt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; + Ct = _cube[0] + ( _cube[4] - _cube[0] ) * t ; + Dt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; + break ; + case 11 : + t = _cube[3] / ( _cube[3] - _cube[7] ) ; + At = 0 ; + Bt = _cube[2] + ( _cube[6] - _cube[2] ) * t ; + Ct = _cube[1] + ( _cube[5] - _cube[1] ) * t ; + Dt = _cube[0] + ( _cube[4] - _cube[0] ) * t ; + break ; + default : printf( "Invalid edge %d\n", edge ) ; print_cube() ; break ; + } + break ; + + default : printf( "Invalid ambiguous case %d\n", _case ) ; print_cube() ; break ; + } + + if( At >= 0 ) test ++ ; + if( Bt >= 0 ) test += 2 ; + if( Ct >= 0 ) test += 4 ; + if( Dt >= 0 ) test += 8 ; + switch( test ) + { + case 0 : return s>0 ; + case 1 : return s>0 ; + case 2 : return s>0 ; + case 3 : return s>0 ; + case 4 : return s>0 ; + case 5 : if( At * Ct - Bt * Dt < FLT_EPSILON ) return s>0 ; break ; + case 6 : return s>0 ; + case 7 : return s<0 ; + case 8 : return s>0 ; + case 9 : return s>0 ; + case 10 : if( At * Ct - Bt * Dt >= FLT_EPSILON ) return s>0 ; break ; + case 11 : return s<0 ; + case 12 : return s>0 ; + case 13 : return s<0 ; + case 14 : return s<0 ; + case 15 : return s<0 ; + } + + return s<0 ; +} +//_____________________________________________________________________________ + + + + +//_____________________________________________________________________________ +// Process a unit cube +void MarchingCubes::process_cube( ) +//----------------------------------------------------------------------------- +{ + if( _originalMC ) + { + char nt = 0 ; + while( casesClassic[_lut_entry][3*nt] != -1 ) nt++ ; + add_triangle( casesClassic[_lut_entry], nt ) ; + return ; + } + + int v12 = -1 ; + _case = cases[_lut_entry][0] ; + _config = cases[_lut_entry][1] ; + _subconfig = 0 ; + + switch( _case ) + { + case 0 : + break ; + + case 1 : + add_triangle( tiling1[_config], 1 ) ; + break ; + + case 2 : + add_triangle( tiling2[_config], 2 ) ; + break ; + + case 3 : + if( test_face( test3[_config]) ) + add_triangle( tiling3_2[_config], 4 ) ; // 3.2 + else + add_triangle( tiling3_1[_config], 2 ) ; // 3.1 + break ; + + case 4 : + if( test_interior( test4[_config]) ) + add_triangle( tiling4_1[_config], 2 ) ; // 4.1.1 + else + add_triangle( tiling4_2[_config], 6 ) ; // 4.1.2 + break ; + + case 5 : + add_triangle( tiling5[_config], 3 ) ; + break ; + + case 6 : + if( test_face( test6[_config][0]) ) + add_triangle( tiling6_2[_config], 5 ) ; // 6.2 + else + { + if( test_interior( test6[_config][1]) ) + add_triangle( tiling6_1_1[_config], 3 ) ; // 6.1.1 + else + { + v12 = add_c_vertex() ; + add_triangle( tiling6_1_2[_config], 9 , v12) ; // 6.1.2 + } + } + break ; + + case 7 : + if( test_face( test7[_config][0] ) ) _subconfig += 1 ; + if( test_face( test7[_config][1] ) ) _subconfig += 2 ; + if( test_face( test7[_config][2] ) ) _subconfig += 4 ; + switch( _subconfig ) + { + case 0 : + add_triangle( tiling7_1[_config], 3 ) ; break ; + case 1 : + add_triangle( tiling7_2[_config][0], 5 ) ; break ; + case 2 : + add_triangle( tiling7_2[_config][1], 5 ) ; break ; + case 3 : + v12 = add_c_vertex() ; + add_triangle( tiling7_3[_config][0], 9, v12 ) ; break ; + case 4 : + add_triangle( tiling7_2[_config][2], 5 ) ; break ; + case 5 : + v12 = add_c_vertex() ; + add_triangle( tiling7_3[_config][1], 9, v12 ) ; break ; + case 6 : + v12 = add_c_vertex() ; + add_triangle( tiling7_3[_config][2], 9, v12 ) ; break ; + case 7 : + if( test_interior( test7[_config][3]) ) + add_triangle( tiling7_4_2[_config], 9 ) ; + else + add_triangle( tiling7_4_1[_config], 5 ) ; + break ; + }; + break ; + + case 8 : + add_triangle( tiling8[_config], 2 ) ; + break ; + + case 9 : + add_triangle( tiling9[_config], 4 ) ; + break ; + + case 10 : + if( test_face( test10[_config][0]) ) + { + if( test_face( test10[_config][1]) ) + add_triangle( tiling10_1_1_[_config], 4 ) ; // 10.1.1 + else + { + v12 = add_c_vertex() ; + add_triangle( tiling10_2[_config], 8, v12 ) ; // 10.2 + } + } + else + { + if( test_face( test10[_config][1]) ) + { + v12 = add_c_vertex() ; + add_triangle( tiling10_2_[_config], 8, v12 ) ; // 10.2 + } + else + { + if( test_interior( test10[_config][2]) ) + add_triangle( tiling10_1_1[_config], 4 ) ; // 10.1.1 + else + add_triangle( tiling10_1_2[_config], 8 ) ; // 10.1.2 + } + } + break ; + + case 11 : + add_triangle( tiling11[_config], 4 ) ; + break ; + + case 12 : + if( test_face( test12[_config][0]) ) + { + if( test_face( test12[_config][1]) ) + add_triangle( tiling12_1_1_[_config], 4 ) ; // 12.1.1 + else + { + v12 = add_c_vertex() ; + add_triangle( tiling12_2[_config], 8, v12 ) ; // 12.2 + } + } + else + { + if( test_face( test12[_config][1]) ) + { + v12 = add_c_vertex() ; + add_triangle( tiling12_2_[_config], 8, v12 ) ; // 12.2 + } + else + { + if( test_interior( test12[_config][2]) ) + add_triangle( tiling12_1_1[_config], 4 ) ; // 12.1.1 + else + add_triangle( tiling12_1_2[_config], 8 ) ; // 12.1.2 + } + } + break ; + + case 13 : + if( test_face( test13[_config][0] ) ) _subconfig += 1 ; + if( test_face( test13[_config][1] ) ) _subconfig += 2 ; + if( test_face( test13[_config][2] ) ) _subconfig += 4 ; + if( test_face( test13[_config][3] ) ) _subconfig += 8 ; + if( test_face( test13[_config][4] ) ) _subconfig += 16 ; + if( test_face( test13[_config][5] ) ) _subconfig += 32 ; + switch( subconfig13[_subconfig] ) + { + case 0 :/* 13.1 */ + add_triangle( tiling13_1[_config], 4 ) ; break ; + + case 1 :/* 13.2 */ + add_triangle( tiling13_2[_config][0], 6 ) ; break ; + case 2 :/* 13.2 */ + add_triangle( tiling13_2[_config][1], 6 ) ; break ; + case 3 :/* 13.2 */ + add_triangle( tiling13_2[_config][2], 6 ) ; break ; + case 4 :/* 13.2 */ + add_triangle( tiling13_2[_config][3], 6 ) ; break ; + case 5 :/* 13.2 */ + add_triangle( tiling13_2[_config][4], 6 ) ; break ; + case 6 :/* 13.2 */ + add_triangle( tiling13_2[_config][5], 6 ) ; break ; + + case 7 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][0], 10, v12 ) ; break ; + case 8 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][1], 10, v12 ) ; break ; + case 9 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][2], 10, v12 ) ; break ; + case 10 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][3], 10, v12 ) ; break ; + case 11 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][4], 10, v12 ) ; break ; + case 12 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][5], 10, v12 ) ; break ; + case 13 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][6], 10, v12 ) ; break ; + case 14 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][7], 10, v12 ) ; break ; + case 15 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][8], 10, v12 ) ; break ; + case 16 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][9], 10, v12 ) ; break ; + case 17 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][10], 10, v12 ) ; break ; + case 18 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3[_config][11], 10, v12 ) ; break ; + + case 19 :/* 13.4 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_4[_config][0], 12, v12 ) ; break ; + case 20 :/* 13.4 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_4[_config][1], 12, v12 ) ; break ; + case 21 :/* 13.4 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_4[_config][2], 12, v12 ) ; break ; + case 22 :/* 13.4 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_4[_config][3], 12, v12 ) ; break ; + + case 23 :/* 13.5 */ + _subconfig = 0 ; + if( test_interior( test13[_config][6] ) ) + add_triangle( tiling13_5_1[_config][0], 6 ) ; + else + add_triangle( tiling13_5_2[_config][0], 10 ) ; + break ; + case 24 :/* 13.5 */ + _subconfig = 1 ; + if( test_interior( test13[_config][6] ) ) + add_triangle( tiling13_5_1[_config][1], 6 ) ; + else + add_triangle( tiling13_5_2[_config][1], 10 ) ; + break ; + case 25 :/* 13.5 */ + _subconfig = 2 ; + if( test_interior( test13[_config][6] ) ) + add_triangle( tiling13_5_1[_config][2], 6 ) ; + else + add_triangle( tiling13_5_2[_config][2], 10 ) ; + break ; + case 26 :/* 13.5 */ + _subconfig = 3 ; + if( test_interior( test13[_config][6] ) ) + add_triangle( tiling13_5_1[_config][3], 6 ) ; + else + add_triangle( tiling13_5_2[_config][3], 10 ) ; + break ; + + case 27 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][0], 10, v12 ) ; break ; + case 28 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][1], 10, v12 ) ; break ; + case 29 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][2], 10, v12 ) ; break ; + case 30 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][3], 10, v12 ) ; break ; + case 31 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][4], 10, v12 ) ; break ; + case 32 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][5], 10, v12 ) ; break ; + case 33 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][6], 10, v12 ) ; break ; + case 34 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][7], 10, v12 ) ; break ; + case 35 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][8], 10, v12 ) ; break ; + case 36 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][9], 10, v12 ) ; break ; + case 37 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][10], 10, v12 ) ; break ; + case 38 :/* 13.3 */ + v12 = add_c_vertex() ; + add_triangle( tiling13_3_[_config][11], 10, v12 ) ; break ; + + case 39 :/* 13.2 */ + add_triangle( tiling13_2_[_config][0], 6 ) ; break ; + case 40 :/* 13.2 */ + add_triangle( tiling13_2_[_config][1], 6 ) ; break ; + case 41 :/* 13.2 */ + add_triangle( tiling13_2_[_config][2], 6 ) ; break ; + case 42 :/* 13.2 */ + add_triangle( tiling13_2_[_config][3], 6 ) ; break ; + case 43 :/* 13.2 */ + add_triangle( tiling13_2_[_config][4], 6 ) ; break ; + case 44 :/* 13.2 */ + add_triangle( tiling13_2_[_config][5], 6 ) ; break ; + + case 45 :/* 13.1 */ + add_triangle( tiling13_1_[_config], 4 ) ; break ; + + default : + printf("Marching Cubes: Impossible case 13?\n" ) ; print_cube() ; + } + break ; + + case 14 : + add_triangle( tiling14[_config], 4 ) ; + break ; + }; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// Adding triangles +void MarchingCubes::add_triangle( const char* trig, char n, int v12 ) +//----------------------------------------------------------------------------- +{ + int tv[3] ; + + for( int t = 0 ; t < 3*n ; t++ ) + { + switch( trig[t] ) + { + case 0 : tv[ t % 3 ] = get_x_vert( _i , _j , _k ) ; break ; + case 1 : tv[ t % 3 ] = get_y_vert(_i+1, _j , _k ) ; break ; + case 2 : tv[ t % 3 ] = get_x_vert( _i ,_j+1, _k ) ; break ; + case 3 : tv[ t % 3 ] = get_y_vert( _i , _j , _k ) ; break ; + case 4 : tv[ t % 3 ] = get_x_vert( _i , _j ,_k+1) ; break ; + case 5 : tv[ t % 3 ] = get_y_vert(_i+1, _j ,_k+1) ; break ; + case 6 : tv[ t % 3 ] = get_x_vert( _i ,_j+1,_k+1) ; break ; + case 7 : tv[ t % 3 ] = get_y_vert( _i , _j ,_k+1) ; break ; + case 8 : tv[ t % 3 ] = get_z_vert( _i , _j , _k ) ; break ; + case 9 : tv[ t % 3 ] = get_z_vert(_i+1, _j , _k ) ; break ; + case 10 : tv[ t % 3 ] = get_z_vert(_i+1,_j+1, _k ) ; break ; + case 11 : tv[ t % 3 ] = get_z_vert( _i ,_j+1, _k ) ; break ; + case 12 : tv[ t % 3 ] = v12 ; break ; + default : break ; + } + + if( tv[t%3] == -1 ) + { + printf("Marching Cubes: invalid triangle %d\n", _ntrigs+1) ; + print_cube() ; + } + + if( t%3 == 2 ) + { + if( _ntrigs >= _Ntrigs ) + { + Triangle *temp = _triangles ; + _triangles = new Triangle[ 2*_Ntrigs ] ; + memcpy( _triangles, temp, _Ntrigs*sizeof(Triangle) ) ; + delete[] temp ; + printf("%d allocated triangles\n", _Ntrigs) ; + _Ntrigs *= 2 ; + } + + Triangle *T = _triangles + _ntrigs++ ; + T->v1 = tv[0] ; + T->v2 = tv[1] ; + T->v3 = tv[2] ; + } + } +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// Calculating gradient + +real MarchingCubes::get_x_grad( const int i, const int j, const int k ) const +//----------------------------------------------------------------------------- +{ + if( i > 0 ) + { + if ( i < _size_x - 1 ) + return ( get_data( i+1, j, k ) - get_data( i-1, j, k ) ) / 2 ; + else + return get_data( i, j, k ) - get_data( i-1, j, k ) ; + } + else + return get_data( i+1, j, k ) - get_data( i, j, k ) ; +} +//----------------------------------------------------------------------------- + +real MarchingCubes::get_y_grad( const int i, const int j, const int k ) const +//----------------------------------------------------------------------------- +{ + if( j > 0 ) + { + if ( j < _size_y - 1 ) + return ( get_data( i, j+1, k ) - get_data( i, j-1, k ) ) / 2 ; + else + return get_data( i, j, k ) - get_data( i, j-1, k ) ; + } + else + return get_data( i, j+1, k ) - get_data( i, j, k ) ; +} +//----------------------------------------------------------------------------- + +real MarchingCubes::get_z_grad( const int i, const int j, const int k ) const +//----------------------------------------------------------------------------- +{ + if( k > 0 ) + { + if ( k < _size_z - 1 ) + return ( get_data( i, j, k+1 ) - get_data( i, j, k-1 ) ) / 2 ; + else + return get_data( i, j, k ) - get_data( i, j, k-1 ) ; + } + else + return get_data( i, j, k+1 ) - get_data( i, j, k ) ; +} +//_____________________________________________________________________________ + + +//_____________________________________________________________________________ +// Adding vertices + +void MarchingCubes::test_vertex_addition() +{ + if( _nverts >= _Nverts ) + { + Vertex *temp = _vertices ; + _vertices = new Vertex[ _Nverts*2 ] ; + memcpy( _vertices, temp, _Nverts*sizeof(Vertex) ) ; + delete[] temp ; + printf("%d allocated vertices\n", _Nverts) ; + _Nverts *= 2 ; + } +} + + +int MarchingCubes::add_x_vertex( ) +//----------------------------------------------------------------------------- +{ + test_vertex_addition() ; + Vertex *vert = _vertices + _nverts++ ; + + real u = ( _cube[0] ) / ( _cube[0] - _cube[1] ) ; + + vert->x = (real)_i+u; + vert->y = (real) _j ; + vert->z = (real) _k ; + + vert->nx = (1-u)*get_x_grad(_i,_j,_k) + u*get_x_grad(_i+1,_j,_k) ; + vert->ny = (1-u)*get_y_grad(_i,_j,_k) + u*get_y_grad(_i+1,_j,_k) ; + vert->nz = (1-u)*get_z_grad(_i,_j,_k) + u*get_z_grad(_i+1,_j,_k) ; + + u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ; + if( u > 0 ) + { + vert->nx /= u ; + vert->ny /= u ; + vert->nz /= u ; + } + + + return _nverts-1 ; +} +//----------------------------------------------------------------------------- + +int MarchingCubes::add_y_vertex( ) +//----------------------------------------------------------------------------- +{ + test_vertex_addition() ; + Vertex *vert = _vertices + _nverts++ ; + + real u = ( _cube[0] ) / ( _cube[0] - _cube[3] ) ; + + vert->x = (real) _i ; + vert->y = (real)_j+u; + vert->z = (real) _k ; + + vert->nx = (1-u)*get_x_grad(_i,_j,_k) + u*get_x_grad(_i,_j+1,_k) ; + vert->ny = (1-u)*get_y_grad(_i,_j,_k) + u*get_y_grad(_i,_j+1,_k) ; + vert->nz = (1-u)*get_z_grad(_i,_j,_k) + u*get_z_grad(_i,_j+1,_k) ; + + u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ; + if( u > 0 ) + { + vert->nx /= u ; + vert->ny /= u ; + vert->nz /= u ; + } + + return _nverts-1 ; +} +//----------------------------------------------------------------------------- + +int MarchingCubes::add_z_vertex( ) +//----------------------------------------------------------------------------- +{ + test_vertex_addition() ; + Vertex *vert = _vertices + _nverts++ ; + + real u = ( _cube[0] ) / ( _cube[0] - _cube[4] ) ; + + vert->x = (real) _i ; + vert->y = (real) _j ; + vert->z = (real)_k+u; + + vert->nx = (1-u)*get_x_grad(_i,_j,_k) + u*get_x_grad(_i,_j,_k+1) ; + vert->ny = (1-u)*get_y_grad(_i,_j,_k) + u*get_y_grad(_i,_j,_k+1) ; + vert->nz = (1-u)*get_z_grad(_i,_j,_k) + u*get_z_grad(_i,_j,_k+1) ; + + u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ; + if( u > 0 ) + { + vert->nx /= u ; + vert->ny /= u ; + vert->nz /= u ; + } + + return _nverts-1 ; +} + + +int MarchingCubes::add_c_vertex( ) +//----------------------------------------------------------------------------- +{ + test_vertex_addition() ; + Vertex *vert = _vertices + _nverts++ ; + + real u = 0 ; + int vid ; + + vert->x = vert->y = vert->z = vert->nx = vert->ny = vert->nz = 0 ; + + // Computes the average of the intersection points of the cube + vid = get_x_vert( _i , _j , _k ) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_y_vert(_i+1, _j , _k ) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_x_vert( _i ,_j+1, _k ) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_y_vert( _i , _j , _k ) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_x_vert( _i , _j ,_k+1) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_y_vert(_i+1, _j ,_k+1) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_x_vert( _i ,_j+1,_k+1) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_y_vert( _i , _j ,_k+1) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_z_vert( _i , _j , _k ) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_z_vert(_i+1, _j , _k ) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_z_vert(_i+1,_j+1, _k ) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + vid = get_z_vert( _i ,_j+1, _k ) ; + if( vid != -1 ) { ++u ; const Vertex &v = _vertices[vid] ; vert->x += v.x ; vert->y += v.y ; vert->z += v.z ; vert->nx += v.nx ; vert->ny += v.ny ; vert->nz += v.nz ; } + + vert->x /= u ; + vert->y /= u ; + vert->z /= u ; + + u = (real) sqrt( vert->nx * vert->nx + vert->ny * vert->ny +vert->nz * vert->nz ) ; + if( u > 0 ) + { + vert->nx /= u ; + vert->ny /= u ; + vert->nz /= u ; + } + + return _nverts-1 ; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +//_____________________________________________________________________________ + + + + +//_____________________________________________________________________________ +// Grid exportation +void MarchingCubes::writeISO(const char *fn ) +//----------------------------------------------------------------------------- +{ + unsigned char buf[sizeof(float)] ; + + FILE *fp = fopen( fn, "wb" ) ; + + // header + * (int*) buf = _size_x ; + fwrite(buf, sizeof(float), 1, fp); + * (int*) buf = _size_y ; + fwrite(buf, sizeof(float), 1, fp); + * (int*) buf = _size_z ; + fwrite(buf, sizeof(float), 1, fp); + + * (float*) buf = -1.0f ; + fwrite(buf, sizeof(float), 1, fp); + * (float*) buf = 1.0f ; + fwrite(buf, sizeof(float), 1, fp); + * (float*) buf = -1.0f ; + fwrite(buf, sizeof(float), 1, fp); + * (float*) buf = 1.0f ; + fwrite(buf, sizeof(float), 1, fp); + * (float*) buf = -1.0f ; + fwrite(buf, sizeof(float), 1, fp); + * (float*) buf = 1.0f ; + fwrite(buf, sizeof(float), 1, fp); + + for( int i = 0 ; i < _size_x ; i++ ) + { + for( int j = 0 ; j < _size_y ; j++ ) + { + for( int k = 0 ; k < _size_z ; k++ ) + { + * (float*) buf = (float)get_data( i,j,k ) ; + fwrite(buf, sizeof(float), 1, fp); + } + } + } + + fclose(fp) ; +} +//_____________________________________________________________________________ + + + + + +//_____________________________________________________________________________ +// PLY exportation +void MarchingCubes::writePLY(const char *fn, bool bin ) +//----------------------------------------------------------------------------- +{ + + typedef struct PlyFace { + unsigned char nverts; /* number of Vertex indices in list */ + int *verts; /* Vertex index list */ + } PlyFace; + + + PlyProperty vert_props[] = { /* list of property information for a PlyVertex */ + {"x", Float32, Float32, offsetof( Vertex,x ), 0, 0, 0, 0}, + {"y", Float32, Float32, offsetof( Vertex,y ), 0, 0, 0, 0}, + {"z", Float32, Float32, offsetof( Vertex,z ), 0, 0, 0, 0}, + {"nx", Float32, Float32, offsetof( Vertex,nx ), 0, 0, 0, 0}, + {"ny", Float32, Float32, offsetof( Vertex,ny ), 0, 0, 0, 0}, + {"nz", Float32, Float32, offsetof( Vertex,nz ), 0, 0, 0, 0} + }; + + PlyProperty face_props[] = { /* list of property information for a PlyFace */ + {"vertex_indices", Int32, Int32, offsetof( PlyFace,verts ), + 1, Uint8, Uint8, offsetof( PlyFace,nverts )}, + }; + + + PlyFile *ply; + FILE *fp = fopen( fn, "w" ); + + int i ; + PlyFace face ; + int verts[3] ; + char *elem_names[] = { "vertex", "face" }; + printf("Marching Cubes::writePLY(%s)...", fn ) ; + ply = write_ply ( fp, 2, elem_names, bin? PLY_BINARY_LE : PLY_ASCII ); + + /* describe what properties go into the PlyVertex elements */ + describe_element_ply ( ply, "vertex", _nverts ); + describe_property_ply ( ply, &vert_props[0] ); + describe_property_ply ( ply, &vert_props[1] ); + describe_property_ply ( ply, &vert_props[2] ); + describe_property_ply ( ply, &vert_props[3] ); + describe_property_ply ( ply, &vert_props[4] ); + describe_property_ply ( ply, &vert_props[5] ); + + /* describe PlyFace properties (just list of PlyVertex indices) */ + describe_element_ply ( ply, "face", _ntrigs ); + describe_property_ply ( ply, &face_props[0] ); + + header_complete_ply ( ply ); + + /* set up and write the PlyVertex elements */ + put_element_setup_ply ( ply, "vertex" ); + for ( i = 0; i < _nverts; i++ ) + put_element_ply ( ply, ( void * ) &(_vertices[i]) ); + printf(" %d vertices written\n", _nverts ) ; + + /* set up and write the PlyFace elements */ + put_element_setup_ply ( ply, "face" ); + face.nverts = 3 ; + face.verts = verts ; + for ( i = 0; i < _ntrigs; i++ ) + { + face.verts[0] = _triangles[i].v1 ; + face.verts[1] = _triangles[i].v2 ; + face.verts[2] = _triangles[i].v3 ; + put_element_ply ( ply, ( void * ) &face ); + } + printf(" %d triangles written\n", _ntrigs ) ; + + close_ply ( ply ); + free_ply ( ply ); + fclose( fp ) ; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// PLY importation +void MarchingCubes::readPLY(const char *fn ) +//----------------------------------------------------------------------------- +{ + typedef struct PlyFace { + unsigned char nverts; /* number of Vertex indices in list */ + int *verts; /* Vertex index list */ + } PlyFace; + + + PlyProperty vert_props[] = { /* list of property information for a PlyVertex */ + {"x", Float32, Float32, offsetof( Vertex,x ), 0, 0, 0, 0}, + {"y", Float32, Float32, offsetof( Vertex,y ), 0, 0, 0, 0}, + {"z", Float32, Float32, offsetof( Vertex,z ), 0, 0, 0, 0}, + {"nx", Float32, Float32, offsetof( Vertex,nx ), 0, 0, 0, 0}, + {"ny", Float32, Float32, offsetof( Vertex,ny ), 0, 0, 0, 0}, + {"nz", Float32, Float32, offsetof( Vertex,nz ), 0, 0, 0, 0} + }; + + PlyProperty face_props[] = { /* list of property information for a PlyFace */ + {"vertex_indices", Int32, Int32, offsetof( PlyFace,verts ), + 1, Uint8, Uint8, offsetof( PlyFace,nverts )}, + }; + + + FILE *fp = fopen( fn, "r" ); + if( !fp ) return ; + PlyFile *ply = read_ply ( fp ); + printf("Marching Cubes::readPLY(%s)...", fn ) ; + + //----------------------------------------------------------------------------- + + // gets the number of faces and vertices + for ( int i = 0; i < ply->num_elem_types; ++i ) + { + int elem_count ; + char *elem_name = setup_element_read_ply ( ply, i, &elem_count ); + if ( equal_strings ( "vertex", elem_name ) ) + _Nverts = _nverts = elem_count; + if ( equal_strings ( "face", elem_name ) ) + _Ntrigs = _ntrigs = elem_count; + } + delete [] _vertices ; + _vertices = new Vertex [_Nverts] ; + delete [] _triangles ; + _triangles = new Triangle[_Ntrigs] ; + + //----------------------------------------------------------------------------- + + /* examine each element type that is in the file (PlyVertex, PlyFace) */ + + for ( int i = 0; i < ply->num_elem_types; ++i ) + { + /* prepare to read the i'th list of elements */ + int elem_count ; + char *elem_name = setup_element_read_ply ( ply, i, &elem_count ); + + //----------------------------------------------------------------------------- + if ( equal_strings ( "vertex", elem_name ) ) + { + /* set up for getting PlyVertex elements */ + setup_property_ply ( ply, &vert_props[0] ); + setup_property_ply ( ply, &vert_props[1] ); + setup_property_ply ( ply, &vert_props[2] ); + setup_property_ply ( ply, &vert_props[3] ); + setup_property_ply ( ply, &vert_props[4] ); + setup_property_ply ( ply, &vert_props[5] ); + + for ( int j = 0; j < _nverts; ++j ) + { + get_element_ply ( ply, ( void * ) (_vertices + j) ); + } + printf(" %d vertices read\n", _nverts ) ; + } + + //----------------------------------------------------------------------------- + else if ( equal_strings ( "face", elem_name ) ) + { + /* set up for getting PlyFace elements */ + /* (all we need are PlyVertex indices) */ + + setup_property_ply ( ply, &face_props[0] ) ; + PlyFace face ; + for ( int j = 0; j < _ntrigs; ++j ) + { + get_element_ply ( ply, ( void * ) &face ); + if( face.nverts != 3 ) + { + printf( "not a triangulated surface: polygon %d has %d sides\n", j, face.nverts ) ; + return ; + } + + _triangles[j].v1 = face.verts[0] ; + _triangles[j].v2 = face.verts[1] ; + _triangles[j].v3 = face.verts[2] ; + + free( face.verts ) ; + } + printf(" %d triangles read\n", _ntrigs ) ; + } + //----------------------------------------------------------------------------- + + //----------------------------------------------------------------------------- + else /* all non-PlyVertex and non-PlyFace elements are grabbed here */ + get_other_element_ply ( ply ); + //----------------------------------------------------------------------------- + } + + close_ply ( ply ); + free_ply ( ply ); + +// fit_to_bbox() ; + fclose( fp ) ; +} +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +// Open Inventor / VRML 1.0 ascii exportation +void MarchingCubes::writeIV(const char *fn ) +//----------------------------------------------------------------------------- +{ + FILE *fp = fopen( fn, "w" ) ; + int i ; + + printf("Marching Cubes::exportIV(%s)...", fn) ; + + fprintf( fp, "#Inventor V2.1 ascii \n\nSeparator { \n ShapeHints {\n vertexOrdering COUNTERCLOCKWISE\n shapeType UNKNOWN_SHAPE_TYPE\n creaseAngle 0.0\n }\n Coordinate3 { \n point [ \n" ) ; + for ( i = 0; i < _nverts; i++ ) + fprintf( fp, " %f %f %f,\n", _vertices[i].x, _vertices[i].y, _vertices[i].z ) ; + printf(" %d vertices written\n", _nverts ) ; + + fprintf( fp, "\n ] \n} \nNormal { \nvector [ \n" ) ; + for ( i = 0; i < _nverts; i++ ) + fprintf( fp, " %f %f %f,\n", _vertices[i].nx, _vertices[i].ny, _vertices[i].nz ) ; + + fprintf( fp, "\n ] \n} \nIndexedFaceSet { \ncoordIndex [ \n" ) ; + for ( i = 0; i < _ntrigs; i++ ) + fprintf( fp, "%d, %d, %d, -1,\n", _triangles[i].v1, _triangles[i].v2, _triangles[i].v3 ) ; + + fprintf( fp, " ] \n } \n } \n" ) ; + fclose( fp ) ; + printf(" %d triangles written\n", _ntrigs ) ; +} +//_____________________________________________________________________________ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/MarchingCubes.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/MarchingCubes.h new file mode 100755 index 0000000000000000000000000000000000000000..c589bffb7f52d6574763fcdc8947f5539e0871a7 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/MarchingCubes.h @@ -0,0 +1,343 @@ +/** + * @file MarchingCubes.h + * @author Thomas Lewiner <thomas.lewiner@polytechnique.org> + * @author Math Dept, PUC-Rio + * @version 0.2 + * @date 12/08/2002 + * + * @brief MarchingCubes Algorithm + */ +//________________________________________________ + + +#ifndef _MARCHINGCUBES_H_ +#define _MARCHINGCUBES_H_ + +#if !defined(WIN32) || defined(__CYGWIN__) +#pragma interface +#endif // WIN32 + + +//_____________________________________________________________________________ +// types +/** unsigned char alias */ +typedef unsigned char uchar ; +/** signed char alias */ +typedef signed char schar ; +/** isovalue alias */ +typedef float real ; + +//----------------------------------------------------------------------------- +// Vertex structure +/** \struct Vertex "MarchingCubes.h" MarchingCubes + * Position and normal of a vertex + * \brief vertex structure + * \param x X coordinate + * \param y Y coordinate + * \param z Z coordinate + * \param nx X component of the normal + * \param ny Y component of the normal + * \param nz Z component of the normal + */ +typedef struct +{ + real x, y, z ; /**< Vertex coordinates */ + real nx, ny, nz ; /**< Vertex normal */ +} Vertex ; + +//----------------------------------------------------------------------------- +// Triangle structure +/** \struct Triangle "MarchingCubes.h" MarchingCubes + * Indices of the oriented triange vertices + * \brief triangle structure + * \param v1 First vertex index + * \param v2 Second vertex index + * \param v3 Third vertex index + */ +typedef struct +{ + int v1,v2,v3 ; /**< Triangle vertices */ +} Triangle ; +//_____________________________________________________________________________ + + + +//_____________________________________________________________________________ +/** Marching Cubes algorithm wrapper */ +/** \class MarchingCubes + * \brief Marching Cubes algorithm. + */ +class MarchingCubes +//----------------------------------------------------------------------------- +{ +// Constructors +public : + /** + * Main and default constructor + * \brief constructor + * \param size_x width of the grid + * \param size_y depth of the grid + * \param size_z height of the grid + */ + MarchingCubes ( const int size_x = -1, const int size_y = -1, const int size_z = -1 ) ; + /** Destructor */ + ~MarchingCubes() ; + +//----------------------------------------------------------------------------- +// Accessors +public : + /** accesses the number of vertices of the generated mesh */ + inline const int nverts() const { return _nverts ; } + /** accesses the number of triangles of the generated mesh */ + inline const int ntrigs() const { return _ntrigs ; } + /** accesses a specific vertex of the generated mesh */ + inline Vertex * vert( const int i ) const { if( i < 0 || i >= _nverts ) return ( Vertex *)NULL ; return _vertices + i ; } + /** accesses a specific triangle of the generated mesh */ + inline Triangle * trig( const int i ) const { if( i < 0 || i >= _ntrigs ) return (Triangle*)NULL ; return _triangles + i ; } + + /** accesses the vertex buffer of the generated mesh */ + inline Vertex *vertices () { return _vertices ; } + /** accesses the triangle buffer of the generated mesh */ + inline Triangle *triangles() { return _triangles ; } + + /** accesses the width of the grid */ + inline const int size_x() const { return _size_x ; } + /** accesses the depth of the grid */ + inline const int size_y() const { return _size_y ; } + /** accesses the height of the grid */ + inline const int size_z() const { return _size_z ; } + + /** + * changes the size of the grid + * \param size_x width of the grid + * \param size_y depth of the grid + * \param size_z height of the grid + */ + inline void set_resolution( const int size_x, const int size_y, const int size_z ) { _size_x = size_x ; _size_y = size_y ; _size_z = size_z ; } + /** + * selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes + * \param originalMC true for the original Marching Cubes + */ + inline void set_method ( const bool originalMC = false ) { _originalMC = originalMC ; } + /** + * selects to use data from another class + * \param data is the pointer to the external data, allocated as a size_x*size_y*size_z vector running in x first + */ + inline void set_ext_data ( real *data ) + { if( !_ext_data ) delete [] _data ; _ext_data = data != NULL ; if( _ext_data ) _data = data ; } + /** + * selects to allocate data + */ + inline void set_int_data () { _ext_data = false ; _data = NULL ; } + + // Data access + /** + * accesses a specific cube of the grid + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + inline const real get_data ( const int i, const int j, const int k ) const { return _data[ i + j*_size_x + k*_size_x*_size_y] ; } + /** + * sets a specific cube of the grid + * \param val new value for the cube + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + inline void set_data ( const real val, const int i, const int j, const int k ) { _data[ i + j*_size_x + k*_size_x*_size_y] = val ; } + + // Data initialization + /** inits temporary structures (must set sizes before call) : the grid and the vertex index per cube */ + void init_temps () ; + /** inits all structures (must set sizes before call) : the temporary structures and the mesh buffers */ + void init_all () ; + /** clears temporary structures : the grid and the main */ + void clean_temps() ; + /** clears all structures : the temporary structures and the mesh buffers */ + void clean_all () ; + + +//----------------------------------------------------------------------------- +// Exportation +public : + /** + * PLY exportation of the generated mesh + * \param fn name of the PLY file to create + * \param bin if true, the PLY will be written in binary mode + */ + void writePLY( const char *fn, bool bin = false ) ; + + /** + * PLY importation of a mesh + * \param fn name of the PLY file to read from + */ + void readPLY( const char *fn ) ; + + /** + * VRML / Open Inventor exportation of the generated mesh + * \param fn name of the IV file to create + */ + void writeIV ( const char *fn ) ; + + /** + * ISO exportation of the input grid + * \param fn name of the ISO file to create + */ + void writeISO( const char *fn ) ; + + +//----------------------------------------------------------------------------- +// Algorithm +public : + /** + * Main algorithm : must be called after init_all + * \param iso isovalue + */ + void run( real iso = (real)0.0 ) ; + +protected : + /** tesselates one cube */ + void process_cube () ; + /** tests if the components of the tesselation of the cube should be connected by the interior of an ambiguous face */ + bool test_face ( schar face ) ; + /** tests if the components of the tesselation of the cube should be connected through the interior of the cube */ + bool test_interior( schar s ) ; + + +//----------------------------------------------------------------------------- +// Operations +protected : + /** + * computes almost all the vertices of the mesh by interpolation along the cubes edges + * \param iso isovalue + */ + void compute_intersection_points( real iso ) ; + + /** + * routine to add a triangle to the mesh + * \param trig the code for the triangle as a sequence of edges index + * \param n the number of triangles to produce + * \param v12 the index of the interior vertex to use, if necessary + */ + void add_triangle ( const char* trig, char n, int v12 = -1 ) ; + + /** tests and eventually doubles the vertex buffer capacity for a new vertex insertion */ + void test_vertex_addition() ; + /** adds a vertex on the current horizontal edge */ + int add_x_vertex() ; + /** adds a vertex on the current longitudinal edge */ + int add_y_vertex() ; + /** adds a vertex on the current vertical edge */ + int add_z_vertex() ; + /** adds a vertex inside the current cube */ + int add_c_vertex() ; + + /** + * interpolates the horizontal gradient of the implicit function at the lower vertex of the specified cube + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + real get_x_grad( const int i, const int j, const int k ) const ; + /** + * interpolates the longitudinal gradient of the implicit function at the lower vertex of the specified cube + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + real get_y_grad( const int i, const int j, const int k ) const ; + /** + * interpolates the vertical gradient of the implicit function at the lower vertex of the specified cube + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + real get_z_grad( const int i, const int j, const int k ) const ; + + /** + * accesses the pre-computed vertex index on the lower horizontal edge of a specific cube + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + inline int get_x_vert( const int i, const int j, const int k ) const { return _x_verts[ i + j*_size_x + k*_size_x*_size_y] ; } + /** + * accesses the pre-computed vertex index on the lower longitudinal edge of a specific cube + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + inline int get_y_vert( const int i, const int j, const int k ) const { return _y_verts[ i + j*_size_x + k*_size_x*_size_y] ; } + /** + * accesses the pre-computed vertex index on the lower vertical edge of a specific cube + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + inline int get_z_vert( const int i, const int j, const int k ) const { return _z_verts[ i + j*_size_x + k*_size_x*_size_y] ; } + + /** + * sets the pre-computed vertex index on the lower horizontal edge of a specific cube + * \param val the index of the new vertex + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + inline void set_x_vert( const int val, const int i, const int j, const int k ) { _x_verts[ i + j*_size_x + k*_size_x*_size_y] = val ; } + /** + * sets the pre-computed vertex index on the lower longitudinal edge of a specific cube + * \param val the index of the new vertex + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + inline void set_y_vert( const int val, const int i, const int j, const int k ) { _y_verts[ i + j*_size_x + k*_size_x*_size_y] = val ; } + /** + * sets the pre-computed vertex index on the lower vertical edge of a specific cube + * \param val the index of the new vertex + * \param i abscisse of the cube + * \param j ordinate of the cube + * \param k height of the cube + */ + inline void set_z_vert( const int val, const int i, const int j, const int k ) { _z_verts[ i + j*_size_x + k*_size_x*_size_y] = val ; } + + /** prints cube for debug */ + void print_cube() ; + +//----------------------------------------------------------------------------- +// Elements +protected : + bool _originalMC ; /**< selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes */ + bool _ext_data ; /**< selects wether to allocate data or use data from another class */ + + int _size_x ; /**< width of the grid */ + int _size_y ; /**< depth of the grid */ + int _size_z ; /**< height of the grid */ + real *_data ; /**< implicit function values sampled on the grid */ + + int *_x_verts ; /**< pre-computed vertex indices on the lower horizontal edge of each cube */ + int *_y_verts ; /**< pre-computed vertex indices on the lower longitudinal edge of each cube */ + int *_z_verts ; /**< pre-computed vertex indices on the lower vertical edge of each cube */ + + int _nverts ; /**< number of allocated vertices in the vertex buffer */ + int _ntrigs ; /**< number of allocated triangles in the triangle buffer */ + int _Nverts ; /**< size of the vertex buffer */ + int _Ntrigs ; /**< size of the triangle buffer */ + Vertex *_vertices ; /**< vertex buffer */ + Triangle *_triangles ; /**< triangle buffer */ + + int _i ; /**< abscisse of the active cube */ + int _j ; /**< height of the active cube */ + int _k ; /**< ordinate of the active cube */ + + real _cube[8] ; /**< values of the implicit function on the active cube */ + uchar _lut_entry ; /**< cube sign representation in [0..255] */ + uchar _case ; /**< case of the active cube in [0..15] */ + uchar _config ; /**< configuration of the active cube */ + uchar _subconfig ; /**< subconfiguration of the active cube */ +}; +//_____________________________________________________________________________ + + +#endif // _MARCHINGCUBES_H_ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/ply.c b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/ply.c new file mode 100755 index 0000000000000000000000000000000000000000..06c60f4dbb863fa79c88ac5336c3498adfecb99b --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/ply.c @@ -0,0 +1,3325 @@ +/* + +The interface routines for reading and writing PLY polygon files. + +Greg Turk + +--------------------------------------------------------------- + +A PLY file contains a single polygonal _object_. + +An object is composed of lists of _elements_. Typical elements are +vertices, faces, edges and materials. + +Each type of element for a given object has one or more _properties_ +associated with the element type. For instance, a vertex element may +have as properties the floating-point values x,y,z and the three unsigned +chars representing red, green and blue. + +----------------------------------------------------------------------- + +Copyright (c) 1998 Georgia Institute of Technology. All rights reserved. + +Permission to use, copy, modify and distribute this software and its +documentation for any purpose is hereby granted without fee, provided +that the above copyright notice and this permission notice appear in +all copies of this software and that you do not sell the software. + +THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> +#include "ply.h" + +char *type_names[] = { /* names of scalar types */ +"invalid", +"int8", "int16", "int32", "uint8", "uint16", "uint32", "float32", "float64", +}; + +char *old_type_names[] = { /* old names of types for backward compatability */ +"invalid", +"char", "short", "int", "uchar", "ushort", "uint", "float", "double", +}; + +int ply_type_size[] = { +0, 1, 2, 4, 1, 2, 4, 4, 8 +}; + +#define NO_OTHER_PROPS -1 + +#define DONT_STORE_PROP 0 +#define STORE_PROP 1 + +#define OTHER_PROP 0 +#define NAMED_PROP 1 + +/* returns 1 if strings are equal, 0 if not */ +int equal_strings( char * , char * ); + +/* find an element in a plyfile's list */ +PlyElement *find_element( PlyFile * , char * ); + +/* find a property in an element's list */ +PlyProperty *find_property( PlyElement * , char * , int * ); + +/* write to a file the word describing a PLY file data type */ +void write_scalar_type( FILE * , int ); + +/* read a line from a file and break it up into separate words */ +char* *get_words( FILE * , int * , char ** ); + +/* write an item to a file */ +void write_binary_item( FILE * , int, unsigned int, double, int ); +void write_ascii_item( FILE * , int, unsigned int, double, int ); + +/* add information to a PLY file descriptor */ +void add_element( PlyFile * , char ** , int ); +void add_property( PlyFile * , char ** , int ); +void add_comment( PlyFile * , char * ); +void add_obj_info( PlyFile * , char * ); + +/* copy a property */ +void copy_property( PlyProperty * , PlyProperty * ); + +/* store a value into where a pointer and a type specify */ +void store_item( char * , int, int, unsigned int, double ); + +/* return the value of a stored item */ +void get_stored_item( void * , int, int * , unsigned int * , double * ); + +/* return the value stored in an item, given ptr to it and its type */ +double get_item_value( char * , int ); + +/* get binary or ascii item and store it according to ptr and type */ +void get_ascii_item( char * , int, int * , unsigned int * , double * ); +void get_binary_item( FILE * , int, int * , unsigned int * , double * ); + +/* get a bunch of elements from a file */ +void ascii_get_element( PlyFile * , char * ); +void binary_get_element( PlyFile * , char * ); + +/* memory allocation */ +static char *my_alloc( int, int, char * ); + + +/*************/ +/* Writing */ +/*************/ + + +/****************************************************************************** +Given a file pointer, get ready to write PLY data to the file. + +Entry: +fp - the given file pointer +nelems - number of elements in object +elem_names - list of element names +file_type - file type, either ascii or binary + +Exit: +returns a pointer to a PlyFile, used to refer to this file, or NULL if error +******************************************************************************/ + +PlyFile *ply_write( FILE *fp, int nelems, char **elem_names, int file_type ) +{ + int i; + PlyFile *plyfile; + PlyElement *elem; + + /* check for NULL file pointer */ + if ( fp == NULL ) + return ( NULL ); + + /* create a record for this object */ + + plyfile = ( PlyFile * ) myalloc ( sizeof ( PlyFile ) ); + plyfile->file_type = file_type; + plyfile->num_comments = 0; + plyfile->num_obj_info = 0; + plyfile->num_elem_types = nelems; + plyfile->version = 1.0; + plyfile->fp = fp; + plyfile->other_elems = NULL; + + /* tuck aside the names of the elements */ + + plyfile->elems = ( PlyElement * * ) myalloc ( sizeof ( PlyElement * ) * nelems ); + for ( i = 0; i < nelems; i++ ) + { + elem = ( PlyElement * ) myalloc ( sizeof ( PlyElement ) ); + plyfile->elems[i] = elem; + elem->name = strdup ( elem_names[i] ); + elem->num = 0; + elem->nprops = 0; + } + + /* return pointer to the file descriptor */ + return ( plyfile ); +} + + +/****************************************************************************** +Open a polygon file for writing. + +Entry: +filename - name of file to read from +nelems - number of elements in object +elem_names - list of element names +file_type - file type, either ascii or binary + +Exit: +returns a file identifier, used to refer to this file, or NULL if error +******************************************************************************/ + +PlyFile *open_for_writing_ply( char *filename, int nelems, char **elem_names, int file_type ) +{ + PlyFile *plyfile; + char *name; + FILE *fp; + + /* tack on the extension .ply, if necessary */ + + name = ( char * ) myalloc ( sizeof ( char ) * ( strlen ( filename ) + 5 ) ); + strcpy ( name, filename ); + if ( strlen ( name ) < 4 || strcmp ( name + strlen ( name ) - 4, ".ply" ) != 0 ) + strcat ( name, ".ply" ); + + /* open the file for writing */ + + fp = fopen ( name, "w" ); + if ( fp == NULL ) + { + return ( NULL ); + } + + /* create the actual PlyFile structure */ + + plyfile = ply_write ( fp, nelems, elem_names, file_type ); + if ( plyfile == NULL ) + return ( NULL ); + + /* return pointer to the file descriptor */ + return ( plyfile ); +} + + +/****************************************************************************** +Describe an element, including its properties and how many will be written +to the file. + +Entry: +plyfile - file identifier +elem_name - name of element that information is being specified about +nelems - number of elements of this type to be written +nprops - number of properties contained in the element +prop_list - list of properties +******************************************************************************/ + +void element_layout_ply( PlyFile *plyfile, char *elem_name, int nelems, int nprops, PlyProperty *prop_list ) +{ + int i; + PlyElement *elem; + PlyProperty *prop; + + /* look for appropriate element */ + elem = find_element ( plyfile, elem_name ); + if ( elem == NULL ) + { + fprintf( stderr,"element_layout_ply: can't find element '%s'\n",elem_name ); + exit ( -1 ); + } + + elem->num = nelems; + + /* copy the list of properties */ + + elem->nprops = nprops; + elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) * nprops ); + elem->store_prop = ( char * ) myalloc ( sizeof ( char ) * nprops ); + + for ( i = 0; i < nprops; i++ ) + { + prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); + elem->props[i] = prop; + elem->store_prop[i] = NAMED_PROP; + copy_property ( prop, &prop_list[i] ); + } +} + + +/****************************************************************************** +Describe a property of an element. + +Entry: +plyfile - file identifier +elem_name - name of element that information is being specified about +prop - the new property +******************************************************************************/ + +void ply_describe_property( PlyFile *plyfile, char *elem_name, PlyProperty *prop ) +{ + PlyElement *elem; + PlyProperty *elem_prop; + + /* look for appropriate element */ + elem = find_element ( plyfile, elem_name ); + if ( elem == NULL ) + { + fprintf( stderr, "ply_describe_property: can't find element '%s'\n", + elem_name ); + return; + } + + /* create room for new property */ + + if ( elem->nprops == 0 ) + { + elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) ); + elem->store_prop = ( char * ) myalloc ( sizeof ( char ) ); + elem->nprops = 1; + } + else + { + elem->nprops++; + elem->props = ( PlyProperty * * ) + realloc ( elem->props, sizeof ( PlyProperty * ) * elem->nprops ); + elem->store_prop = ( char * ) + realloc ( elem->store_prop, sizeof ( char ) * elem->nprops ); + } + + /* copy the new property */ + + elem_prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); + elem->props[elem->nprops - 1] = elem_prop; + elem->store_prop[elem->nprops - 1] = NAMED_PROP; + copy_property ( elem_prop, prop ); +} + + +/****************************************************************************** +State how many of a given element will be written. + +Entry: +plyfile - file identifier +elem_name - name of element that information is being specified about +nelems - number of elements of this type to be written +******************************************************************************/ + +void element_count_ply( PlyFile *plyfile, char *elem_name, int nelems ) +{ + PlyElement *elem; + + /* look for appropriate element */ + elem = find_element ( plyfile, elem_name ); + if ( elem == NULL ) + { + fprintf( stderr,"element_count_ply: can't find element '%s'\n",elem_name ); + exit ( -1 ); + } + + elem->num = nelems; +} + + +/****************************************************************************** +Signal that we've described everything a PLY file's header and that the +header should be written to the file. + +Entry: +plyfile - file identifier +******************************************************************************/ + +void header_complete_ply( PlyFile *plyfile ) +{ + int i,j; + FILE *fp = plyfile->fp; + PlyElement *elem; + PlyProperty *prop; + + fprintf ( fp, "ply\n" ); + + switch ( plyfile->file_type ) + { + case PLY_ASCII: + fprintf ( fp, "format ascii 1.0\n" ); + break; + case PLY_BINARY_BE: + fprintf ( fp, "format binary_big_endian 1.0\n" ); + break; + case PLY_BINARY_LE: + fprintf ( fp, "format binary_little_endian 1.0\n" ); + break; + default: + fprintf ( stderr, "ply_header_complete: bad file type = %d\n", + plyfile->file_type ); + exit ( -1 ); + } + + /* write out the comments */ + + for ( i = 0; i < plyfile->num_comments; i++ ) + fprintf ( fp, "comment %s\n", plyfile->comments[i] ); + + /* write out object information */ + + for ( i = 0; i < plyfile->num_obj_info; i++ ) + fprintf ( fp, "obj_info %s\n", plyfile->obj_info[i] ); + + /* write out information about each element */ + + for ( i = 0; i < plyfile->num_elem_types; i++ ) + { + elem = plyfile->elems[i]; + fprintf ( fp, "element %s %d\n", elem->name, elem->num ); + + /* write out each property */ + for ( j = 0; j < elem->nprops; j++ ) + { + prop = elem->props[j]; + if ( prop->is_list == PLY_LIST ) + { + fprintf ( fp, "property list " ); + write_scalar_type ( fp, prop->count_external ); + fprintf ( fp, " " ); + write_scalar_type ( fp, prop->external_type ); + fprintf ( fp, " %s\n", prop->name ); + } + else if ( prop->is_list == PLY_STRING ) + { + fprintf ( fp, "property string" ); + fprintf ( fp, " %s\n", prop->name ); + } + else + { + fprintf ( fp, "property " ); + write_scalar_type ( fp, prop->external_type ); + fprintf ( fp, " %s\n", prop->name ); + } + } + } + + fprintf ( fp, "end_header\n" ); +} + + +/****************************************************************************** +Specify which elements are going to be written. This should be called +before a call to the routine ply_put_element(). + +Entry: +plyfile - file identifier +elem_name - name of element we're talking about +******************************************************************************/ + +void put_element_setup_ply( PlyFile *plyfile, char *elem_name ) +{ + PlyElement *elem; + + elem = find_element ( plyfile, elem_name ); + if ( elem == NULL ) + { + fprintf( stderr, "put_element_setup_ply: can't find element '%s'\n", elem_name ); + exit ( -1 ); + } + + plyfile->which_elem = elem; +} + + +/****************************************************************************** +Write an element to the file. This routine assumes that we're +writing the type of element specified in the last call to the routine +put_element_setup_ply(). + +Entry: +plyfile - file identifier +elem_ptr - pointer to the element +******************************************************************************/ + +void put_element_ply( PlyFile *plyfile, void *elem_ptr ) +{ + int j,k; + FILE *fp = plyfile->fp; + PlyElement *elem; + PlyProperty *prop; + char *item; + char *elem_data; + char* *item_ptr; + int list_count; + int item_size; + int int_val; + unsigned int uint_val; + double double_val; + char* *other_ptr; + + elem = plyfile->which_elem; + elem_data = ( char * ) elem_ptr; + other_ptr = ( char * * ) ( ( ( char * ) elem_ptr ) + elem->other_offset ); + + /* write out either to an ascii or binary file */ + + if ( plyfile->file_type == PLY_ASCII ) + { + /* write an ascii file */ + + /* write out each property of the element */ + for ( j = 0; j < elem->nprops; j++ ) + { + prop = elem->props[j]; + + if ( elem->store_prop[j] == OTHER_PROP ) + elem_data = *other_ptr; + else + elem_data = ( char * ) elem_ptr; + + if ( prop->is_list == PLY_LIST ) + { + /* list */ + item = elem_data + prop->count_offset; + get_stored_item ( ( void * ) item, prop->count_internal, + &int_val, &uint_val, &double_val ); + write_ascii_item ( fp, int_val, uint_val, double_val, + prop->count_external ); + list_count = uint_val; + item_ptr = ( char * * ) ( elem_data + prop->offset ); + item = item_ptr[0]; + item_size = ply_type_size[prop->internal_type]; + for ( k = 0; k < list_count; k++ ) + { + get_stored_item ( ( void * ) item, prop->internal_type, + &int_val, &uint_val, &double_val ); + write_ascii_item ( fp, int_val, uint_val, double_val, + prop->external_type ); + item += item_size; + } + } + else if ( prop->is_list == PLY_STRING ) + { + /* string */ + char* *str; + item = elem_data + prop->offset; + str = ( char * * ) item; + fprintf ( fp, "\"%s\"", *str ); + } + else + { + /* scalar */ + item = elem_data + prop->offset; + get_stored_item ( ( void * ) item, prop->internal_type, + &int_val, &uint_val, &double_val ); + write_ascii_item ( fp, int_val, uint_val, double_val, + prop->external_type ); + } + } + + fprintf ( fp, "\n" ); + } + else + { + /* write a binary file */ + + /* write out each property of the element */ + for ( j = 0; j < elem->nprops; j++ ) + { + prop = elem->props[j]; + if ( elem->store_prop[j] == OTHER_PROP ) + elem_data = *other_ptr; + else + elem_data = ( char * ) elem_ptr; + if ( prop->is_list == PLY_LIST ) + { + /* list */ + item = elem_data + prop->count_offset; + item_size = ply_type_size[prop->count_internal]; + get_stored_item ( ( void * ) item, prop->count_internal, + &int_val, &uint_val, &double_val ); + write_binary_item ( fp, int_val, uint_val, double_val, + prop->count_external ); + list_count = uint_val; + item_ptr = ( char * * ) ( elem_data + prop->offset ); + item = item_ptr[0]; + item_size = ply_type_size[prop->internal_type]; + for ( k = 0; k < list_count; k++ ) + { + get_stored_item ( ( void * ) item, prop->internal_type, + &int_val, &uint_val, &double_val ); + write_binary_item ( fp, int_val, uint_val, double_val, + prop->external_type ); + item += item_size; + } + } + else if ( prop->is_list == PLY_STRING ) + { + /* string */ + int len; + char* *str; + item = elem_data + prop->offset; + str = ( char * * ) item; + + /* write the length */ + len = strlen( *str ) + 1; + fwrite ( &len, sizeof( int ), 1, fp ); + + /* write the string, including the null character */ + fwrite ( *str, len, 1, fp ); + } + else + { + /* scalar */ + item = elem_data + prop->offset; + item_size = ply_type_size[prop->internal_type]; + get_stored_item ( ( void * ) item, prop->internal_type, + &int_val, &uint_val, &double_val ); + write_binary_item ( fp, int_val, uint_val, double_val, + prop->external_type ); + } + } + } +} + + + + + + +/*************/ +/* Reading */ +/*************/ + + + +/****************************************************************************** +Given a file pointer, get ready to read PLY data from the file. + +Entry: +fp - the given file pointer + +Exit: +nelems - number of elements in object +elem_names - list of element names +returns a pointer to a PlyFile, used to refer to this file, or NULL if error +******************************************************************************/ + +PlyFile *ply_read( FILE *fp, int *nelems, char ***elem_names ) +{ + int i,j; + PlyFile *plyfile; + int nwords; + char* *words; + int found_format = 0; + char* *elist; + PlyElement *elem; + char *orig_line; + + /* check for NULL file pointer */ + if ( fp == NULL ) + return ( NULL ); + + /* create record for this object */ + + plyfile = ( PlyFile * ) myalloc ( sizeof ( PlyFile ) ); + plyfile->num_elem_types = 0; + plyfile->comments = NULL; + plyfile->num_comments = 0; + plyfile->obj_info = NULL; + plyfile->num_obj_info = 0; + plyfile->fp = fp; + plyfile->other_elems = NULL; + plyfile->rule_list = NULL; + + /* read and parse the file's header */ + + words = get_words ( plyfile->fp, &nwords, &orig_line ); + if ( !words || !equal_strings ( words[0], "ply" ) ) + return ( NULL ); + + while ( words ) + { + /* parse words */ + + if ( equal_strings ( words[0], "format" ) ) + { + if ( nwords != 3 ) + return ( NULL ); + if ( equal_strings ( words[1], "ascii" ) ) + plyfile->file_type = PLY_ASCII; + else if ( equal_strings ( words[1], "binary_big_endian" ) ) + plyfile->file_type = PLY_BINARY_BE; + else if ( equal_strings ( words[1], "binary_little_endian" ) ) + plyfile->file_type = PLY_BINARY_LE; + else + return ( NULL ); + plyfile->version = ( float ) atof ( words[2] ); + found_format = 1; + } + else if ( equal_strings ( words[0], "element" ) ) + add_element ( plyfile, words, nwords ); + else if ( equal_strings ( words[0], "property" ) ) + add_property ( plyfile, words, nwords ); + else if ( equal_strings ( words[0], "comment" ) ) + add_comment ( plyfile, orig_line ); + else if ( equal_strings ( words[0], "obj_info" ) ) + add_obj_info ( plyfile, orig_line ); + else if ( equal_strings ( words[0], "end_header" ) ) + break; + + /* free up words space */ + free ( words ); + + words = get_words ( plyfile->fp, &nwords, &orig_line ); + } + + /* create tags for each property of each element, to be used */ + /* later to say whether or not to store each property for the user */ + + for ( i = 0; i < plyfile->num_elem_types; i++ ) + { + elem = plyfile->elems[i]; + elem->store_prop = ( char * ) myalloc ( sizeof ( char ) * elem->nprops ); + for ( j = 0; j < elem->nprops; j++ ) + elem->store_prop[j] = DONT_STORE_PROP; + elem->other_offset = NO_OTHER_PROPS; /* no "other" props by default */ + } + + /* set return values about the elements */ + + elist = ( char * * ) myalloc ( sizeof ( char * ) * plyfile->num_elem_types ); + for ( i = 0; i < plyfile->num_elem_types; i++ ) + elist[i] = strdup ( plyfile->elems[i]->name ); + + *elem_names = elist; + *nelems = plyfile->num_elem_types; + + /* return a pointer to the file's information */ + + return ( plyfile ); +} + + +/****************************************************************************** +Open a polygon file for reading. + +Entry: +filename - name of file to read from + +Exit: +nelems - number of elements in object +elem_names - list of element names +file_type - file type, either ascii or binary +version - version number of PLY file +returns a file identifier, used to refer to this file, or NULL if error +******************************************************************************/ + +PlyFile *ply_open_for_reading( char *filename, int *nelems, char ***elem_names, int *file_type, float *version ) +{ + FILE *fp; + PlyFile *plyfile; + char *name; + + /* tack on the extension .ply, if necessary */ + + name = ( char * ) myalloc ( sizeof ( char ) * ( strlen ( filename ) + 5 ) ); + strcpy ( name, filename ); + if ( strlen ( name ) < 4 || strcmp ( name + strlen ( name ) - 4, ".ply" ) != 0 ) + strcat ( name, ".ply" ); + + /* open the file for reading */ + + fp = fopen ( name, "r" ); + if ( fp == NULL ) + return ( NULL ); + + /* create the PlyFile data structure */ + + plyfile = ply_read ( fp, nelems, elem_names ); + + /* determine the file type and version */ + + *file_type = plyfile->file_type; + *version = plyfile->version; + + /* return a pointer to the file's information */ + + return ( plyfile ); +} + + +/****************************************************************************** +Get information about a particular element. + +Entry: +plyfile - file identifier +elem_name - name of element to get information about + +Exit: +nelems - number of elements of this type in the file +nprops - number of properties +returns a list of properties, or NULL if the file doesn't contain that elem +******************************************************************************/ + +PlyProperty **get_element_description_ply( PlyFile *plyfile, char *elem_name, int *nelems, int *nprops ) +{ + int i; + PlyElement *elem; + PlyProperty *prop; + PlyProperty* *prop_list; + + /* find information about the element */ + elem = find_element ( plyfile, elem_name ); + if ( elem == NULL ) + return ( NULL ); + + *nelems = elem->num; + *nprops = elem->nprops; + + /* make a copy of the element's property list */ + prop_list = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) * elem->nprops ); + for ( i = 0; i < elem->nprops; i++ ) + { + prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); + copy_property ( prop, elem->props[i] ); + prop_list[i] = prop; + } + + /* return this duplicate property list */ + return ( prop_list ); +} + + +/****************************************************************************** +Specify which properties of an element are to be returned. This should be +called before a call to the routine get_element_ply(). + +Entry: +plyfile - file identifier +elem_name - which element we're talking about +nprops - number of properties +prop_list - list of properties +******************************************************************************/ + +void get_element_setup_ply( PlyFile *plyfile, char *elem_name, int nprops, PlyProperty *prop_list ) +{ + int i; + PlyElement *elem; + PlyProperty *prop; + int index; + + /* find information about the element */ + elem = find_element ( plyfile, elem_name ); + plyfile->which_elem = elem; + + /* deposit the property information into the element's description */ + for ( i = 0; i < nprops; i++ ) + { + /* look for actual property */ + prop = find_property ( elem, prop_list[i].name, &index ); + if ( prop == NULL ) + { + fprintf ( stderr, "Warning: Can't find property '%s' in element '%s'\n", + prop_list[i].name, elem_name ); + continue; + } + + /* store its description */ + prop->internal_type = prop_list[i].internal_type; + prop->offset = prop_list[i].offset; + prop->count_internal = prop_list[i].count_internal; + prop->count_offset = prop_list[i].count_offset; + + /* specify that the user wants this property */ + elem->store_prop[index] = STORE_PROP; + } +} + + +/****************************************************************************** +Specify a property of an element that is to be returned. This should be +called (usually multiple times) before a call to the routine ply_get_element(). +This routine should be used in preference to the less flexible old routine +called ply_get_element_setup(). + +Entry: +plyfile - file identifier +elem_name - which element we're talking about +prop - property to add to those that will be returned +******************************************************************************/ + +void ply_get_property( PlyFile *plyfile, char *elem_name, PlyProperty *prop ) +{ + PlyElement *elem; + PlyProperty *prop_ptr; + int index; + + /* find information about the element */ + elem = find_element ( plyfile, elem_name ); + plyfile->which_elem = elem; + + /* deposit the property information into the element's description */ + + prop_ptr = find_property ( elem, prop->name, &index ); + if ( prop_ptr == NULL ) + { + fprintf ( stderr, "Warning: Can't find property '%s' in element '%s'\n", + prop->name, elem_name ); + return; + } + prop_ptr->internal_type = prop->internal_type; + prop_ptr->offset = prop->offset; + prop_ptr->count_internal = prop->count_internal; + prop_ptr->count_offset = prop->count_offset; + + /* specify that the user wants this property */ + elem->store_prop[index] = STORE_PROP; +} + + +/****************************************************************************** +Read one element from the file. This routine assumes that we're reading +the type of element specified in the last call to the routine +ply_get_element_setup(). + +Entry: +plyfile - file identifier +elem_ptr - pointer to location where the element information should be put +******************************************************************************/ + +void ply_get_element( PlyFile *plyfile, void *elem_ptr ) +{ + if ( plyfile->file_type == PLY_ASCII ) + ascii_get_element ( plyfile, ( char * ) elem_ptr ); + else + binary_get_element ( plyfile, ( char * ) elem_ptr ); +} + + +/****************************************************************************** +Extract the comments from the header information of a PLY file. + +Entry: +plyfile - file identifier + +Exit: +num_comments - number of comments returned +returns a pointer to a list of comments +******************************************************************************/ + +char **get_comments_ply( PlyFile *plyfile, int *num_comments ) +{ + *num_comments = plyfile->num_comments; + return ( plyfile->comments ); +} + + +/****************************************************************************** +Extract the object information (arbitrary text) from the header information +of a PLY file. + +Entry: +plyfile - file identifier + +Exit: +num_obj_info - number of lines of text information returned +returns a pointer to a list of object info lines +******************************************************************************/ + +char **get_obj_info_ply( PlyFile *plyfile, int *num_obj_info ) +{ + *num_obj_info = plyfile->num_obj_info; + return ( plyfile->obj_info ); +} + + +/****************************************************************************** +ake ready for "other" properties of an element-- those properties that +the user has not explicitly asked for, but that are to be stashed away +in a special structure to be carried along with the element's other +information. + +Entry: +plyfile - file identifier +elem - element for which we want to save away other properties +******************************************************************************/ + +void setup_other_props( PlyFile *plyfile, PlyElement *elem ) +{ + int i; + PlyProperty *prop; + int size = 0; + int type_size; + + /* Examine each property in decreasing order of size. */ + /* We do this so that all data types will be aligned by */ + /* word, half-word, or whatever within the structure. */ + + for ( type_size = 8; type_size > 0; type_size /= 2 ) + { + /* add up the space taken by each property, and save this information */ + /* away in the property descriptor */ + + for ( i = 0; i < elem->nprops; i++ ) + { + /* don't bother with properties we've been asked to store explicitly */ + if ( elem->store_prop[i] ) + continue; + + prop = elem->props[i]; + + /* internal types will be same as external */ + prop->internal_type = prop->external_type; + prop->count_internal = prop->count_external; + + /* list case */ + if ( prop->is_list == PLY_LIST ) + { + /* pointer to list */ + if ( type_size == sizeof ( void * ) ) + { + prop->offset = size; + size += sizeof ( void * ); /* always use size of a pointer here */ + } + + /* count of number of list elements */ + if ( type_size == ply_type_size[prop->count_external] ) + { + prop->count_offset = size; + size += ply_type_size[prop->count_external]; + } + } + /* string */ + else if ( prop->is_list == PLY_STRING ) + { + /* pointer to string */ + if ( type_size == sizeof ( char * ) ) + { + prop->offset = size; + size += sizeof ( char * ); + } + } + /* scalar */ + else if ( type_size == ply_type_size[prop->external_type] ) + { + prop->offset = size; + size += ply_type_size[prop->external_type]; + } + } + } + + /* save the size for the other_props structure */ + elem->other_size = size; +} + + +/****************************************************************************** +Specify that we want the "other" properties of an element to be tucked +away within the user's structure. + +Entry: +plyfile - file identifier +elem - the element that we want to store other_props in +offset - offset to where other_props will be stored inside user's structure + +Exit: +returns pointer to structure containing description of other_props +******************************************************************************/ + +static PlyOtherProp *get_other_properties( PlyFile *plyfile, PlyElement *elem, int offset ) +{ + int i; + PlyOtherProp *other; + PlyProperty *prop; + int nprops; + + /* remember that this is the "current" element */ + plyfile->which_elem = elem; + + /* save the offset to where to store the other_props */ + elem->other_offset = offset; + + /* place the appropriate pointers, etc. in the element's property list */ + setup_other_props ( plyfile, elem ); + + /* create structure for describing other_props */ + other = ( PlyOtherProp * ) myalloc ( sizeof ( PlyOtherProp ) ); + other->name = strdup ( elem->name ); +#if 0 +if (elem->other_offset == NO_OTHER_PROPS) { +other->size = 0; +other->props = NULL; +other->nprops = 0; +return (other); +} +#endif + other->size = elem->other_size; + other->props = ( PlyProperty * * ) myalloc ( sizeof( PlyProperty ) * elem->nprops ); + + /* save descriptions of each "other" property */ + nprops = 0; + for ( i = 0; i < elem->nprops; i++ ) + { + if ( elem->store_prop[i] ) + continue; + prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); + copy_property ( prop, elem->props[i] ); + other->props[nprops] = prop; + nprops++; + } + other->nprops = nprops; + + /* set other_offset pointer appropriately if there are NO other properties */ + if ( other->nprops == 0 ) + { + elem->other_offset = NO_OTHER_PROPS; + } + + /* return structure */ + return ( other ); +} + + +/****************************************************************************** +Specify that we want the "other" properties of an element to be tucked +away within the user's structure. The user needn't be concerned for how +these properties are stored. + +Entry: +plyfile - file identifier +elem_name - name of element that we want to store other_props in +offset - offset to where other_props will be stored inside user's structure + +Exit: +returns pointer to structure containing description of other_props +******************************************************************************/ + +PlyOtherProp *ply_get_other_properties( PlyFile *plyfile, char *elem_name, int offset ) +{ + PlyElement *elem; + PlyOtherProp *other; + + /* find information about the element */ + elem = find_element ( plyfile, elem_name ); + if ( elem == NULL ) + { + fprintf ( stderr, "ply_get_other_properties: Can't find element '%s'\n", + elem_name ); + return ( NULL ); + } + + other = get_other_properties ( plyfile, elem, offset ); + return ( other ); +} + + + + +/*************************/ +/* Other Element Stuff */ +/*************************/ + + + + + +/****************************************************************************** +Grab all the data for the current element that a user does not want to +explicitly read in. Stores this in the PLY object's data structure. + +Entry: +plyfile - pointer to file + +Exit: +returns pointer to ALL the "other" element data for this PLY file +******************************************************************************/ + +PlyOtherElems *get_other_element_ply( PlyFile *plyfile ) +{ + int i; + PlyElement *elem; + char *elem_name; + int elem_count; + PlyOtherElems *other_elems; + OtherElem *other; + + elem = plyfile->which_elem; + elem_name = elem->name; + elem_count = elem->num; + + /* create room for the new "other" element, initializing the */ + /* other data structure if necessary */ + + if ( plyfile->other_elems == NULL ) + { + plyfile->other_elems = ( PlyOtherElems * ) myalloc ( sizeof ( PlyOtherElems ) ); + other_elems = plyfile->other_elems; + other_elems->other_list = ( OtherElem * ) myalloc ( sizeof ( OtherElem ) ); + other = &( other_elems->other_list[0] ); + other_elems->num_elems = 1; + } + else + { + other_elems = plyfile->other_elems; + other_elems->other_list = ( OtherElem * ) realloc ( other_elems->other_list, + sizeof ( OtherElem ) * other_elems->num_elems + 1 ); + other = &( other_elems->other_list[other_elems->num_elems] ); + other_elems->num_elems++; + } + + /* count of element instances in file */ + other->elem_count = elem_count; + + /* save name of element */ + other->elem_name = strdup ( elem_name ); + + /* create a list to hold all the current elements */ + other->other_data = ( OtherData * * ) + malloc ( sizeof ( OtherData * ) * other->elem_count ); + + /* set up for getting elements */ + other->other_props = ply_get_other_properties ( plyfile, elem_name, + offsetof( OtherData,other_props ) ); + + /* grab all these elements */ + for ( i = 0; i < other->elem_count; i++ ) + { + /* grab and element from the file */ + other->other_data[i] = ( OtherData * ) malloc ( sizeof ( OtherData ) ); + ply_get_element ( plyfile, ( void * ) other->other_data[i] ); + } + + /* return pointer to the other elements data */ + return ( other_elems ); +} + + +/****************************************************************************** +Write out the "other" elements specified for this PLY file. + +Entry: +plyfile - pointer to PLY file to write out other elements for +******************************************************************************/ + +void put_other_elements_ply( PlyFile *plyfile ) +{ + int i,j; + OtherElem *other; + + /* make sure we have other elements to write */ + if ( plyfile->other_elems == NULL ) + return; + + /* write out the data for each "other" element */ + + for ( i = 0; i < plyfile->other_elems->num_elems; i++ ) + { + other = &( plyfile->other_elems->other_list[i] ); + put_element_setup_ply ( plyfile, other->elem_name ); + + /* write out each instance of the current element */ + for ( j = 0; j < other->elem_count; j++ ) + put_element_ply ( plyfile, ( void * ) other->other_data[j] ); + } +} + + +/****************************************************************************** +Free up storage used by an "other" elements data structure. + +Entry: +other_elems - data structure to free up +******************************************************************************/ + +void free_other_elements_ply( PlyOtherElems *other_elems ) +{ +} + + + +/*******************/ +/* Miscellaneous */ +/*******************/ + + + +/****************************************************************************** +Close a PLY file. + +Entry: +plyfile - identifier of file to close +******************************************************************************/ + +void ply_close( PlyFile *plyfile ) +{ + fclose ( plyfile->fp ); + + /* free up memory associated with the PLY file */ + free ( plyfile ); +} + + +/****************************************************************************** +Get version number and file type of a PlyFile. + +Entry: +ply - pointer to PLY file + +Exit: +version - version of the file +file_type - PLY_ASCII, PLY_BINARY_BE, or PLY_BINARY_LE +******************************************************************************/ + +void get_info_ply( PlyFile *ply, float *version, int *file_type ) +{ + if ( ply == NULL ) + return; + + *version = ply->version; + *file_type = ply->file_type; +} + + +/****************************************************************************** +Compare two strings. Returns 1 if they are the same, 0 if not. +******************************************************************************/ + +int equal_strings( char *s1, char *s2 ) +{ + while ( *s1 && *s2 ) + if ( *s1++ != *s2++ ) + return ( 0 ); + + if ( *s1 != *s2 ) + return ( 0 ); + else + return ( 1 ); +} + + +/****************************************************************************** +Re-create the command line that was used to invoke this program. + +Entry: +argc - number of words in argv +argv - array of words in command line +******************************************************************************/ + +char *recreate_command_line( int argc, char *argv[] ) +{ + int i; + char *line; + int len = 0; + + /* count total number of characters needed, including separating spaces */ + for ( i = 0; i < argc; i++ ) + len += strlen( argv[i] ) + 1; + + /* create empty line */ + line = ( char * ) malloc ( sizeof( char ) * len ); + line[0] = '\0'; + + /* repeatedly append argv */ + for ( i = 0; i < argc; i++ ) + { + strcat ( line, argv[i] ); + if ( i != argc - 1 ) + strcat ( line, " " ); + } + + return ( line ); +} + + +/****************************************************************************** +Find an element from the element list of a given PLY object. + +Entry: +plyfile - file id for PLY file +element - name of element we're looking for + +Exit: +returns the element, or NULL if not found +******************************************************************************/ + +PlyElement *find_element( PlyFile *plyfile, char *element ) +{ + int i; + + for ( i = 0; i < plyfile->num_elem_types; i++ ) + if ( equal_strings ( element, plyfile->elems[i]->name ) ) + return ( plyfile->elems[i] ); + + return ( NULL ); +} + + +/****************************************************************************** +Find a property in the list of properties of a given element. + +Entry: +elem - pointer to element in which we want to find the property +prop_name - name of property to find + +Exit: +index - index to position in list +returns a pointer to the property, or NULL if not found +******************************************************************************/ + +PlyProperty *find_property( PlyElement *elem, char *prop_name, int *index ) +{ + int i; + + for ( i = 0; i < elem->nprops; i++ ) + if ( equal_strings ( prop_name, elem->props[i]->name ) ) + { + *index = i; + return ( elem->props[i] ); + } + + *index = -1; + return ( NULL ); +} + + +/****************************************************************************** +Read an element from an ascii file. + +Entry: +plyfile - file identifier +elem_ptr - pointer to element +******************************************************************************/ + +void ascii_get_element( PlyFile *plyfile, char *elem_ptr ) +{ + int j,k; + PlyElement *elem; + PlyProperty *prop; + char* *words; + int nwords; + int which_word; + char *elem_data,*item; + char *item_ptr; + int item_size; + int int_val; + unsigned int uint_val; + double double_val; + int list_count; + int store_it; + char* *store_array; + char *orig_line; + char *other_data; + int other_flag; + + item = (char*) NULL ; + other_data = (char*) NULL ; + + /* the kind of element we're reading currently */ + elem = plyfile->which_elem; + + /* do we need to setup for other_props? */ + + if ( elem->other_offset != NO_OTHER_PROPS ) + { + char* *ptr; + other_flag = 1; + /* make room for other_props */ + other_data = ( char * ) myalloc ( elem->other_size ); + /* store pointer in user's structure to the other_props */ + ptr = ( char * * ) ( elem_ptr + elem->other_offset ); + *ptr = other_data; + } + else + other_flag = 0; + + /* read in the element */ + + words = get_words ( plyfile->fp, &nwords, &orig_line ); + if ( words == NULL ) + { + fprintf ( stderr, "ply_get_element: unexpected end of file\n" ); + exit ( -1 ); + } + + which_word = 0; + + for ( j = 0; j < elem->nprops; j++ ) + { + prop = elem->props[j]; + store_it = ( elem->store_prop[j] | other_flag ); + + /* store either in the user's structure or in other_props */ + if ( elem->store_prop[j] ) + elem_data = elem_ptr; + else + elem_data = other_data; + + if ( prop->is_list == PLY_LIST ) + { + /* a list */ + + /* get and store the number of items in the list */ + get_ascii_item ( words[which_word++], prop->count_external, + &int_val, &uint_val, &double_val ); + if ( store_it ) + { + item = elem_data + prop->count_offset; + store_item( item, prop->count_internal, int_val, uint_val, double_val ); + } + + /* allocate space for an array of items and store a ptr to the array */ + list_count = int_val; + item_size = ply_type_size[prop->internal_type]; + store_array = ( char * * ) ( elem_data + prop->offset ); + + if ( list_count == 0 ) + { + if ( store_it ) + *store_array = NULL; + } + else + { + if ( store_it ) + { + item_ptr = ( char * ) myalloc ( sizeof ( char ) * item_size * list_count ); + item = item_ptr; + *store_array = item_ptr; + } + + /* read items and store them into the array */ + for ( k = 0; k < list_count; k++ ) + { + get_ascii_item ( words[which_word++], prop->external_type, + &int_val, &uint_val, &double_val ); + if ( store_it ) + { + store_item ( item, prop->internal_type, + int_val, uint_val, double_val ); + item += item_size; + } + } + } + } + else if ( prop->is_list == PLY_STRING ) + { + /* a string */ + if ( store_it ) + { + char *str; + char* *str_ptr; + str = strdup ( words[which_word++] ); + item = elem_data + prop->offset; + str_ptr = ( char * * ) item; + *str_ptr = str; + } + else + { + which_word++; + } + } + else + { + /* a scalar */ + get_ascii_item ( words[which_word++], prop->external_type, + &int_val, &uint_val, &double_val ); + if ( store_it ) + { + item = elem_data + prop->offset; + store_item ( item, prop->internal_type, int_val, uint_val, double_val ); + } + } + } + + free ( words ); +} + + +/****************************************************************************** +Read an element from a binary file. + +Entry: +plyfile - file identifier +elem_ptr - pointer to an element +******************************************************************************/ + +void binary_get_element( PlyFile *plyfile, char *elem_ptr ) +{ + int j,k; + PlyElement *elem; + PlyProperty *prop; + FILE *fp = plyfile->fp; + char *elem_data; + char *item; + char *item_ptr; + int item_size; + int int_val; + unsigned int uint_val; + double double_val; + int list_count; + int store_it; + char* *store_array; + char *other_data; + int other_flag; + + item = (char*) NULL ; + other_data = (char*) NULL ; + + /* the kind of element we're reading currently */ + elem = plyfile->which_elem; + + /* do we need to setup for other_props? */ + + if ( elem->other_offset != NO_OTHER_PROPS ) + { + char* *ptr; + other_flag = 1; + /* make room for other_props */ + other_data = ( char * ) myalloc ( elem->other_size ); + /* store pointer in user's structure to the other_props */ + ptr = ( char * * ) ( elem_ptr + elem->other_offset ); + *ptr = other_data; + } + else + other_flag = 0; + + /* read in a number of elements */ + + for ( j = 0; j < elem->nprops; j++ ) + { + prop = elem->props[j]; + store_it = ( elem->store_prop[j] | other_flag ); + + /* store either in the user's structure or in other_props */ + if ( elem->store_prop[j] ) + elem_data = elem_ptr; + else + elem_data = other_data; + + if ( prop->is_list == PLY_LIST ) + { + /* list */ + + /* get and store the number of items in the list */ + get_binary_item ( fp, prop->count_external, + &int_val, &uint_val, &double_val ); + if ( store_it ) + { + item = elem_data + prop->count_offset; + store_item( item, prop->count_internal, int_val, uint_val, double_val ); + } + + /* allocate space for an array of items and store a ptr to the array */ + list_count = int_val; + item_size = ply_type_size[prop->internal_type]; + store_array = ( char * * ) ( elem_data + prop->offset ); + if ( list_count == 0 ) + { + if ( store_it ) + *store_array = NULL; + } + else + { + if ( store_it ) + { + item_ptr = ( char * ) myalloc ( sizeof ( char ) * item_size * list_count ); + item = item_ptr; + *store_array = item_ptr; + } + + /* read items and store them into the array */ + for ( k = 0; k < list_count; k++ ) + { + get_binary_item ( fp, prop->external_type, + &int_val, &uint_val, &double_val ); + if ( store_it ) + { + store_item ( item, prop->internal_type, + int_val, uint_val, double_val ); + item += item_size; + } + } + } + } + else if ( prop->is_list == PLY_STRING ) + { + /* string */ + int len; + char *str; + fread ( &len, sizeof( int ), 1, fp ); + str = ( char * ) myalloc ( len ); + fread ( str, len, 1, fp ); + if ( store_it ) + { + char* *str_ptr; + item = elem_data + prop->offset; + str_ptr = ( char * * ) item; + *str_ptr = str; + } + } + else + { + /* scalar */ + get_binary_item ( fp, prop->external_type, + &int_val, &uint_val, &double_val ); + if ( store_it ) + { + item = elem_data + prop->offset; + store_item ( item, prop->internal_type, int_val, uint_val, double_val ); + } + } + } +} + + +/****************************************************************************** +Write to a file the word that represents a PLY data type. + +Entry: +fp - file pointer +code - code for type +******************************************************************************/ + +void write_scalar_type( FILE *fp, int code ) +{ + /* make sure this is a valid code */ + + if ( code <= StartType || code >= EndType ) + { + fprintf ( stderr, "write_scalar_type: bad data code = %d\n", code ); + exit ( -1 ); + } + + /* write the code to a file */ + + fprintf ( fp, "%s", type_names[code] ); +} + + +/****************************************************************************** +Get a text line from a file and break it up into words. + +IMPORTANT: The calling routine should call "free" on the returned pointer once +finished with it. + +Entry: +fp - file to read from + +Exit: +nwords - number of words returned +orig_line - the original line of characters +returns a list of words from the line, or NULL if end-of-file +******************************************************************************/ + +char **get_words( FILE *fp, int *nwords, char **orig_line ) +{ +#define BIG_STRING 4096 + static char str[BIG_STRING]; + static char str_copy[BIG_STRING]; + char* *words; + int max_words = 10; + int num_words = 0; + char *ptr,*ptr2; + char *result; + + words = ( char * * ) myalloc ( sizeof ( char * ) * max_words ); + + /* read in a line */ + result = fgets ( str, BIG_STRING, fp ); + if ( result == NULL ) + { + *nwords = 0; + *orig_line = NULL; + return ( NULL ); + } + + /* convert line-feed and tabs into spaces */ + /* (this guarentees that there will be a space before the */ + /* null character at the end of the string) */ + + str[BIG_STRING - 2] = ' '; + str[BIG_STRING - 1] = '\0'; + + for ( ptr = str, ptr2 = str_copy; *ptr != '\0'; ptr++, ptr2++ ) + { + *ptr2 = *ptr; + if ( *ptr == '\t' ) + { + *ptr = ' '; + *ptr2 = ' '; + } + else if ( *ptr == '\n' ) + { + *ptr = ' '; + *ptr2 = ' '; + break; + } + else if ( *ptr == '\r' ) + { + *ptr = ' '; + *ptr2 = '\0'; + } + } + + /* find the words in the line */ + + ptr = str; + while ( *ptr != '\0' ) + { + /* jump over leading spaces */ + while ( *ptr == ' ' ) + ptr++; + + /* break if we reach the end */ + if ( *ptr == '\0' ) + break; + + /* allocate more room for words if necessary */ + if ( num_words >= max_words ) + { + max_words += 10; + words = ( char * * ) realloc ( words, sizeof ( char * ) * max_words ); + } + + if ( *ptr == '\"' ) + { + /* a quote indidicates that we have a string */ + + /* skip over leading quote */ + ptr++; + + /* save pointer to beginning of word */ + words[num_words++] = ptr; + + /* find trailing quote or end of line */ + while ( *ptr != '\"' && *ptr != '\0' ) + ptr++; + + /* replace quote with a null character to mark the end of the word */ + /* if we are not already at the end of the line */ + if ( *ptr != '\0' ) + *ptr++ = '\0'; + } + else + { + /* non-string */ + + /* save pointer to beginning of word */ + words[num_words++] = ptr; + + /* jump over non-spaces */ + while ( *ptr != ' ' ) + ptr++; + + /* place a null character here to mark the end of the word */ + *ptr++ = '\0'; + } + } + + /* return the list of words */ + *nwords = num_words; + *orig_line = str_copy; + return ( words ); +} + + +/****************************************************************************** +Return the value of an item, given a pointer to it and its type. + +Entry: +item - pointer to item +type - data type that "item" points to + +Exit: +returns a double-precision float that contains the value of the item +******************************************************************************/ + +double get_item_value( char *item, int type ) +{ + unsigned char *puchar; + char *pchar; + short int *pshort; + unsigned short int *pushort; + int *pint; + unsigned int *puint; + float *pfloat; + double *pdouble; + int int_value; + unsigned int uint_value; + double double_value; + + switch ( type ) + { + case Int8: + pchar = ( char * ) item; + int_value = *pchar; + return ( ( double ) int_value ); + case Uint8: + puchar = ( unsigned char * ) item; + int_value = *puchar; + return ( ( double ) int_value ); + case Int16: + pshort = ( short int * ) item; + int_value = *pshort; + return ( ( double ) int_value ); + case Uint16: + pushort = ( unsigned short int * ) item; + int_value = *pushort; + return ( ( double ) int_value ); + case Int32: + pint = ( int * ) item; + int_value = *pint; + return ( ( double ) int_value ); + case Uint32: + puint = ( unsigned int * ) item; + uint_value = *puint; + return ( ( double ) uint_value ); + case Float32: + pfloat = ( float * ) item; + double_value = *pfloat; + return ( double_value ); + case Float64: + pdouble = ( double * ) item; + double_value = *pdouble; + return ( double_value ); + default: + fprintf ( stderr, "get_item_value: bad type = %d\n", type ); + exit ( -1 ); + } + + return ( 0.0 ); /* never actually gets here */ +} + + +/****************************************************************************** +Write out an item to a file as raw binary bytes. + +Entry: +fp - file to write to +int_val - integer version of item +uint_val - unsigned integer version of item +double_val - double-precision float version of item +type - data type to write out +******************************************************************************/ + +void write_binary_item( FILE *fp, int int_val, unsigned int uint_val, double double_val, int type ) +{ + unsigned char uchar_val; + char char_val; + unsigned short ushort_val; + short short_val; + float float_val; + + switch ( type ) + { + case Int8: + char_val = int_val; + fwrite ( &char_val, 1, 1, fp ); + break; + case Int16: + short_val = int_val; + fwrite ( &short_val, 2, 1, fp ); + break; + case Int32: + fwrite ( &int_val, 4, 1, fp ); + break; + case Uint8: + uchar_val = uint_val; + fwrite ( &uchar_val, 1, 1, fp ); + break; + case Uint16: + ushort_val = uint_val; + fwrite ( &ushort_val, 2, 1, fp ); + break; + case Uint32: + fwrite ( &uint_val, 4, 1, fp ); + break; + case Float32: + float_val = ( float ) double_val; + fwrite ( &float_val, 4, 1, fp ); + break; + case Float64: + fwrite ( &double_val, 8, 1, fp ); + break; + default: + fprintf ( stderr, "write_binary_item: bad type = %d\n", type ); + exit ( -1 ); + } +} + + +/****************************************************************************** +Write out an item to a file as ascii characters. + +Entry: +fp - file to write to +int_val - integer version of item +uint_val - unsigned integer version of item +double_val - double-precision float version of item +type - data type to write out +******************************************************************************/ + +void write_ascii_item( FILE *fp, int int_val, unsigned int uint_val, double double_val, int type ) +{ + switch ( type ) + { + case Int8: + case Int16: + case Int32: + fprintf ( fp, "%d ", int_val ); + break; + case Uint8: + case Uint16: + case Uint32: + fprintf ( fp, "%u ", uint_val ); + break; + case Float32: + case Float64: + fprintf ( fp, "%12f ", double_val ); + break; + default: + fprintf ( stderr, "write_ascii_item: bad type = %d\n", type ); + exit ( -1 ); + } +} + + +/****************************************************************************** +Get the value of an item that is in memory, and place the result +into an integer, an unsigned integer and a double. + +Entry: +ptr - pointer to the item +type - data type supposedly in the item + +Exit: +int_val - integer value +uint_val - unsigned integer value +double_val - double-precision floating point value +******************************************************************************/ + +void get_stored_item( void *ptr, int type, int *int_val, unsigned int *uint_val, double *double_val ) +{ + switch ( type ) + { + case Int8: + *int_val = *( ( char * ) ptr ); + *uint_val = *int_val; + *double_val = *int_val; + break; + case Uint8: + *uint_val = *( ( unsigned char * ) ptr ); + *int_val = *uint_val; + *double_val = *uint_val; + break; + case Int16: + *int_val = *( ( short int * ) ptr ); + *uint_val = *int_val; + *double_val = *int_val; + break; + case Uint16: + *uint_val = *( ( unsigned short int * ) ptr ); + *int_val = *uint_val; + *double_val = *uint_val; + break; + case Int32: + *int_val = *( ( int * ) ptr ); + *uint_val = *int_val; + *double_val = *int_val; + break; + case Uint32: + *uint_val = *( ( unsigned int * ) ptr ); + *int_val = *uint_val; + *double_val = *uint_val; + break; + case Float32: + *double_val = *( ( float * ) ptr ); + *int_val = ( int ) *double_val; + *uint_val = ( unsigned int ) *double_val; + break; + case Float64: + *double_val = *( ( double * ) ptr ); + *int_val = ( int ) *double_val; + *uint_val = ( unsigned int ) *double_val; + break; + default: + fprintf ( stderr, "get_stored_item: bad type = %d\n", type ); + exit ( -1 ); + } +} + + +/****************************************************************************** +Get the value of an item from a binary file, and place the result +into an integer, an unsigned integer and a double. + +Entry: +fp - file to get item from +type - data type supposedly in the word + +Exit: +int_val - integer value +uint_val - unsigned integer value +double_val - double-precision floating point value +******************************************************************************/ + +void get_binary_item( FILE *fp, int type, int *int_val, unsigned int *uint_val, double *double_val ) +{ + char c[8]; + void *ptr; + + ptr = ( void * ) c; + + switch ( type ) + { + case Int8: + fread ( ptr, 1, 1, fp ); + *int_val = *( ( char * ) ptr ); + *uint_val = *int_val; + *double_val = *int_val; + break; + case Uint8: + fread ( ptr, 1, 1, fp ); + *uint_val = *( ( unsigned char * ) ptr ); + *int_val = *uint_val; + *double_val = *uint_val; + break; + case Int16: + fread ( ptr, 2, 1, fp ); + *int_val = *( ( short int * ) ptr ); + *uint_val = *int_val; + *double_val = *int_val; + break; + case Uint16: + fread ( ptr, 2, 1, fp ); + *uint_val = *( ( unsigned short int * ) ptr ); + *int_val = *uint_val; + *double_val = *uint_val; + break; + case Int32: + fread ( ptr, 4, 1, fp ); + *int_val = *( ( int * ) ptr ); + *uint_val = *int_val; + *double_val = *int_val; + break; + case Uint32: + fread ( ptr, 4, 1, fp ); + *uint_val = *( ( unsigned int * ) ptr ); + *int_val = *uint_val; + *double_val = *uint_val; + break; + case Float32: + fread ( ptr, 4, 1, fp ); + *double_val = *( ( float * ) ptr ); + *int_val = ( int ) *double_val; + *uint_val = ( unsigned int ) *double_val; + break; + case Float64: + fread ( ptr, 8, 1, fp ); + *double_val = *( ( double * ) ptr ); + *int_val = ( int ) *double_val; + *uint_val = ( unsigned int ) *double_val; + break; + default: + fprintf ( stderr, "get_binary_item: bad type = %d\n", type ); + exit ( -1 ); + } +} + + +/****************************************************************************** +Extract the value of an item from an ascii word, and place the result +into an integer, an unsigned integer and a double. + +Entry: +word - word to extract value from +type - data type supposedly in the word + +Exit: +int_val - integer value +uint_val - unsigned integer value +double_val - double-precision floating point value +******************************************************************************/ + +void get_ascii_item( char *word, int type, int *int_val, unsigned int *uint_val, double *double_val ) +{ + switch ( type ) + { + case Int8: + case Uint8: + case Int16: + case Uint16: + case Int32: + *int_val = atoi ( word ); + *uint_val = *int_val; + *double_val = *int_val; + break; + + case Uint32: + *uint_val = strtoul ( word, ( char * * ) NULL, 10 ); + *int_val = *uint_val; + *double_val = *uint_val; + break; + + case Float32: + case Float64: + *double_val = atof ( word ); + *int_val = ( int ) *double_val; + *uint_val = ( unsigned int ) *double_val; + break; + + default: + fprintf ( stderr, "get_ascii_item: bad type = %d\n", type ); + exit ( -1 ); + } +} + + +/****************************************************************************** +Store a value into a place being pointed to, guided by a data type. + +Entry: +item - place to store value +type - data type +int_val - integer version of value +uint_val - unsigned integer version of value +double_val - double version of value + +Exit: +item - pointer to stored value +******************************************************************************/ + +void store_item( char *item, int type, int int_val, unsigned int uint_val, double double_val ) +{ + unsigned char *puchar; + short int *pshort; + unsigned short int *pushort; + int *pint; + unsigned int *puint; + float *pfloat; + double *pdouble; + + switch ( type ) + { + case Int8: + *item = int_val; + break; + case Uint8: + puchar = ( unsigned char * ) item; + *puchar = uint_val; + break; + case Int16: + pshort = ( short * ) item; + *pshort = int_val; + break; + case Uint16: + pushort = ( unsigned short * ) item; + *pushort = uint_val; + break; + case Int32: + pint = ( int * ) item; + *pint = int_val; + break; + case Uint32: + puint = ( unsigned int * ) item; + *puint = uint_val; + break; + case Float32: + pfloat = ( float * ) item; + *pfloat = ( float ) double_val; + break; + case Float64: + pdouble = ( double * ) item; + *pdouble = double_val; + break; + default: + fprintf ( stderr, "store_item: bad type = %d\n", type ); + exit ( -1 ); + } +} + + +/****************************************************************************** +Add an element to a PLY file descriptor. + +Entry: +plyfile - PLY file descriptor +words - list of words describing the element +nwords - number of words in the list +******************************************************************************/ + +void add_element( PlyFile *plyfile, char **words, int nwords ) +{ + PlyElement *elem; + + /* create the new element */ + elem = ( PlyElement * ) myalloc ( sizeof ( PlyElement ) ); + elem->name = strdup ( words[1] ); + elem->num = atoi ( words[2] ); + elem->nprops = 0; + + /* make room for new element in the object's list of elements */ + if ( plyfile->num_elem_types == 0 ) + plyfile->elems = ( PlyElement * * ) myalloc ( sizeof ( PlyElement * ) ); + else + plyfile->elems = ( PlyElement * * ) realloc ( plyfile->elems, + sizeof ( PlyElement * ) * ( plyfile->num_elem_types + 1 ) ); + + /* add the new element to the object's list */ + plyfile->elems[plyfile->num_elem_types] = elem; + plyfile->num_elem_types++; +} + + +/****************************************************************************** +Return the type of a property, given the name of the property. + +Entry: +name - name of property type + +Exit: +returns integer code for property, or 0 if not found +******************************************************************************/ + +int get_prop_type( char *type_name ) +{ + int i; + + /* try to match the type name */ + for ( i = StartType + 1; i < EndType; i++ ) + if ( equal_strings ( type_name, type_names[i] ) ) + return ( i ); + + /* see if we can match an old type name */ + for ( i = StartType + 1; i < EndType; i++ ) + if ( equal_strings ( type_name, old_type_names[i] ) ) + return ( i ); + + /* if we get here, we didn't find the type */ + return ( 0 ); +} + + +/****************************************************************************** +Add a property to a PLY file descriptor. + +Entry: +plyfile - PLY file descriptor +words - list of words describing the property +nwords - number of words in the list +******************************************************************************/ + +void add_property( PlyFile *plyfile, char **words, int nwords ) +{ + PlyProperty *prop; + PlyElement *elem; + + /* create the new property */ + + prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); + + if ( equal_strings ( words[1], "list" ) ) + { + /* list */ + prop->count_external = get_prop_type ( words[2] ); + prop->external_type = get_prop_type ( words[3] ); + prop->name = strdup ( words[4] ); + prop->is_list = PLY_LIST; + } + else if ( equal_strings ( words[1], "string" ) ) + { + /* string */ + prop->count_external = Int8; + prop->external_type = Int8; + prop->name = strdup ( words[2] ); + prop->is_list = PLY_STRING; + } + else + { + /* scalar */ + prop->external_type = get_prop_type ( words[1] ); + prop->name = strdup ( words[2] ); + prop->is_list = PLY_SCALAR; + } + + /* add this property to the list of properties of the current element */ + + elem = plyfile->elems[plyfile->num_elem_types - 1]; + + if ( elem->nprops == 0 ) + elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) ); + else + elem->props = ( PlyProperty * * ) realloc ( elem->props, + sizeof ( PlyProperty * ) * ( elem->nprops + 1 ) ); + + elem->props[elem->nprops] = prop; + elem->nprops++; +} + + +/****************************************************************************** +Add a comment to a PLY file descriptor. + +Entry: +plyfile - PLY file descriptor +line - line containing comment +******************************************************************************/ + +void add_comment( PlyFile *plyfile, char *line ) +{ + int i; + + /* skip over "comment" and leading spaces and tabs */ + i = 7; + while ( line[i] == ' ' || line[i] == '\t' ) + i++; + + append_comment_ply ( plyfile, &line[i] ); +} + + +/****************************************************************************** +Add a some object information to a PLY file descriptor. + +Entry: +plyfile - PLY file descriptor +line - line containing text info +******************************************************************************/ + +void add_obj_info( PlyFile *plyfile, char *line ) +{ + int i; + + /* skip over "obj_info" and leading spaces and tabs */ + i = 8; + while ( line[i] == ' ' || line[i] == '\t' ) + i++; + + append_obj_info_ply ( plyfile, &line[i] ); +} + + +/****************************************************************************** +Copy a property. +******************************************************************************/ + +void copy_property( PlyProperty *dest, PlyProperty *src ) +{ + dest->name = strdup ( src->name ); + dest->external_type = src->external_type; + dest->internal_type = src->internal_type; + dest->offset = src->offset; + + dest->is_list = src->is_list; + dest->count_external = src->count_external; + dest->count_internal = src->count_internal; + dest->count_offset = src->count_offset; +} + + +/****************************************************************************** +Allocate some memory. + +Entry: +size - amount of memory requested (in bytes) +lnum - line number from which memory was requested +fname - file name from which memory was requested +******************************************************************************/ + +static char *my_alloc( int size, int lnum, char *fname ) +{ + char *ptr; + + ptr = ( char * ) malloc ( size ); + + if ( ptr == 0 ) + { + fprintf( stderr, "Memory allocation bombed on line %d in %s\n", lnum, fname ); + } + + return ( ptr ); +} + + +/**** NEW STUFF ****/ +/**** NEW STUFF ****/ +/**** NEW STUFF ****/ +/**** NEW STUFF ****/ + + + +/****************************************************************************** +Given a file pointer, get ready to read PLY data from the file. + +Entry: +fp - the given file pointer + +Exit: +nelems - number of elements in object +elem_names - list of element names +returns a pointer to a PlyFile, used to refer to this file, or NULL if error +******************************************************************************/ + +PlyFile *read_ply( FILE *fp ) +{ + PlyFile *ply; + int num_elems; + char* *elem_names; + + ply = ply_read ( fp, &num_elems, &elem_names ); + + return ( ply ); +} + + +/****************************************************************************** +Given a file pointer, get ready to write PLY data to the file. + +Entry: +fp - the given file pointer +nelems - number of elements in object +elem_names - list of element names +file_type - file type, either ascii or binary + +Exit: +returns a pointer to a PlyFile, used to refer to this file, or NULL if error +******************************************************************************/ + +PlyFile *write_ply( FILE *fp, int nelems, char **elem_names, int file_type ) +{ + PlyFile *ply; + + ply = ply_write ( fp, nelems, elem_names, file_type ); + + return ( ply ); +} + + +/****************************************************************************** +Return a list of the names of the elements in a particular PLY file. + +Entry: +ply - PLY file whose element name list we want + +Exit: +num_elems - the number of element names in the list +returns the list of names +******************************************************************************/ + +char **get_element_list_ply( PlyFile *ply, int *num_elems ) +{ + int i; + char* *elist; + + /* create the list of element names */ + + elist = ( char * * ) myalloc ( sizeof ( char * ) * ply->num_elem_types ); + for ( i = 0; i < ply->num_elem_types; i++ ) + elist[i] = strdup ( ply->elems[i]->name ); + + /* return the number of elements and the list of element names */ + *num_elems = ply->num_elem_types; + return ( elist ); +} + + +/****************************************************************************** +Append a comment to a PLY file. + +Entry: +ply - file to append comment to +comment - the comment to append +******************************************************************************/ + +void append_comment_ply( PlyFile *ply, char *comment ) +{ + /* (re)allocate space for new comment */ + if ( ply->num_comments == 0 ) + ply->comments = ( char * * ) myalloc ( sizeof ( char * ) ); + else + ply->comments = ( char * * ) realloc ( ply->comments, + sizeof ( char * ) * ( ply->num_comments + 1 ) ); + + /* add comment to list */ + ply->comments[ply->num_comments] = strdup ( comment ); + ply->num_comments++; +} + + +/****************************************************************************** +Copy the comments from one PLY file to another. + +Entry: +out_ply - destination file to copy comments to +in_ply - the source of the comments +******************************************************************************/ + +void copy_comments_ply( PlyFile *out_ply, PlyFile *in_ply ) +{ + int i; + + for ( i = 0; i < in_ply->num_comments; i++ ) + append_comment_ply ( out_ply, in_ply->comments[i] ); +} + + +/****************************************************************************** +Append object information (arbitrary text) to a PLY file. + +Entry: +ply - file to append object info to +obj_info - the object info to append +******************************************************************************/ + +void append_obj_info_ply( PlyFile *ply, char *obj_info ) +{ + /* (re)allocate space for new info */ + if ( ply->num_obj_info == 0 ) + ply->obj_info = ( char * * ) myalloc ( sizeof ( char * ) ); + else + ply->obj_info = ( char * * ) realloc ( ply->obj_info, + sizeof ( char * ) * ( ply->num_obj_info + 1 ) ); + + /* add info to list */ + ply->obj_info[ply->num_obj_info] = strdup ( obj_info ); + ply->num_obj_info++; +} + + +/****************************************************************************** +Copy the object information from one PLY file to another. + +Entry: +out_ply - destination file to copy object information to +in_ply - the source of the object information +******************************************************************************/ + +void copy_obj_info_ply( PlyFile *out_ply, PlyFile *in_ply ) +{ + int i; + + for ( i = 0; i < in_ply->num_obj_info; i++ ) + append_obj_info_ply ( out_ply, in_ply->obj_info[i] ); +} + + +/****************************************************************************** +Close a PLY file. + +Entry: +plyfile - identifier of file to close +******************************************************************************/ + +void close_ply( PlyFile *plyfile ) +{ + fclose ( plyfile->fp ); +} + + +/****************************************************************************** +Free the memory used by a PLY file. + +Entry: +plyfile - identifier of file +******************************************************************************/ + +void free_ply( PlyFile *plyfile ) +{ + /* free up memory associated with the PLY file */ + free ( plyfile ); +} + + +/****************************************************************************** +Specify the index of the next element to be read in from a PLY file. + +Entry: +ply - file to read from +index - index of the element to be read + +Exit: +elem_count - the number of elements in the file +returns pointer to the name of this next element +******************************************************************************/ + +char *setup_element_read_ply( PlyFile *ply, int index, int *elem_count ) +{ + PlyElement *elem; + + if ( index < 0 || index > ply->num_elem_types ) + { + fprintf ( stderr, "Warning: No element with index %d\n", index ); + return ( 0 ); + } + + elem = ply->elems[index]; + + /* set this to be the current element */ + ply->which_elem = elem; + + /* return the number of such elements in the file and the element's name */ + *elem_count = elem->num; + return ( elem->name ); +} + + +/****************************************************************************** +Read one element from the file. This routine assumes that we're reading +the type of element specified in the last call to the routine +setup_element_read_ply(). + +Entry: +plyfile - file identifier +elem_ptr - pointer to location where the element information should be put +******************************************************************************/ + +void get_element_ply( PlyFile *plyfile, void *elem_ptr ) +{ + if ( plyfile->file_type == PLY_ASCII ) + ascii_get_element ( plyfile, ( char * ) elem_ptr ); + else + binary_get_element ( plyfile, ( char * ) elem_ptr ); +} + + +/****************************************************************************** +Specify one of several properties of the current element that is to be +read from a file. This should be called (usually multiple times) before a +call to the routine get_element_ply(). + +Entry: +plyfile - file identifier +prop - property to add to those that will be returned + +Exit: +0 if the property has not been found +1 if the property has been found +******************************************************************************/ + +int setup_property_ply( PlyFile *plyfile, PlyProperty *prop ) +{ + PlyElement *elem; + PlyProperty *prop_ptr; + int index; + + elem = plyfile->which_elem; + + /* deposit the property information into the element's description */ + + prop_ptr = find_property ( elem, prop->name, &index ); + if ( prop_ptr == NULL ) + { + fprintf ( stderr, "Warning: Can't find property '%s' in element '%s'\n", + prop->name, elem->name ); + return 0; + } + prop_ptr->internal_type = prop->internal_type; + prop_ptr->offset = prop->offset; + prop_ptr->count_internal = prop->count_internal; + prop_ptr->count_offset = prop->count_offset; + + /* specify that the user wants this property */ + elem->store_prop[index] = STORE_PROP; + return 1 ; +} + + +/****************************************************************************** +Specify that we want the "other" properties of the current element to be tucked +away within the user's structure. + +Entry: +plyfile - file identifier +offset - offset to where other_props will be stored inside user's structure + +Exit: +returns pointer to structure containing description of other_props +******************************************************************************/ + +PlyOtherProp *get_other_properties_ply( PlyFile *plyfile, int offset ) +{ + PlyOtherProp *other; + + other = get_other_properties ( plyfile, plyfile->which_elem, offset ); + return ( other ); +} + + +/****************************************************************************** +Describe which element is to be written next and state how many of them will +be written. + +Entry: +plyfile - file identifier +elem_name - name of element that information is being described +nelems - number of elements of this type to be written +******************************************************************************/ + +void describe_element_ply( PlyFile *plyfile, char *elem_name, int nelems ) +{ + PlyElement *elem; + + /* look for appropriate element */ + elem = find_element ( plyfile, elem_name ); + if ( elem == NULL ) + { + fprintf( stderr,"describe_element_ply: can't find element '%s'\n",elem_name ); + exit ( -1 ); + } + + elem->num = nelems; + + /* now this element is the current element */ + plyfile->which_elem = elem; +} + + +/****************************************************************************** +Describe a property of an element. + +Entry: +plyfile - file identifier +prop - the new property +******************************************************************************/ + +void describe_property_ply( PlyFile *plyfile, PlyProperty *prop ) +{ + PlyElement *elem; + PlyProperty *elem_prop; + + elem = plyfile->which_elem; + + /* create room for new property */ + + if ( elem->nprops == 0 ) + { + elem->props = ( PlyProperty * * ) myalloc ( sizeof ( PlyProperty * ) ); + elem->store_prop = ( char * ) myalloc ( sizeof ( char ) ); + elem->nprops = 1; + } + else + { + elem->nprops++; + elem->props = ( PlyProperty * * ) + realloc ( elem->props, sizeof ( PlyProperty * ) * elem->nprops ); + elem->store_prop = ( char * ) + realloc ( elem->store_prop, sizeof ( char ) * elem->nprops ); + } + + /* copy the new property */ + + elem_prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); + elem->props[elem->nprops - 1] = elem_prop; + elem->store_prop[elem->nprops - 1] = NAMED_PROP; + copy_property ( elem_prop, prop ); +} + + +/****************************************************************************** +Describe what the "other" properties are that are to be stored, and where +they are in an element. +******************************************************************************/ + +void describe_other_properties_ply( PlyFile *plyfile, PlyOtherProp *other, int offset ) +{ + int i; + PlyElement *elem; + PlyProperty *prop; + + /* look for appropriate element */ + elem = find_element ( plyfile, other->name ); + if ( elem == NULL ) + { + fprintf( stderr, "describe_other_properties_ply: can't find element '%s'\n", + other->name ); + return; + } + + /* create room for other properties */ + + if ( elem->nprops == 0 ) + { + elem->props = ( PlyProperty * * ) + myalloc ( sizeof ( PlyProperty * ) * other->nprops ); + elem->store_prop = ( char * ) myalloc ( sizeof ( char ) * other->nprops ); + elem->nprops = 0; + } + else + { + int newsize; + newsize = elem->nprops + other->nprops; + elem->props = ( PlyProperty * * ) + realloc ( elem->props, sizeof ( PlyProperty * ) * newsize ); + elem->store_prop = ( char * ) + realloc ( elem->store_prop, sizeof ( char ) * newsize ); + } + + /* copy the other properties */ + + for ( i = 0; i < other->nprops; i++ ) + { + prop = ( PlyProperty * ) myalloc ( sizeof ( PlyProperty ) ); + copy_property ( prop, other->props[i] ); + elem->props[elem->nprops] = prop; + elem->store_prop[elem->nprops] = OTHER_PROP; + elem->nprops++; + } + + /* save other info about other properties */ + elem->other_size = other->size; + elem->other_offset = offset; +} + + +/****************************************************************************** +Pass along a pointer to "other" elements that we want to save in a given +PLY file. These other elements were presumably read from another PLY file. + +Entry: +plyfile - file pointer in which to store this other element info +other_elems - info about other elements that we want to store +******************************************************************************/ + +void describe_other_elements_ply( PlyFile *plyfile, PlyOtherElems *other_elems ) +{ + int i; + OtherElem *other; + + /* ignore this call if there is no other element */ + if ( other_elems == NULL ) + return; + + /* save pointer to this information */ + plyfile->other_elems = other_elems; + + /* describe the other properties of this element */ + + for ( i = 0; i < other_elems->num_elems; i++ ) + { + other = &( other_elems->other_list[i] ); + element_count_ply ( plyfile, other->elem_name, other->elem_count ); + describe_other_properties_ply ( plyfile, other->other_props, + offsetof( OtherData,other_props ) ); + } +} + + + +/**** Property Propagation Rules ****/ + + +typedef struct RuleName { +int code; +char *name; +} RuleName; + +RuleName rule_name_list[] = { +{AVERAGE_RULE, "avg"}, +{RANDOM_RULE, "rnd"}, +{MINIMUM_RULE, "max"}, +{MAXIMUM_RULE, "min"}, +{MAJORITY_RULE, "major"}, +{SAME_RULE, "same"}, +{-1, "end_marker"}, +}; + + + +/****************************************************************************** +Initialize the property propagation rules for an element. Default is to +use averaging (AVERAGE_RULE) for creating all new properties. + +Entry: +ply - PLY object that this is for +elem_name - name of the element that we're making the rules for + +Exit: +returns pointer to the default rules +******************************************************************************/ + +PlyPropRules *init_rule_ply( PlyFile *ply, char *elem_name ) +{ + int i,j; + PlyElement *elem; + PlyPropRules *rules; + PlyRuleList *list; + int found_prop; + + elem = find_element ( ply, elem_name ); + if ( elem == NULL ) + { + fprintf ( stderr, "init_rule_ply: Can't find element '%s'\n", elem_name ); + exit ( -1 ); + } + + rules = ( PlyPropRules * ) myalloc ( sizeof ( PlyPropRules ) ); + rules->elem = elem; + rules->rule_list = ( int * ) myalloc ( sizeof( int ) * elem->nprops ); + rules->max_props = 0; + rules->nprops = 0; + + /* default is to use averaging rule */ + for ( i = 0; i < elem->nprops; i++ ) + rules->rule_list[i] = AVERAGE_RULE; + + /* see if there are other rules we should use */ + + if ( ply->rule_list == NULL ) + return ( rules ); + + /* try to match the element, property and rule name */ + + for ( list = ply->rule_list; list != NULL; list = list->next ) + { + if ( !equal_strings ( list->element, elem->name ) ) + continue; + + found_prop = 0; + + for ( i = 0; i < elem->nprops; i++ ) + if ( equal_strings ( list->property, elem->props[i]->name ) ) + { + found_prop = 1; + + /* look for matching rule name */ + for ( j = 0; rule_name_list[j].code != -1; j++ ) + if ( equal_strings ( list->name, rule_name_list[j].name ) ) + { + rules->rule_list[i] = rule_name_list[j].code; + break; + } + } + + if ( !found_prop ) + { + fprintf ( stderr, "Can't find property '%s' for rule '%s'\n", + list->property, list->name ); + continue; + } + } + + return ( rules ); +} + + +/****************************************************************************** +odify a property propagation rule. + +Entry: +rules - rules for the element +prop_name - name of the property whose rule we're modifying +rule_type - type of rule (MAXIMUM_RULE, MINIMUM_RULE, MAJORITY_RULE, etc.) +******************************************************************************/ + +void modify_rule_ply( PlyPropRules *rules, char *prop_name, int rule_type ) +{ + int i; + PlyElement *elem = rules->elem; + + /* find the property and modify its rule type */ + + for ( i = 0; i < elem->nprops; i++ ) + if ( equal_strings ( elem->props[i]->name, prop_name ) ) + { + rules->rule_list[i] = rule_type; + return; + } + + /* we didn't find the property if we get here */ + fprintf ( stderr, "modify_rule_ply: Can't find property '%s'\n", prop_name ); + exit ( -1 ); +} + + +/****************************************************************************** +Begin to create a set of properties from a set of propagation rules. + +Entry: +ply - PLY object whose rules we're preparing to use +rules - rules for the element +******************************************************************************/ + +void start_props_ply( PlyFile *ply, PlyPropRules *rules ) +{ + /* PlyElement *elem = rules->elem; */ + + /* save pointer to the rules in the PLY object */ + ply->current_rules = rules; + + /* get ready for new sets of properties to combine */ + rules->nprops = 0; +} + + +/****************************************************************************** +Remember a set of properties and their weights for creating a new set of +properties. + +Entry: +weight - weights for this set of properties +other_props - the properties to use +******************************************************************************/ + +void weight_props_ply( PlyFile *ply, float weight, void *other_props ) +{ + PlyPropRules *rules = ply->current_rules; + + /* allocate space for properties and weights, if necessary */ + if ( rules->max_props == 0 ) + { + rules->max_props = 6; + rules->props = ( void * * ) myalloc ( sizeof ( void * ) * rules->max_props ); + rules->weights = ( float * ) myalloc ( sizeof ( float ) * rules->max_props ); + } + if ( rules->nprops == rules->max_props ) + { + rules->max_props *= 2; + rules->props = ( void * * ) realloc ( rules->props, + sizeof ( void * ) * rules->max_props ); + rules->weights = ( float * ) realloc ( rules->weights, + sizeof ( float ) * rules->max_props ); + } + + /* remember these new properties and their weights */ + + rules->props[rules->nprops] = other_props; + rules->weights[rules->nprops] = weight; + rules->nprops++; +} + + +/****************************************************************************** +Return a pointer to a new set of properties that have been created using +a specified set of property combination rules and a given collection of +"other" properties. + +Exit: +returns a pointer to the new properties +******************************************************************************/ + +void *get_new_props_ply( PlyFile *ply ) +{ + int i,j; + static double *vals; + static int max_vals = 0; + PlyPropRules *rules = ply->current_rules; + PlyElement *elem = rules->elem; + PlyProperty *prop; + char *data; + char *new_data; + void *ptr; + int offset; + int type; + double double_val; + int int_val; + unsigned int uint_val; + int random_pick; + + /* return NULL if we've got no "other" properties */ + if ( elem->other_size == 0 ) + { + return ( NULL ); + } + + /* create room for combined other properties */ + new_data = ( char * ) myalloc ( sizeof ( char ) * elem->other_size ); + + /* make sure there is enough room to store values we're to combine */ + + if ( max_vals == 0 ) + { + max_vals = rules->nprops; + vals = ( double * ) myalloc ( sizeof ( double ) * rules->nprops ); + } + if ( rules->nprops >= max_vals ) + { + max_vals = rules->nprops; + vals = ( double * ) realloc ( vals, sizeof ( double ) * rules->nprops ); + } + + /* in case we need a random choice */ + random_pick = ( int ) floor ( rules->nprops ); //* drand48()); + + /* calculate the combination for each "other" property of the element */ + + for ( i = 0; i < elem->nprops; i++ ) + { + /* don't bother with properties we've been asked to store explicitly */ + if ( elem->store_prop[i] ) + continue; + + prop = elem->props[i]; + offset = prop->offset; + type = prop->external_type; + + /* collect together all the values we're to combine */ + + for ( j = 0; j < rules->nprops; j++ ) + { + data = ( char * ) rules->props[j]; + ptr = ( void * ) ( data + offset ); + get_stored_item ( ( void * ) ptr, type, &int_val, &uint_val, &double_val ); + vals[j] = double_val; + } + + /* calculate the combined value */ + + switch ( rules->rule_list[i] ) + { + case AVERAGE_RULE: + { + double sum = 0; + double weight_sum = 0; + for ( j = 0; j < rules->nprops; j++ ) + { + sum += vals[j] * rules->weights[j]; + weight_sum += rules->weights[j]; + } + double_val = sum / weight_sum; + break; + } + case MINIMUM_RULE: + { + double_val = vals[0]; + for ( j = 1; j < rules->nprops; j++ ) + if ( double_val > vals[j] ) + double_val = vals[j]; + break; + } + case MAXIMUM_RULE: + { + double_val = vals[0]; + for ( j = 1; j < rules->nprops; j++ ) + if ( double_val < vals[j] ) + double_val = vals[j]; + break; + } + case RANDOM_RULE: + { + double_val = vals[random_pick]; + break; + } + case SAME_RULE: + { + double_val = vals[0]; + for ( j = 1; j < rules->nprops; j++ ) + if ( double_val != vals[j] ) + { + fprintf ( stderr, + "get_new_props_ply: Error combining properties that should be the same.\n" ); + exit ( -1 ); + } + break; + } + default: + fprintf ( stderr, "get_new_props_ply: Bad rule = %d\n", + rules->rule_list[i] ); + exit ( -1 ); + } + + /* store the combined value */ + + int_val = ( int ) double_val; + uint_val = ( unsigned int ) double_val; + ptr = ( void * ) ( new_data + offset ); + store_item ( ( char * ) ptr, type, int_val, uint_val, double_val ); + } + + return ( ( void * ) new_data ); +} + + +/****************************************************************************** +Set the list of user-specified property combination rules. +******************************************************************************/ + +void set_prop_rules_ply( PlyFile *ply, PlyRuleList *prop_rules ) +{ + ply->rule_list = prop_rules; +} + + +/****************************************************************************** +Append a property rule to a growing list of user-specified rules. + +Entry: +rule_list - current rule list +name - name of property combination rule +property - "element.property" says which property the rule affects + +Exit: +returns pointer to the new rule list +******************************************************************************/ + +PlyRuleList *append_prop_rule( PlyRuleList *rule_list, char *name, char *property ) +{ + PlyRuleList *rule; + PlyRuleList *rule_ptr; + char *str,*str2; + char *ptr; + + /* find . */ + str = strdup ( property ); + for ( ptr = str; *ptr != '\0' && *ptr != '.'; ptr++ ) + ; + + /* split string at . */ + if ( *ptr == '.' ) + { + *ptr = '\0'; + str2 = ptr + 1; + } + else + { + fprintf ( stderr, "Can't find property '%s' for rule '%s'\n", + property, name ); + return ( rule_list ); + } + + rule = ( PlyRuleList * ) malloc ( sizeof ( PlyRuleList ) ); + rule->name = name; + rule->element = str; + rule->property = str2; + rule->next = NULL; + + /* either start rule list or append to it */ + + if ( rule_list == NULL ) + rule_list = rule; + else + { + /* append new rule to current list */ + rule_ptr = rule_list; + while ( rule_ptr->next != NULL ) + rule_ptr = rule_ptr->next; + rule_ptr->next = rule; + } + + /* return pointer to list */ + + return ( rule_list ); +} + + +/****************************************************************************** +See if a name matches the name of any property combination rules. + +Entry: +name - name of rule we're trying to match + +Exit: +returns 1 if we find a match, 0 if not +******************************************************************************/ + +int matches_rule_name( char *name ) +{ + int i; + + for ( i = 0; rule_name_list[i].code != -1; i++ ) + if ( equal_strings ( rule_name_list[i].name, name ) ) + return ( 1 ); + + return ( 0 ); +} + diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/ply.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/ply.h new file mode 100755 index 0000000000000000000000000000000000000000..1925d5e584371f4713a93860f6cdfd93601d1ec4 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/MarchingCubes/ply.h @@ -0,0 +1,233 @@ +/* + +Header for PLY polygon files. + +- Greg Turk + +A PLY file contains a single polygonal _object_. + +An object is composed of lists of _elements_. Typical elements are +vertices, faces, edges and materials. + +Each type of element for a given object has one or more _properties_ +associated with the element type. For instance, a vertex element may +have as properties three floating-point values x,y,z and three unsigned +chars for red, green and blue. + +----------------------------------------------------------------------- + +Copyright (c) 1998 Georgia Institute of Technology. All rights reserved. + +Permission to use, copy, modify and distribute this software and its +documentation for any purpose is hereby granted without fee, provided +that the above copyright notice and this permission notice appear in +all copies of this software and that you do not sell the software. + +THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +*/ + +#ifndef __PLY_H__ +#define __PLY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <stddef.h> + +#define PLY_ASCII 1 /* ascii PLY file */ +#define PLY_BINARY_BE 2 /* binary PLY file, big endian */ +#define PLY_BINARY_LE 3 /* binary PLY file, little endian */ + +#define PLY_OKAY 0 /* ply routine worked okay */ +#define PLY_ERROR -1 /* error in ply routine */ + +/* scalar data types supported by PLY format */ + +#define StartType 0 +#define Int8 1 +#define Int16 2 +#define Int32 3 +#define Uint8 4 +#define Uint16 5 +#define Uint32 6 +#define Float32 7 +#define Float64 8 +#define EndType 9 + +#define PLY_SCALAR 0 +#define PLY_LIST 1 +#define PLY_STRING 2 + + +typedef struct PlyProperty { /* description of a property */ + +char *name; /* property name */ +int external_type; /* file's data type */ +int internal_type; /* program's data type */ +int offset; /* offset bytes of prop in a struct */ + +int is_list; /* 0 = scalar, 1 = list, 2 = char string */ +int count_external; /* file's count type */ +int count_internal; /* program's count type */ +int count_offset; /* offset byte for list count */ + +} PlyProperty; + +typedef struct PlyElement { /* description of an element */ +char *name; /* element name */ +int num; /* number of elements in this object */ +int size; /* size of element (bytes) or -1 if variable */ +int nprops; /* number of properties for this element */ +PlyProperty **props; /* list of properties in the file */ +char *store_prop; /* flags: property wanted by user? */ +int other_offset; /* offset to un-asked-for props, or -1 if none*/ +int other_size; /* size of other_props structure */ +} PlyElement; + +typedef struct PlyOtherProp { /* describes other properties in an element */ +char *name; /* element name */ +int size; /* size of other_props */ +int nprops; /* number of properties in other_props */ +PlyProperty **props; /* list of properties in other_props */ +} PlyOtherProp; + +typedef struct OtherData { /* for storing other_props for an other element */ +void *other_props; +} OtherData; + +typedef struct OtherElem { /* data for one "other" element */ +char *elem_name; /* names of other elements */ +int elem_count; /* count of instances of each element */ +OtherData **other_data; /* actual property data for the elements */ +PlyOtherProp *other_props; /* description of the property data */ +} OtherElem; + +typedef struct PlyOtherElems { /* "other" elements, not interpreted by user */ +int num_elems; /* number of other elements */ +OtherElem *other_list; /* list of data for other elements */ +} PlyOtherElems; + +#define AVERAGE_RULE 1 +#define MAJORITY_RULE 2 +#define MINIMUM_RULE 3 +#define MAXIMUM_RULE 4 +#define SAME_RULE 5 +#define RANDOM_RULE 6 + +typedef struct PlyPropRules { /* rules for combining "other" properties */ +PlyElement *elem; /* element whose rules we are making */ +int *rule_list; /* types of rules (AVERAGE_PLY, MAJORITY_PLY, etc.) */ +int nprops; /* number of properties we're combining so far */ +int max_props; /* maximum number of properties we have room for now */ +void **props; /* list of properties we're combining */ +float *weights; /* list of weights of the properties */ +} PlyPropRules; + +typedef struct PlyRuleList { +char *name; /* name of the rule */ +char *element; /* name of element that rule applies to */ +char *property; /* name of property that rule applies to */ +struct PlyRuleList *next; /* pointer for linked list of rules */ +} PlyRuleList; + +typedef struct PlyFile { /* description of PLY file */ +FILE *fp; /* file pointer */ +int file_type; /* ascii or binary */ +float version; /* version number of file */ +int num_elem_types; /* number of element types of object */ +PlyElement **elems; /* list of elements */ +int num_comments; /* number of comments */ +char **comments; /* list of comments */ +int num_obj_info; /* number of items of object information */ +char **obj_info; /* list of object info items */ +PlyElement *which_elem; /* element we're currently reading or writing */ +PlyOtherElems *other_elems; /* "other" elements from a PLY file */ +PlyPropRules *current_rules; /* current propagation rules */ +PlyRuleList *rule_list; /* rule list from user */ +} PlyFile; + +/* memory allocation */ +/* +extern char *my_alloc(); +*/ +#define myalloc(mem_size) my_alloc((mem_size), __LINE__, __FILE__) + + +/* old routines */ + +#if 0 +extern PlyFile *ply_write(FILE *, int, char **, int); +extern PlyFile *ply_read(FILE *, int *, char ***); +extern PlyFile *ply_open_for_reading( char *, int *, char ***, int *, float *); +extern void ply_close(PlyFile *); +extern PlyOtherProp *ply_get_other_properties(PlyFile *, char *, int); +#endif + +extern void ply_describe_property( PlyFile * , char * , PlyProperty * ); +extern void ply_get_property( PlyFile * , char * , PlyProperty * ); +extern void ply_get_element( PlyFile * , void * ); + + +/*** delcaration of routines ***/ + +PlyOtherElems *get_other_element_ply( PlyFile * ); + +PlyFile *read_ply( FILE * ); +PlyFile *write_ply( FILE * , int, char ** , int ); +extern PlyFile *open_for_writing_ply( char * , int, char ** , int ); +void close_ply( PlyFile * ); +void free_ply( PlyFile * ); + +void get_info_ply( PlyFile * , float * , int * ); +void free_other_elements_ply( PlyOtherElems * ); + +void append_comment_ply( PlyFile * , char * ); +void append_obj_info_ply( PlyFile * , char * ); +void copy_comments_ply( PlyFile * , PlyFile * ); +void copy_obj_info_ply( PlyFile * , PlyFile * ); +char* *get_comments_ply( PlyFile * , int * ); +char* *get_obj_info_ply( PlyFile * , int * ); + +char* *get_element_list_ply( PlyFile * , int * ); +int setup_property_ply( PlyFile * , PlyProperty * ); +void get_element_ply( PlyFile * , void * ); +char *setup_element_read_ply( PlyFile * , int, int * ); +PlyOtherProp *get_other_properties_ply( PlyFile * , int ); + +void element_count_ply( PlyFile * , char * , int ); +void describe_element_ply( PlyFile * , char * , int ); +void describe_property_ply( PlyFile * , PlyProperty * ); +void describe_other_properties_ply( PlyFile * , PlyOtherProp * , int ); +void describe_other_elements_ply( PlyFile * , PlyOtherElems * ); +void get_element_setup_ply( PlyFile * , char * , int, PlyProperty * ); +PlyProperty* *get_element_description_ply( PlyFile * , char * , int * , int * ); +void element_layout_ply( PlyFile * , char * , int, int, PlyProperty * ); + +void header_complete_ply( PlyFile * ); +void put_element_setup_ply( PlyFile * , char * ); +void put_element_ply( PlyFile * , void * ); +void put_other_elements_ply( PlyFile * ); + +PlyPropRules *init_rule_ply( PlyFile * , char * ); +void modify_rule_ply( PlyPropRules * , char * , int ); +void start_props_ply( PlyFile * , PlyPropRules * ); +void weight_props_ply( PlyFile * , float, void * ); +void *get_new_props_ply( PlyFile * ); +void set_prop_rules_ply( PlyFile * , PlyRuleList * ); +PlyRuleList *append_prop_rule( PlyRuleList * , char * , char * ); +int matches_rule_name( char * ); + +int equal_strings( char * , char * ); +char *recreate_command_line( int, char *argv[] ); + + +#ifdef __cplusplus +} +#endif +#endif /* !__PLY_H__ */ + diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/cvMeshSurfaceSimplify.C b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/cvMeshSurfaceSimplify.C new file mode 100644 index 0000000000000000000000000000000000000000..adc46f762378c75dafefa76bac50f125a5793b12 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/cvMeshSurfaceSimplify.C @@ -0,0 +1,350 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2012 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 + cvMeshSurfaceSimplify + +Description + Simplifies surfaces by resampling. + + Uses Thomas Lewiner's topology preserving MarchingCubes. + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "Time.H" +#include "searchableSurfaces.H" +#include "conformationSurfaces.H" +#include "triSurfaceMesh.H" + +#include "MarchingCubes.h" + + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Main program: + +int main(int argc, char *argv[]) +{ + argList::addNote + ( + "Re-sample surfaces used in cvMesh operation" + ); + //argList::validArgs.append("inputFile"); + argList::validArgs.append("(nx ny nz)"); + argList::validArgs.append("outputName"); + + #include "setRootCase.H" + #include "createTime.H" + runTime.functionObjects().off(); + + const Vector<label> n(IStringStream(args.args()[1])()); + const fileName exportName = args.args()[2]; + + Info<< "Reading surfaces as specified in the cvMeshDict and" + << " writing re-sampled " << n << " to " << exportName + << nl << endl; + + cpuTime timer; + + IOdictionary cvMeshDict + ( + IOobject + ( + "cvMeshDict", + runTime.system(), + runTime, + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE + ) + ); + + // Define/load all geometry + searchableSurfaces allGeometry + ( + IOobject + ( + "cvSearchableSurfaces", + runTime.constant(), + "triSurface", + runTime, + IOobject::MUST_READ, + IOobject::NO_WRITE + ), + cvMeshDict.subDict("geometry") + ); + + Info<< "Geometry read in = " + << timer.cpuTimeIncrement() << " s." << nl << endl; + + + Random rndGen(64293*Pstream::myProcNo()); + + conformationSurfaces geometryToConformTo + ( + runTime, + rndGen, + allGeometry, + cvMeshDict.subDict("surfaceConformation") + ); + + Info<< "Set up geometry in = " + << timer.cpuTimeIncrement() << " s." << nl << endl; + + + + // Extend + treeBoundBox bb = geometryToConformTo.globalBounds(); + { + const vector smallVec = 0.1*bb.span(); + bb.min() -= smallVec; + bb.max() += smallVec; + } + + Info<< "Meshing to bounding box " << bb << nl << endl; + + const vector span(bb.span()); + const vector d + ( + span.x()/(n.x()-1), + span.y()/(n.y()-1), + span.z()/(n.z()-1) + ); + + MarchingCubes mc(span.x(), span.y(), span.z() ) ; + mc.set_resolution(n.x(), n.y(), n.z()); + mc.init_all() ; + + + // Generate points + pointField points(mc.size_x()*mc.size_y()*mc.size_z()); + label pointI = 0; + + point pt; + for( int k = 0 ; k < mc.size_z() ; k++ ) + { + pt.z() = bb.min().z() + k*d.z(); + for( int j = 0 ; j < mc.size_y() ; j++ ) + { + pt.y() = bb.min().y() + j*d.y(); + for( int i = 0 ; i < mc.size_x() ; i++ ) + { + pt.x() = bb.min().x() + i*d.x(); + points[pointI++] = pt; + } + } + } + + Info<< "Generated " << points.size() << " sampling points in = " + << timer.cpuTimeIncrement() << " s." << nl << endl; + + + // Compute data + const searchableSurfaces& geometry = geometryToConformTo.geometry(); + const labelList& surfaces = geometryToConformTo.surfaces(); + + scalarField signedDist; + labelList nearestSurfaces; + searchableSurfacesQueries::signedDistance + ( + geometry, + surfaces, + points, + scalarField(points.size(), sqr(GREAT)), + nearestSurfaces, + signedDist + ); + + // Fill elements + pointI = 0; + for( int k = 0 ; k < mc.size_z() ; k++ ) + { + for( int j = 0 ; j < mc.size_y() ; j++ ) + { + for( int i = 0 ; i < mc.size_x() ; i++ ) + { + mc.set_data(float(signedDist[pointI++]), i, j, k); + } + } + } + + Info<< "Determined signed distance in = " + << timer.cpuTimeIncrement() << " s." << nl << endl; + + + mc.run() ; + + Info<< "Constructed iso surface in = " + << timer.cpuTimeIncrement() << " s." << nl << endl; + + + mc.clean_temps() ; + + + + // Write output file + if (mc.ntrigs() > 0) + { + Triangle* triangles = mc.triangles(); + List<labelledTri> tris(mc.ntrigs()); + forAll(tris, triI) + { + tris[triI] = labelledTri + ( + triangles[triI].v1, + triangles[triI].v2, + triangles[triI].v3, + 0 // region + ); + } + + + Vertex* vertices = mc.vertices(); + pointField points(mc.nverts()); + forAll(points, pointI) + { + Vertex& v = vertices[pointI]; + points[pointI] = point + ( + bb.min().x() + v.x*span.x()/mc.size_x(), + bb.min().y() + v.y*span.y()/mc.size_y(), + bb.min().z() + v.z*span.z()/mc.size_z() + ); + } + + + // Find correspondence to original surfaces + labelList regionOffsets(surfaces.size()); + label nRegions = 0; + forAll(surfaces, i) + { + const wordList& regions = geometry[surfaces[i]].regions(); + regionOffsets[i] = nRegions; + nRegions += regions.size(); + } + + + geometricSurfacePatchList patches(nRegions); + nRegions = 0; + forAll(surfaces, i) + { + const wordList& regions = geometry[surfaces[i]].regions(); + + forAll(regions, regionI) + { + patches[nRegions] = geometricSurfacePatch + ( + "patch", + geometry[surfaces[i]].name() + "_" + regions[regionI], + nRegions + ); + nRegions++; + } + } + + triSurface s(tris, patches, points, true); + + Info<< "Extracted triSurface in = " + << timer.cpuTimeIncrement() << " s." << nl << endl; + + + // Find out region on local surface of nearest point + { + List<pointIndexHit> hitInfo; + labelList hitSurfaces; + geometryToConformTo.findSurfaceNearest + ( + s.faceCentres(), + scalarField(s.size(), sqr(GREAT)), + hitInfo, + hitSurfaces + ); + + // Get region + DynamicList<pointIndexHit> surfInfo(hitSurfaces.size()); + DynamicList<label> surfIndices(hitSurfaces.size()); + + forAll(surfaces, surfI) + { + // Extract info on this surface + surfInfo.clear(); + surfIndices.clear(); + forAll(hitSurfaces, triI) + { + if (hitSurfaces[triI] == surfI) + { + surfInfo.append(hitInfo[triI]); + surfIndices.append(triI); + } + } + + // Calculate sideness of these surface points + labelList region; + geometry[surfaces[surfI]].getRegion(surfInfo, region); + + forAll(region, i) + { + label triI = surfIndices[i]; + s[triI].region() = regionOffsets[surfI]+region[i]; + } + } + } + + Info<< "Re-patched surface in = " + << timer.cpuTimeIncrement() << " s." << nl << endl; + + triSurfaceMesh smesh + ( + IOobject + ( + exportName, + runTime.constant(), // instance + "triSurface", + runTime, // registry + IOobject::NO_READ, + IOobject::AUTO_WRITE, + false + ), + s + ); + + Info<< "writing surfMesh:\n " + << smesh.searchableSurface::objectPath() << nl << endl; + smesh.searchableSurface::write(); + + Info<< "Written surface in = " + << timer.cpuTimeIncrement() << " s." << nl << endl; + } + + mc.clean_all() ; + + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/marching_cubes_jgt.zip b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/marching_cubes_jgt.zip new file mode 100644 index 0000000000000000000000000000000000000000..bb15279b270eb84738e70467383317685d53e425 Binary files /dev/null and b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/marching_cubes_jgt.zip differ diff --git a/applications/utilities/postProcessing/sampling/sample/sampleDict b/applications/utilities/postProcessing/sampling/sample/sampleDict index 8684d769326caccad8e9d16984e8129ec4fe54f4..b55b190bf71ce090805ab9f9a7dd3ff47a493573 100644 --- a/applications/utilities/postProcessing/sampling/sample/sampleDict +++ b/applications/utilities/postProcessing/sampling/sample/sampleDict @@ -272,10 +272,12 @@ surfaces // Distance to surface distance 0.0; + //cell false;// optional: use isoSurface instead + // of isoSurfaceCell interpolate false; - regularise false; // Optional: do not simplify - // mergeTol 1e-10; // Optional: fraction of mesh bounding box - // to merge points (default=1e-6) + regularise false; // Optional: do not simplify + // mergeTol 1e-10; // Optional: fraction of mesh bounding box + // to merge points (default=1e-6) } triSurfaceSampling diff --git a/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.C b/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.C index 17ef34fb6f710730e879bcdc4a2005d7b320bc07..024f7d27ecf4203c1684e3295bc7e20ad52692fc 100644 --- a/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.C +++ b/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.C @@ -379,6 +379,124 @@ Foam::label Foam::indexedOctree<Type>::compactContents } +template <class Type> +bool Foam::indexedOctree<Type>::quickCircumsphereRejection +( + const label nodeI, + const point& cc, + const scalar crSqr, + const List<scalar>& nearestDistances +) const +{ + const node& nod = nodes_[nodeI]; + + volumeType nodeType = volumeType(nodeTypes_.get(nodeI<<3)); + + //scalar boxDist = nearestDistances[nodeI] + 0.5*nod.bb_.mag(); + scalar boxDist = crSqr + magSqr(cc - nod.bb_.midpoint()); + + if + ( + nodeType == INSIDE + //&& (crSqr < sqr(boxDist)) + && (boxDist < sqr(nearestDistances[nodeI])) + ) + { + return true; + } + else + { + direction octant = nod.bb_.subOctant(cc); + + labelBits index = nod.subNodes_[octant]; + + if (isNode(index)) + { + return quickCircumsphereRejection + ( + getNode(index), + cc, + crSqr, + nearestDistances + ); + } + else + { + return false; + } + } +} + + +template <class Type> +bool Foam::indexedOctree<Type>::quickCircumsphereRejection +( + const point& cc, + const scalar crSqr, + const List<scalar>& nearestDistances +) const +{ + if (nodes_.size()) + { + return quickCircumsphereRejection + ( + 0, + cc, + crSqr, + nearestDistances + ); + } + + return false; +} + + +template <class Type> +Foam::scalar +Foam::indexedOctree<Type>::calcNearestDistance +( + const label nodeI +) const +{ + const node& nod = nodes_[nodeI]; + + const point& nodeCentre = nod.bb_.midpoint(); + + scalar nearestDistance = 0.0; + + pointIndexHit pHit = findNearest(nodeCentre, sqr(GREAT)); + + if (pHit.hit()) + { + nearestDistance = mag(pHit.hitPoint() - nodeCentre); + } + else + { + WarningIn("Foam::indexedOctree<Type>::calcNearestDistance(const label)") + << "Cannot calculate distance of nearest point on surface from " + << "the midpoint of the octree node. Returning distance of zero." + << endl; + } + + return nearestDistance; +} + + +template <class Type> +Foam::List<Foam::scalar> +Foam::indexedOctree<Type>::calcNearestDistance() const +{ + List<scalar> nearestDistances(nodes_.size()); + + forAll(nearestDistances, nodeI) + { + nearestDistances[nodeI] = calcNearestDistance(nodeI); + } + + return nearestDistances; +} + + // Pre-calculates wherever possible the volume status per node/subnode. // Recurses to determine status of lowest level boxes. Level above is // combination of octants below. @@ -540,6 +658,67 @@ Foam::indexedOctree<Type>::getSide // ~~~~~~~~~~~~~~ // + +//template <class Type> +//bool Foam::indexedOctree<Type>::findAnyOverlap +//( +// const label nodeI, +// const point& sample, +// const scalar nearestDistSqr +//) const +//{ +// const node& nod = nodes_[nodeI]; +// +// // Determine order to walk through octants +// FixedList<direction, 8> octantOrder; +// nod.bb_.searchOrder(sample, octantOrder); +// +// // Go into all suboctants (one containing sample first) and update +// // nearest. +// for (direction i = 0; i < 8; i++) +// { +// direction octant = octantOrder[i]; +// +// labelBits index = nod.subNodes_[octant]; +// +// if (isNode(index)) +// { +// label subNodeI = getNode(index); +// +// const treeBoundBox& subBb = nodes_[subNodeI].bb_; +// +// if (overlaps(subBb.min(), subBb.max(), nearestDistSqr, sample)) +// { +// return findAnyOverlap +// ( +// subNodeI, +// sample, +// nearestDistSqr +// ); +// } +// } +// else if (isContent(index)) +// { +// if +// ( +// overlaps +// ( +// nod.bb_, +// octant, +// nearestDistSqr, +// sample +// ) +// ) +// { +// return true; +// } +// } +// } +// +// return false; +//} + + // Find nearest point starting from nodeI template <class Type> void Foam::indexedOctree<Type>::findNearest @@ -1614,7 +1793,6 @@ void Foam::indexedOctree<Type>::traverseNode } } - const node& nod = nodes_[nodeI]; labelBits index = nod.subNodes_[octant]; @@ -1781,6 +1959,11 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine label i = 0; for (; i < 100000; i++) { +// if (isLineInsideOrOutside(nodeI, treeStart, treeEnd)) +// { +// return hitInfo; +// } + // Ray-trace to end of current node. Updates point (either on triangle // in case of hit or on node bounding box in case of miss) @@ -1935,6 +2118,38 @@ Foam::pointIndexHit Foam::indexedOctree<Type>::findLine } +//template <class Type> +//bool Foam::indexedOctree<Type>::isLineInsideOrOutside +//( +// const label nodeI, +// const point& start, +// const point& end +//) const +//{ +// const node& nod = nodes_[nodeI]; +// +// direction startOctant = nod.bb_.subOctant(start); +// direction endOctant = nod.bb_.subOctant(end); +// +// if (startOctant == endOctant) +// { +// volumeType startOctantType +// = volumeType(nodeTypes_.get((nodeI<<3) + startOctant)); +// +// if +// ( +// startOctantType == INSIDE || startOctantType == OUTSIDE +// ) +// { +// //Info<< nodeI << " | " << start << " " << end << endl; +// return true; +// } +// } +// +// return false; +//} + + // Find first intersection template <class Type> Foam::pointIndexHit Foam::indexedOctree<Type>::findLine @@ -2559,6 +2774,27 @@ Foam::scalar& Foam::indexedOctree<Type>::perturbTol() } +//template <class Type> +//bool Foam::indexedOctree<Type>::findAnyOverlap +//( +// const point& sample, +// const scalar startDistSqr +//) const +//{ +// if (nodes_.size()) +// { +// return findAnyOverlap +// ( +// 0, +// sample, +// startDistSqr +// ); +// } +// +// return false; +//} + + template <class Type> Foam::pointIndexHit Foam::indexedOctree<Type>::findNearest ( diff --git a/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.H b/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.H index aa493f34e92c40b7adb599d4a15dac0d0d55af1c..40ee7a8a32cf54d0403a53fd477c4046cecf5cbc 100644 --- a/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.H +++ b/src/OpenFOAM/algorithms/indexedOctree/indexedOctree.H @@ -201,6 +201,16 @@ private: label& compactI ); + scalar calcNearestDistance(const label nodeI) const; + + bool quickCircumsphereRejection + ( + const label nodeI, + const point& cc, + const scalar crSqr, + const List<scalar>& nearestDistances + ) const; + //- Determine inside/outside per node (mixed if cannot be // determined). Only valid for closed shapes. volumeType calcVolumeType(const label nodeI) const; @@ -320,6 +330,13 @@ private: const bool verbose = false ) const; +// bool isLineInsideOrOutside +// ( +// const label nodeI, +// const point& start, +// const point& end +// ) const; + //- Find any or nearest intersection of line between start and end. pointIndexHit findLine ( @@ -532,6 +549,19 @@ public: const scalar nearestDistSqr ) const; +// bool findAnyOverlap +// ( +// const point& sample, +// const scalar nearestDistSqr +// ) const; +// +// bool findAnyOverlap +// ( +// const label nodeI, +// const point& sample, +// const scalar nearestDistSqr +// ) const; + //- Low level: calculate nearest starting from subnode. void findNearest ( @@ -628,6 +658,16 @@ public: CompareOp& cop ) const; + //- Return a list containing the nearest distance of nodes to any + // shapes + List<scalar> calcNearestDistance() const; + + bool quickCircumsphereRejection + ( + const point& cc, + const scalar crSqr, + const List<scalar>& nearestDistances + ) const; // Write diff --git a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C index 0b2a45c473897ded3db69456b1ed73b6041817dd..448a009caba0396c33dfb38009d824e71d266113 100644 --- a/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C +++ b/src/OpenFOAM/fields/GeometricFields/GeometricField/GeometricBoundaryField.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -252,7 +252,7 @@ GeometricBoundaryField // Patch or patch-groups. (using non-wild card entries of dictionaries) forAllConstIter(dictionary, dict, iter) { - if (iter().isDict()) + if (iter().isDict() && !iter().keyword().isPattern()) { const labelList patchIDs = bmesh_.findIndices ( diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.C b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.C index 2465c726968f48d6a27ab19039edce6012d8cc53..8a9136b68a55c5eb00db3a8600aebb3244bdaaf8 100644 --- a/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.C +++ b/src/OpenFOAM/meshes/polyMesh/polyMeshTetDecomposition/polyMeshTetDecomposition.C @@ -555,9 +555,13 @@ Foam::List<Foam::tetIndices> Foam::polyMeshTetDecomposition::faceTetIndices { WarningIn ( - "Foam::List<Foam::FixedList<Foam::label, 4> >" - "Foam::Cloud<ParticleType>::" - "faceTetIndices(label fI, label cI) const" + "Foam::List<Foam::tetIndices> " + "Foam::polyMeshTetDecomposition::faceTetIndices" + "(" + "const polyMesh&, " + "label, " + "label" + ")" ) << "No base point for face " << fI << ", " << f << ", produces a valid tet decomposition." diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.C b/src/dynamicMesh/motionSmoother/motionSmoother.C index 4552d463200beb0b74551bf4224abd4a57011817..cace37690b88521f6927944fbb27617ca74f5d30 100644 --- a/src/dynamicMesh/motionSmoother/motionSmoother.C +++ b/src/dynamicMesh/motionSmoother/motionSmoother.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -271,9 +271,28 @@ Foam::labelHashSet Foam::motionSmoother::getPoints } +Foam::tmp<Foam::scalarField> Foam::motionSmoother::calcEdgeWeights +( + const pointField& points +) const +{ + const edgeList& edges = mesh_.edges(); + + tmp<scalarField> twght(new scalarField(edges.size())); + scalarField& wght = twght(); + + forAll(edges, edgeI) + { + wght[edgeI] = min(GREAT, 1.0/edges[edgeI].mag(points)); + } + return twght; +} + + // Smooth on selected points (usually patch points) void Foam::motionSmoother::minSmooth ( + const scalarField& edgeWeights, const PackedBoolList& isAffectedPoint, const labelList& meshPoints, const pointScalarField& fld, @@ -283,7 +302,7 @@ void Foam::motionSmoother::minSmooth tmp<pointScalarField> tavgFld = avg ( fld, - scalarField(mesh_.nEdges(), 1.0) // uniform weighting + edgeWeights //scalarField(mesh_.nEdges(), 1.0) // uniform weighting ); const pointScalarField& avgFld = tavgFld(); @@ -308,6 +327,7 @@ void Foam::motionSmoother::minSmooth // Smooth on all internal points void Foam::motionSmoother::minSmooth ( + const scalarField& edgeWeights, const PackedBoolList& isAffectedPoint, const pointScalarField& fld, pointScalarField& newFld @@ -316,7 +336,7 @@ void Foam::motionSmoother::minSmooth tmp<pointScalarField> tavgFld = avg ( fld, - scalarField(mesh_.nEdges(), 1.0) // uniform weighting + edgeWeights //scalarField(mesh_.nEdges(), 1.0) // uniform weighting ); const pointScalarField& avgFld = tavgFld(); @@ -337,7 +357,7 @@ void Foam::motionSmoother::minSmooth } -// Scale on selected points +// Scale on all internal points void Foam::motionSmoother::scaleField ( const labelHashSet& pointLabels, @@ -378,6 +398,47 @@ void Foam::motionSmoother::scaleField } +// Lower on internal points +void Foam::motionSmoother::subtractField +( + const labelHashSet& pointLabels, + const scalar f, + pointScalarField& fld +) const +{ + forAllConstIter(labelHashSet, pointLabels, iter) + { + if (isInternalPoint(iter.key())) + { + fld[iter.key()] = max(0.0, fld[iter.key()]-f); + } + } + fld.correctBoundaryConditions(); + applyCornerConstraints(fld); +} + + +// Scale on selected points (usually patch points) +void Foam::motionSmoother::subtractField +( + const labelList& meshPoints, + const labelHashSet& pointLabels, + const scalar f, + pointScalarField& fld +) const +{ + forAll(meshPoints, i) + { + label pointI = meshPoints[i]; + + if (pointLabels.found(pointI)) + { + fld[pointI] = max(0.0, fld[pointI]-f); + } + } +} + + bool Foam::motionSmoother::isInternalPoint(const label pointI) const { return isInternalPoint_.get(pointI) == 1; @@ -1081,13 +1142,17 @@ bool Foam::motionSmoother::scaleMesh { // Scale conflicting patch points scaleField(pp_.meshPoints(), usedPoints, errorReduction, scale_); + //subtractField(pp_.meshPoints(), usedPoints, 0.1, scale_); } if (smoothMesh) { // Scale conflicting internal points scaleField(usedPoints, errorReduction, scale_); + //subtractField(usedPoints, 0.1, scale_); } + scalarField eWeights(calcEdgeWeights(oldPoints_)); + for (label i = 0; i < nSmoothScale; i++) { if (adaptPatchIDs_.size()) @@ -1096,6 +1161,7 @@ bool Foam::motionSmoother::scaleMesh pointScalarField oldScale(scale_); minSmooth ( + eWeights, isAffectedPoint, pp_.meshPoints(), oldScale, @@ -1107,7 +1173,7 @@ bool Foam::motionSmoother::scaleMesh { // Smooth internal values pointScalarField oldScale(scale_); - minSmooth(isAffectedPoint, oldScale, scale_); + minSmooth(eWeights, isAffectedPoint, oldScale, scale_); checkFld(scale_); } } diff --git a/src/dynamicMesh/motionSmoother/motionSmoother.H b/src/dynamicMesh/motionSmoother/motionSmoother.H index b9ce2b9fa770c40336bb80a120747f67cab11201..fe4073c1b5a450d4871b5663d57580f8b2a9d96e 100644 --- a/src/dynamicMesh/motionSmoother/motionSmoother.H +++ b/src/dynamicMesh/motionSmoother/motionSmoother.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -229,9 +229,13 @@ class motionSmoother //- Get points used by given faces labelHashSet getPoints(const labelHashSet&) const; + //- Calculate per-edge weight + tmp<scalarField> calcEdgeWeights(const pointField&) const; + //- explicit smoothing and min on all affected internal points void minSmooth ( + const scalarField& edgeWeights, const PackedBoolList& isAffectedPoint, const pointScalarField& fld, pointScalarField& newFld @@ -240,6 +244,7 @@ class motionSmoother //- same but only on selected points (usually patch points) void minSmooth ( + const scalarField& edgeWeights, const PackedBoolList& isAffectedPoint, const labelList& meshPoints, const pointScalarField& fld, @@ -264,6 +269,24 @@ class motionSmoother pointScalarField& ) const; + //- Lower on internal points + void subtractField + ( + const labelHashSet& pointLabels, + const scalar f, + pointScalarField& + ) const; + + //- As above but points have to be in meshPoints as well + // (usually to scale patch points) + void subtractField + ( + const labelList& meshPoints, + const labelHashSet& pointLabels, + const scalar scale, + pointScalarField& + ) const; + //- Helper function. Is point internal? bool isInternalPoint(const label pointI) const; diff --git a/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.C b/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.C index 0ebb7b58ab6d0e54c7bc91092e02a51df9fadaa8..81f853aa417f1b3f2f0b264437bcc49ee47695d5 100644 --- a/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.C +++ b/src/edgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMesh.C @@ -546,6 +546,49 @@ Foam::extendedFeatureEdgeMesh::extendedFeatureEdgeMesh } featurePointNormals_ = featurePointNormals; + + + // Create featurePointEdges_ + // For each feature point, stores a list of edges which are arranged in + // order according to their connectivity + +// featurePointEdges_.setSize(nonFeatureStart_); +// +// Info<< sFeatEds.size() << " " << surf.pointEdges().size() << " " +// << edges().size() << endl; +// +// forAll(sFeatEds, eI) +// { +// Info<< "Edge " << eI << " " << sFeatEds[eI] << " " +// << edges()[eI] << endl; +// } +// +// const edgeList& edges = eds; +// +// for (label i = 0; i < nonFeatureStart_; i++) +// { +// const labelList& ptEds = surf.pointEdges()[i]; +// +// DynamicList<label> tmpFtEdges; +// +// forAll(ptEds, eI) +// { +// const label edgeI = ptEds[eI]; +// const edge& e = sFeatEds[edgeI]; +// +// Info<< "Edges: " << edgeI << " " << e << endl; +// +// forAll(sFeatEds, fEdgeI) +// { +// if (edges[fEdgeI] == e) +// { +// tmpFtEdges.append(fEdgeI); +// } +// } +// } +// +// featurePointEdges_[i] = tmpFtEdges; +// } } @@ -821,7 +864,7 @@ void Foam::extendedFeatureEdgeMesh::allNearestFeatureEdges if (!hitPoint.hit()) { - nearHit = pointIndexHit(true, hitPoint.missPoint(), hitIndex); + nearHit = pointIndexHit(false, hitPoint.missPoint(), hitIndex); } else { diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C index f70381471bda91d4c1a73244c5a1b2b68f2f2c64..c300cc53a71f8c4ecbc68b1da380e6e878154ecb 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriver.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -2067,8 +2067,10 @@ Foam::label Foam::autoLayerDriver::checkAndUnmark // The important thing, however, is that when only a few faces // are disabled, their coordinates are printed, and this should be // the case - label nReportLocal = - min + label nReportLocal = nChanged; + if (nChangedTotal > nReportMax) + { + nReportLocal = min ( max(nChangedTotal / Pstream::nProcs(), 1), min @@ -2077,11 +2079,15 @@ Foam::label Foam::autoLayerDriver::checkAndUnmark max(nReportMax / Pstream::nProcs(), 1) ) ); + } - Pout<< "Checked mesh with layers. Disabled extrusion at " << endl; - for (label i=0; i < nReportLocal; i++) + if (nReportLocal) { - Pout<< " " << disabledFaceCentres[i] << endl; + Pout<< "Checked mesh with layers. Disabled extrusion at " << endl; + for (label i=0; i < nReportLocal; i++) + { + Pout<< " " << disabledFaceCentres[i] << endl; + } } label nReportTotal = returnReduce(nReportLocal, sumOp<label>()); @@ -2546,7 +2552,7 @@ void Foam::autoLayerDriver::addLayers false ), meshMover().pMesh(), - dimensionedScalar("pointMedialDist", dimless, 0.0) + dimensionedScalar("pointMedialDist", dimLength, 0.0) ); pointVectorField dispVec @@ -2561,7 +2567,7 @@ void Foam::autoLayerDriver::addLayers false ), meshMover().pMesh(), - dimensionedVector("dispVec", dimless, vector::zero) + dimensionedVector("dispVec", dimLength, vector::zero) ); pointScalarField medialRatio diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C index 5731562575b50d515d75b641459f4f1ddf200cab..b6a9e338aa63b18e6fb18798f991f5c2a1fe813b 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverShrink.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -49,6 +49,8 @@ void Foam::autoLayerDriver::sumWeights scalarField& invSumWeight ) const { + const pointField& pts = meshRefiner_.mesh().points(); + invSumWeight = 0; forAll(edges, edgeI) @@ -57,7 +59,18 @@ void Foam::autoLayerDriver::sumWeights { const edge& e = edges[edgeI]; //scalar eWeight = edgeWeights[edgeI]; - scalar eWeight = 1.0; + //scalar eWeight = 1.0; + + scalar eMag = max + ( + VSMALL, + mag + ( + pts[meshPoints[e[1]]] + - pts[meshPoints[e[0]]] + ) + ); + scalar eWeight = 1.0/eMag; invSumWeight[e[0]] += eWeight; invSumWeight[e[1]] += eWeight; @@ -799,25 +812,54 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo // Both end points of edge have very different nearest wall // point. Mark both points as medial axis points. const edge& e = edges[edgeI]; - - forAll(e, ep) + // Approximate medial axis location on edge. + //const point medialAxisPt = e.centre(points); + vector eVec = e.vec(mesh.points()); + scalar eMag = mag(eVec); + if (eMag > VSMALL) { - label pointI = e[ep]; + eVec /= eMag; - if (!pointMedialDist[pointI].valid(dummyTrackData)) + // Calculate distance along edge + const point& p0 = points[e[0]]; + const point& p1 = points[e[1]]; + scalar dist0 = (p0-pointWallDist[e[0]].origin()) & eVec; + scalar dist1 = (pointWallDist[e[1]].origin()-p1) & eVec; + scalar s = 0.5*(dist1+eMag+dist0); + + point medialAxisPt; + if (s <= dist0) { - maxPoints.append(pointI); - maxInfo.append - ( - pointData + medialAxisPt = p0; + } + else if (s >= dist0+eMag) + { + medialAxisPt = p1; + } + else + { + medialAxisPt = p0+(s-dist0)*eVec; + } + + forAll(e, ep) + { + label pointI = e[ep]; + + if (!pointMedialDist[pointI].valid(dummyTrackData)) + { + maxPoints.append(pointI); + maxInfo.append ( - points[pointI], - 0.0, - pointI, // passive data - vector::zero // passive data - ) - ); - pointMedialDist[pointI] = maxInfo.last(); + pointData + ( + medialAxisPt, //points[pointI], + magSqr(points[pointI]-medialAxisPt),//0.0, + pointI, // passive data + vector::zero // passive data + ) + ); + pointMedialDist[pointI] = maxInfo.last(); + } } } } @@ -887,6 +929,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo forAll(pointMedialDist, pointI) { medialDist[pointI] = Foam::sqrt(pointMedialDist[pointI].distSqr()); + //medialVec[pointI] = pointMedialDist[pointI].origin(); } } @@ -923,11 +966,14 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo << " : normalised direction of nearest displacement" << nl << " " << medialDist.name() << " : distance to medial axis" << nl + //<< " " << medialVec.name() + //<< " : nearest point on medial axis" << nl << " " << medialRatio.name() << " : ratio of medial distance to wall distance" << nl << endl; dispVec.write(); medialDist.write(); + //medialVec.write(); medialRatio.write(); } } @@ -950,6 +996,7 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance const pointVectorField& dispVec, const pointScalarField& medialRatio, const pointScalarField& medialDist, + //const pointVectorField& medialVec, List<extrudeMode>& extrudeStatus, pointField& patchDisp, @@ -1025,10 +1072,23 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance { label pointI = meshPoints[patchPointI]; + //- Option 1: look only at extrusion thickness v.s. distance + // to nearest (medial axis or static) point. scalar mDist = medialDist[pointI]; - scalar thicknessRatio = thickness[patchPointI]/(mDist+VSMALL); + //- Option 2: Look at component in the direction + // of nearest (medial axis or static) point. + vector n = + patchDisp[patchPointI] + / (mag(patchDisp[patchPointI]) + VSMALL); + //vector mVec = mesh.points()[pointI]-medialVec[pointI]; + //scalar mDist = mag(mVec); + //scalar thicknessRatio = + // (n&mVec) + // *thickness[patchPointI] + // /(mDist+VSMALL); + if (thicknessRatio > maxThicknessToMedialRatio) { // Truncate thickness. @@ -1043,16 +1103,16 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance minThickness[patchPointI] +thickness[patchPointI] ) + //<< " since near medial at:" << medialVec[pointI] + //<< " with thicknessRatio:" << thicknessRatio << endl; } thickness[patchPointI] = 0.5*(minThickness[patchPointI]+thickness[patchPointI]); - patchDisp[patchPointI] = - thickness[patchPointI] - * patchDisp[patchPointI] - / (mag(patchDisp[patchPointI]) + VSMALL); + patchDisp[patchPointI] = thickness[patchPointI]*n; + numThicknessRatioExclude++; if (str.valid()) diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverTemplates.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverTemplates.C index ddfe4ed4affeea39996ae282674fd037b4edddf0..afb66396c88747a2baac3b68632d19d90c1f9d53 100644 --- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverTemplates.C +++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoLayerDriverTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -41,6 +41,8 @@ void Foam::autoLayerDriver::averageNeighbours Field<Type>& average ) { + const pointField& pts = mesh.points(); + average = pTraits<Type>::zero; forAll(edges, edgeI) @@ -49,7 +51,18 @@ void Foam::autoLayerDriver::averageNeighbours { const edge& e = edges[edgeI]; //scalar eWeight = edgeWeights[edgeI]; - scalar eWeight = 1.0; + //scalar eWeight = 1.0; + scalar eMag = max + ( + VSMALL, + mag + ( + pts[meshPoints[e[1]]] + - pts[meshPoints[e[0]]] + ) + ); + scalar eWeight = 1.0/eMag; + label v0 = e[0]; label v1 = e[1]; diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H index 96d7958528b4a2219a727a8d02d62fb1e6ea56fa..71afd2fba648eb9ef22beea8b3b1259e42e0a29f 100644 --- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H +++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.H @@ -244,6 +244,7 @@ protected: const label size ); + public: //- Runtime type information @@ -319,6 +320,9 @@ public: //- Patch (only if NEARESTPATCHFACE) inline const word& samplePatch() const; + //- Return size of mapped mesh/patch/boundary + inline label sampleSize() const; + //- Offset vector (from patch faces to destination mesh objects) inline const vector& offset() const; diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H index 5814a1e824e95b8de63276793f91b790f8620b0f..928fa86ad7ddf26b31e342cdaa16e4d15856525c 100644 --- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H +++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseI.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -42,6 +42,37 @@ inline const Foam::word& Foam::mappedPatchBase::samplePatch() const } +inline Foam::label Foam::mappedPatchBase::sampleSize() const +{ + switch (mode_) + { + case NEARESTPATCHFACEAMI: + { + return samplePolyPatch().size(); + } + case NEARESTCELL: + { + return sampleMesh().nCells(); + } + case NEARESTPATCHFACE: + { + return samplePolyPatch().size(); + } + case NEARESTFACE: + { + const polyMesh& mesh = sampleMesh(); + return mesh.nFaces() - mesh.nInternalFaces(); + } + default: + { + FatalErrorIn("mappedPatchBase::sampleSize()") + << "problem." << abort(FatalError); + return -1; + } + } +} + + inline const Foam::vector& Foam::mappedPatchBase::offset() const { return offset_; diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C index 47067b00f66328ff0a7ad6ec561657563bcf6f19..a4e36ff4575aff7806297c4596ff8454e2210c27 100644 --- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C +++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBaseTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -89,8 +89,8 @@ void Foam::mappedPatchBase::reverseDistribute(List<Type>& lst) const } default: { - label cSize = patch_.size(); - map().reverseDistribute(cSize, lst); + map().reverseDistribute(sampleSize(), lst); + break; } } } @@ -116,7 +116,7 @@ void Foam::mappedPatchBase::reverseDistribute } default: { - label cSize = patch_.size(); + label cSize = sampleSize(); map().distribute ( Pstream::defaultCommsType, @@ -128,6 +128,7 @@ void Foam::mappedPatchBase::reverseDistribute bop, pTraits<Type>::zero ); + break; } } } diff --git a/src/meshTools/searchableSurface/searchableSurfacesQueries.C b/src/meshTools/searchableSurface/searchableSurfacesQueries.C index bea97b328845bddfe22b078dddac7ab0fdd6ba7e..4db8f9acf37f58a13c9e874c657ab6aa9b7202a9 100644 --- a/src/meshTools/searchableSurface/searchableSurfacesQueries.C +++ b/src/meshTools/searchableSurface/searchableSurfacesQueries.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -27,6 +27,7 @@ License #include "ListOps.H" #include "OFstream.H" #include "meshTools.H" +#include "DynamicField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -686,6 +687,81 @@ void Foam::searchableSurfacesQueries::findNearest } +void Foam::searchableSurfacesQueries::signedDistance +( + const PtrList<searchableSurface>& allSurfaces, + const labelList& surfacesToTest, + const pointField& samples, + const scalarField& nearestDistSqr, + labelList& nearestSurfaces, + scalarField& distance +) +{ + // Initialise + distance.setSize(samples.size()); + distance = -GREAT; + + // Find nearest + List<pointIndexHit> nearestInfo; + findNearest + ( + allSurfaces, + surfacesToTest, + samples, + nearestDistSqr, + nearestSurfaces, + nearestInfo + ); + + // Determine sign of nearest. Sort by surface to do this. + DynamicField<point> surfPoints(samples.size()); + DynamicList<label> surfIndices(samples.size()); + + forAll(surfacesToTest, testI) + { + // Extract samples on this surface + surfPoints.clear(); + surfIndices.clear(); + forAll(nearestSurfaces, i) + { + if (nearestSurfaces[i] == testI) + { + surfPoints.append(samples[i]); + surfIndices.append(i); + } + } + + // Calculate sideness of these surface points + List<searchableSurface::volumeType> volType; + allSurfaces[surfacesToTest[testI]].getVolumeType(surfPoints, volType); + + // Push back to original + forAll(volType, i) + { + label pointI = surfIndices[i]; + scalar dist = mag(samples[pointI] - nearestInfo[pointI].hitPoint()); + + searchableSurface::volumeType vT = volType[i]; + + if (vT == searchableSurface::OUTSIDE) + { + distance[pointI] = dist; + } + else if (vT == searchableSurface::INSIDE) + { + distance[i] = -dist; + } + else + { + FatalErrorIn("signedDistance()") + << "getVolumeType failure, neither INSIDE or OUTSIDE" + << exit(FatalError); + } + } + } +} + + Foam::boundBox Foam::searchableSurfacesQueries::bounds ( const PtrList<searchableSurface>& allSurfaces, diff --git a/src/meshTools/searchableSurface/searchableSurfacesQueries.H b/src/meshTools/searchableSurface/searchableSurfacesQueries.H index 6aa2245409707fdd96ce474ff7be0f07b7a8d3b2..a2dba23cb5d295a7b80338275a57d697ed670454 100644 --- a/src/meshTools/searchableSurface/searchableSurfacesQueries.H +++ b/src/meshTools/searchableSurface/searchableSurfacesQueries.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -184,6 +184,17 @@ public: List<pointIndexHit>& ); + //- Find signed distance to nearest surface + static void signedDistance + ( + const PtrList<searchableSurface>& allSurfaces, + const labelList& surfacesToTest, + const pointField& samples, + const scalarField& nearestDistSqr, + labelList& nearestSurfaces, + scalarField& distance + ); + //- Find the boundBox of the selected surfaces static boundBox bounds ( diff --git a/src/regionModels/thermoBaffleModels/thermoBaffle2D/thermoBaffle2D.C b/src/regionModels/thermoBaffleModels/thermoBaffle2D/thermoBaffle2D.C index 3e131d84b75cb66b9d9293da3ce05f8fd7781151..d251bc64e034fdcd28f8f59ba516d0f1e0ab0177 100644 --- a/src/regionModels/thermoBaffleModels/thermoBaffle2D/thermoBaffle2D.C +++ b/src/regionModels/thermoBaffleModels/thermoBaffle2D/thermoBaffle2D.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -146,12 +146,12 @@ void thermoBaffle2D::solveEnergy() TEqn -= fvc::div(phiMesh); } - Info<< "T gas min/max = " << min(T_).value() << ", " - << max(T_).value() << endl; - TEqn.relax(); TEqn.solve(); + Info<< "T gas min/max = " << min(T_).value() << ", " + << max(T_).value() << endl; + thermo_->correct(); } @@ -362,7 +362,7 @@ void thermoBaffle2D::info() const ( mag(regionMesh().Sf().boundaryField()[patchI]) * pT.snGrad() - * thermo_->K().boundaryField()[patchI] + * thermo_->K(patchI) ) << endl; } } diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurface.C b/src/sampling/sampledSurface/distanceSurface/distanceSurface.C index 6b557df91844b2fce50573d970ddc6e85b496016..7d9c4eace454d7cd0bab0c351267530c03ab8cf5 100644 --- a/src/sampling/sampledSurface/distanceSurface/distanceSurface.C +++ b/src/sampling/sampledSurface/distanceSurface/distanceSurface.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -49,6 +49,8 @@ void Foam::distanceSurface::createGeometry() // Clear any stored topologies facesPtr_.clear(); + isoSurfCellPtr_.clear(); + isoSurfPtr_.clear(); // Clear derived data clearGeom(); @@ -265,24 +267,33 @@ void Foam::distanceSurface::createGeometry() //- Direct from cell field and point field. - isoSurfPtr_.reset - ( - new isoSurface + if (cell_) + { + isoSurfCellPtr_.reset ( - cellDistance, - pointDistance_, - distance_, - regularise_ - ) - //new isoSurfaceCell - //( - // fvm, - // cellDistance, - // pointDistance_, - // distance_, - // regularise_ - //) - ); + new isoSurfaceCell + ( + fvm, + cellDistance, + pointDistance_, + distance_, + regularise_ + ) + ); + } + else + { + isoSurfPtr_.reset + ( + new isoSurface + ( + cellDistance, + pointDistance_, + distance_, + regularise_ + ) + ); + } if (debug) { @@ -321,10 +332,12 @@ Foam::distanceSurface::distanceSurface ), distance_(readScalar(dict.lookup("distance"))), signed_(readBool(dict.lookup("signed"))), + cell_(dict.lookupOrDefault("cell", true)), regularise_(dict.lookupOrDefault("regularise", true)), average_(dict.lookupOrDefault("average", false)), zoneKey_(keyType::null), needsUpdate_(true), + isoSurfCellPtr_(NULL), isoSurfPtr_(NULL), facesPtr_(NULL) { @@ -338,6 +351,52 @@ Foam::distanceSurface::distanceSurface } + +Foam::distanceSurface::distanceSurface +( + const word& name, + const polyMesh& mesh, + const bool interpolate, + const word& surfaceType, + const word& surfaceName, + const scalar distance, + const bool signedDistance, + const bool cell, + const Switch regularise, + const Switch average +) +: + sampledSurface(name, mesh, interpolate), + surfPtr_ + ( + searchableSurface::New + ( + surfaceType, + IOobject + ( + surfaceName, // name + mesh.time().constant(), // directory + "triSurface", // instance + mesh.time(), // registry + IOobject::MUST_READ, + IOobject::NO_WRITE + ), + dictionary() + ) + ), + distance_(distance), + signed_(signedDistance), + cell_(cell), + regularise_(regularise), + average_(average), + zoneKey_(keyType::null), + needsUpdate_(true), + isoSurfCellPtr_(NULL), + isoSurfPtr_(NULL), + facesPtr_(NULL) +{} + + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::distanceSurface::~distanceSurface() diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurface.H b/src/sampling/sampledSurface/distanceSurface/distanceSurface.H index a7040ba7f8d96fa07e53c0160f2831fade41f1bd..2b971970872db59f58db19a885ac9d363a0fdd58 100644 --- a/src/sampling/sampledSurface/distanceSurface/distanceSurface.H +++ b/src/sampling/sampledSurface/distanceSurface/distanceSurface.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -27,6 +27,8 @@ Class Description A sampledSurface defined by a distance to a surface. + Uses either isoSurfaceCell or isoSurface. + SourceFiles distanceSurface.C @@ -37,7 +39,7 @@ SourceFiles #include "sampledSurface.H" #include "searchableSurface.H" -//#include "isoSurfaceCell.H" +#include "isoSurfaceCell.H" #include "isoSurface.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -64,6 +66,9 @@ class distanceSurface //- signed distance const bool signed_; + //- Whether to use isoSurfaceCell or isoSurface + const bool cell_; + //- Whether to coarsen const Switch regularise_; @@ -84,7 +89,9 @@ class distanceSurface scalarField pointDistance_; //- Constructed iso surface - //autoPtr<isoSurfaceCell> isoSurfPtr_; + autoPtr<isoSurfaceCell> isoSurfCellPtr_; + + //- Constructed iso surface autoPtr<isoSurface> isoSurfPtr_; //- triangles converted to faceList @@ -125,6 +132,21 @@ public: const dictionary& dict ); + //- Construct from components + distanceSurface + ( + const word& name, + const polyMesh& mesh, + const bool interpolate, + const word& surfaceType, + const word& surfaceName, + const scalar distance, + const bool signedDistance, + const bool cell, + const Switch regularise, + const Switch average + ); + //- Destructor virtual ~distanceSurface(); @@ -167,11 +189,16 @@ public: return facesPtr_; } - - //const isoSurfaceCell& surface() const - const isoSurface& surface() const + const triSurface& surface() const { - return isoSurfPtr_(); + if (cell_) + { + return isoSurfCellPtr_(); + } + else + { + return isoSurfPtr_(); + } } //- sample field on surface diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurfaceTemplates.C b/src/sampling/sampledSurface/distanceSurface/distanceSurfaceTemplates.C index 5701d09c24fcd49254ea126fdefa2f5fe28d0dba..d8871126ea71629c05d62e9a196ca6b7602fdfe8 100644 --- a/src/sampling/sampledSurface/distanceSurface/distanceSurfaceTemplates.C +++ b/src/sampling/sampledSurface/distanceSurface/distanceSurfaceTemplates.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -37,7 +37,20 @@ Foam::distanceSurface::sampleField const GeometricField<Type, fvPatchField, volMesh>& vField ) const { - return tmp<Field<Type> >(new Field<Type>(vField, surface().meshCells())); + if (cell_) + { + return tmp<Field<Type> > + ( + new Field<Type>(vField, isoSurfCellPtr_().meshCells()) + ); + } + else + { + return tmp<Field<Type> > + ( + new Field<Type>(vField, isoSurfPtr_().meshCells()) + ); + } } @@ -60,15 +73,30 @@ Foam::distanceSurface::interpolateField ); // Sample. - return surface().interpolate - ( + if (cell_) + { + return isoSurfCellPtr_().interpolate ( - average_ - ? pointAverage(pointFld())() - : volFld - ), - pointFld() - ); + ( + average_ + ? pointAverage(pointFld())() + : volFld + ), + pointFld() + ); + } + else + { + return isoSurfPtr_().interpolate + ( + ( + average_ + ? pointAverage(pointFld())() + : volFld + ), + pointFld() + ); + } } diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C index 0b812717fa6c27bc1d3a66fec9b43b892da9dfb3..5c7c5abb90c50b43d7c66f60adff1d1f7acd323a 100644 --- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C +++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -152,12 +152,13 @@ Foam::autoPtr<Foam::sampledSurface> Foam::sampledSurface::New Foam::sampledSurface::sampledSurface ( const word& name, - const polyMesh& mesh + const polyMesh& mesh, + const bool interpolate ) : name_(name), mesh_(mesh), - interpolate_(false), + interpolate_(interpolate), SfPtr_(NULL), magSfPtr_(NULL), CfPtr_(NULL), diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H index 5b4683bee56516f235598a587e20a2465c851c70..9843143107269573d564d0223d7af14e8873ea37 100644 --- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H +++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -81,7 +81,7 @@ class sampledSurface const polyMesh& mesh_; //- Do we intend to interpolate the information? - bool interpolate_; + const bool interpolate_; // Demand-driven data @@ -197,7 +197,8 @@ public: sampledSurface ( const word& name, - const polyMesh& + const polyMesh&, + const bool interpolate = false ); //- Construct from dictionary diff --git a/src/thermophysicalModels/basicSolidThermo/basicSolidThermo/basicSolidThermo.C b/src/thermophysicalModels/basicSolidThermo/basicSolidThermo/basicSolidThermo.C index 2ecdd91b9eaafe51944559f0d1f63b326d762086..5e62a55eee3a7d5f12252385c9dde34b6498fe9d 100644 --- a/src/thermophysicalModels/basicSolidThermo/basicSolidThermo/basicSolidThermo.C +++ b/src/thermophysicalModels/basicSolidThermo/basicSolidThermo/basicSolidThermo.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -257,20 +257,6 @@ const Foam::volScalarField& Foam::basicSolidThermo::emissivity() const } -const Foam::volScalarField& Foam::basicSolidThermo::K() const -{ - notImplemented("basicSolidThermo::K()"); - return volScalarField::null(); -} - - -const Foam::volSymmTensorField& Foam::basicSolidThermo::directionalK() const -{ - notImplemented("basicSolidThermo::directionalK()"); - return const_cast<volSymmTensorField&>(volSymmTensorField::null()); -} - - Foam::basicSolidMixture& Foam::basicSolidThermo::composition() { notImplemented("basicSolidThermo::composition()"); @@ -287,7 +273,7 @@ const Foam::basicSolidMixture& Foam::basicSolidThermo::composition() const Foam::tmp<Foam::volScalarField> Foam::basicSolidThermo::hs() const { - notImplemented("basicSolidThermo::hs()"); + notImplemented("basicSolidThermo::hs() const"); return volScalarField::null(); } @@ -295,31 +281,11 @@ Foam::tmp<Foam::volScalarField> Foam::basicSolidThermo::hs() const Foam::tmp<Foam::scalarField> Foam::basicSolidThermo::hs(const label patchI) const { - notImplemented("basicSolidThermo::hs(const label)"); - return scalarField::null(); -} - - -Foam::tmp<Foam::scalarField> Foam::basicSolidThermo::K -( - const label patchI -)const -{ - notImplemented("basicSolidThermo::K(const label)"); + notImplemented("basicSolidThermo::hs(const label) const"); return scalarField::null(); } -Foam::tmp<Foam::symmTensorField> Foam::basicSolidThermo::directionalK -( - const label -)const -{ - notImplemented("basicSolidThermo::directionalK(const label)"); - return symmTensorField::null(); -} - - bool Foam::basicSolidThermo::read() { return regIOobject::read(); diff --git a/src/thermophysicalModels/basicSolidThermo/basicSolidThermo/basicSolidThermo.H b/src/thermophysicalModels/basicSolidThermo/basicSolidThermo/basicSolidThermo.H index 84ded7e35a23fd16d7505b60d593146b94ac0cf0..3def4a0ee5235ca1bfc12b09b0c9380458329567 100644 --- a/src/thermophysicalModels/basicSolidThermo/basicSolidThermo/basicSolidThermo.H +++ b/src/thermophysicalModels/basicSolidThermo/basicSolidThermo/basicSolidThermo.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -144,35 +144,35 @@ public: // Access to thermodynamic state variables - //- Density [kg/m^3] - const volScalarField& rho() const; + //- Temperature [K] + virtual const volScalarField& T() const; - //- Thermal conductivity [W/m/K] - virtual const volScalarField& K() const; + //- non-const access for T + virtual volScalarField& T(); - //- Thermal conductivity [W/m/K] - virtual const volSymmTensorField& directionalK() const; + //- Density [kg/m^3] + virtual const volScalarField& rho() const; + + //- non-const access for rho + virtual volScalarField& rho(); //- Absorption coefficient [1/m] - const volScalarField& kappa() const; + virtual const volScalarField& kappa() const; //- Emissivity coefficient - const volScalarField& sigmaS() const; + virtual const volScalarField& sigmaS() const; //- Emissivity coefficient [1/m] - const volScalarField& emissivity() const; - - //- Temperature [K] - const volScalarField& T() const; + virtual const volScalarField& emissivity() const; - //- non-const access for T - volScalarField& T(); - //- non-const access for rho - volScalarField& rho(); + // Derived thermal properties + //- Thermal conductivity [W/m/K] + virtual tmp<volScalarField> K() const = 0; - // Derived thermal properties + //- Thermal conductivity [W/m/K] + virtual tmp<volSymmTensorField> directionalK() const = 0; //- Specific heat capacity [J/kg/K] virtual tmp<volScalarField> Cp() const = 0; @@ -186,8 +186,11 @@ public: // Per patch calculation - //- Density [kg/m3] - virtual tmp<scalarField> rho(const label patchI) const = 0; + //- Thermal conductivity [W//m/K] + virtual tmp<scalarField> K(const label patchI) const = 0; + + //- Thermal conductivity [W//m/K] + virtual tmp<symmTensorField> directionalK(const label) const = 0; //- Specific heat capacity [J/kg/K)] virtual tmp<scalarField> Cp(const label patchI) const = 0; @@ -195,24 +198,9 @@ public: //- Sensible enthalpy [J/kg] virtual tmp<scalarField> hs(const label patchI) const; - //- Thermal conductivity [W//m/K] - virtual tmp<scalarField> K(const label patchI) const; - - //- Thermal conductivity [W//m/K] - virtual tmp<symmTensorField> directionalK(const label) const; - //- Heat of formation [J/kg] virtual tmp<scalarField> Hf(const label patchI) const = 0; - //- Scatter coefficient [1/m] - virtual tmp<scalarField> sigmaS(const label) const = 0; - - //- Absorption coefficient [1/m] - virtual tmp<scalarField> kappa(const label) const = 0; - - //- Emissivity [] - virtual tmp<scalarField> emissivity(const label) const = 0; - // I-O //- Write the basicSolidThermo properties diff --git a/src/thermophysicalModels/basicSolidThermo/constSolidThermo/constSolidThermo.C b/src/thermophysicalModels/basicSolidThermo/constSolidThermo/constSolidThermo.C index 2434d959c3ffcda671e66719a53d8becf77fcc3a..ee20901aac3a79685207ccb86372e9696093dca5 100644 --- a/src/thermophysicalModels/basicSolidThermo/constSolidThermo/constSolidThermo.C +++ b/src/thermophysicalModels/basicSolidThermo/constSolidThermo/constSolidThermo.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -132,34 +132,13 @@ void Foam::constSolidThermo::correct() {} -Foam::tmp<Foam::volScalarField> Foam::constSolidThermo::Cp() const -{ - return tmp<volScalarField> - ( - new volScalarField - ( - IOobject - ( - "Cp", - mesh_.time().timeName(), - mesh_, - IOobject::NO_READ, - IOobject::NO_WRITE - ), - mesh_, - constCp_ - ) - ); -} - - -const Foam::volScalarField& Foam::constSolidThermo::K() const +Foam::tmp<Foam::volScalarField> Foam::constSolidThermo::K() const { return K_; } -const Foam::volSymmTensorField& Foam::constSolidThermo::directionalK() const +Foam::tmp<Foam::volSymmTensorField> Foam::constSolidThermo::directionalK() const { dimensionedSymmTensor t ( @@ -194,7 +173,7 @@ const Foam::volSymmTensorField& Foam::constSolidThermo::directionalK() const } -Foam::tmp<Foam::volScalarField> Foam::constSolidThermo::Hf() const +Foam::tmp<Foam::volScalarField> Foam::constSolidThermo::Cp() const { return tmp<volScalarField> ( @@ -202,46 +181,35 @@ Foam::tmp<Foam::volScalarField> Foam::constSolidThermo::Hf() const ( IOobject ( - "Hf", + "Cp", mesh_.time().timeName(), mesh_, IOobject::NO_READ, IOobject::NO_WRITE ), mesh_, - constHf_ - ) - ); -} - - -Foam::tmp<Foam::scalarField> Foam::constSolidThermo::rho -( - const label patchI -) const -{ - return tmp<scalarField> - ( - new scalarField - ( - T_.boundaryField()[patchI].size(), - constRho_.value() + constCp_ ) ); } -Foam::tmp<Foam::scalarField> Foam::constSolidThermo::Cp -( - const label patchI -) const +Foam::tmp<Foam::volScalarField> Foam::constSolidThermo::Hf() const { - return tmp<scalarField> + return tmp<volScalarField> ( - new scalarField + new volScalarField ( - T_.boundaryField()[patchI].size(), - constCp_.value() + IOobject + ( + "Hf", + mesh_.time().timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh_, + constHf_ ) ); } @@ -281,39 +249,7 @@ Foam::tmp<Foam::symmTensorField> Foam::constSolidThermo::directionalK } -Foam::tmp<Foam::scalarField> Foam::constSolidThermo::Hf -( - const label patchI -) const -{ - return tmp<scalarField> - ( - new scalarField - ( - T_.boundaryField()[patchI].size(), - constHf_.value() - ) - ); -} - - -Foam::tmp<Foam::scalarField> Foam::constSolidThermo::emissivity -( - const label patchI -) const -{ - return tmp<scalarField> - ( - new scalarField - ( - T_.boundaryField()[patchI].size(), - constEmissivity_.value() - ) - ); -} - - -Foam::tmp<Foam::scalarField> Foam::constSolidThermo::kappa +Foam::tmp<Foam::scalarField> Foam::constSolidThermo::Cp ( const label patchI ) const @@ -323,13 +259,13 @@ Foam::tmp<Foam::scalarField> Foam::constSolidThermo::kappa new scalarField ( T_.boundaryField()[patchI].size(), - constKappa_.value() + constCp_.value() ) ); } -Foam::tmp<Foam::scalarField> Foam::constSolidThermo::sigmaS +Foam::tmp<Foam::scalarField> Foam::constSolidThermo::Hf ( const label patchI ) const @@ -339,7 +275,7 @@ Foam::tmp<Foam::scalarField> Foam::constSolidThermo::sigmaS new scalarField ( T_.boundaryField()[patchI].size(), - constSigmaS_.value() + constHf_.value() ) ); } diff --git a/src/thermophysicalModels/basicSolidThermo/constSolidThermo/constSolidThermo.H b/src/thermophysicalModels/basicSolidThermo/constSolidThermo/constSolidThermo.H index cba0bda908a26a07662dfcc9319f2d0020313053..75a5068552d0ed377cabc600d598e98a003db418 100644 --- a/src/thermophysicalModels/basicSolidThermo/constSolidThermo/constSolidThermo.H +++ b/src/thermophysicalModels/basicSolidThermo/constSolidThermo/constSolidThermo.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -107,16 +107,13 @@ public: virtual void correct(); - // Acces functions + // Derived thermal properties - //- Constant access to K - virtual const volScalarField& K() const; + //- Thermal conductivity [W/m/K] + virtual tmp<volScalarField> K() const; - //- Thermal conductivity [W/(m.K)] - virtual const volSymmTensorField& directionalK() const; - - - // Derived properties + //- Thermal conductivity [W/m/K] + virtual tmp<volSymmTensorField> directionalK() const; //- Specific heat capacity [J/(kg.K)] virtual tmp<volScalarField> Cp() const; @@ -127,29 +124,18 @@ public: // Per patch calculation - //- Density [kg/m3] - virtual tmp<scalarField> rho(const label patchI) const; - - //- Specific heat capacity [J/kg/K)] - virtual tmp<scalarField> Cp(const label patchI) const; - //- Thermal conductivity [W//m/K] virtual tmp<scalarField> K(const label patchI) const; //- Thermal conductivity [W//m/K] virtual tmp<symmTensorField>directionalK(const label) const; + //- Specific heat capacity [J/kg/K)] + virtual tmp<scalarField> Cp(const label patchI) const; + //- Heat of formation [J/kg] virtual tmp<scalarField> Hf(const label patchI) const; - //- Scatter coefficient [1/m] - virtual tmp<scalarField> sigmaS(const label) const; - - //- Absorption coefficient [1/m] - virtual tmp<scalarField> kappa(const label) const; - - //- Emissivity [] - virtual tmp<scalarField> emissivity(const label) const; // I-O diff --git a/src/thermophysicalModels/basicSolidThermo/directionalKSolidThermo/directionalKSolidThermo.C b/src/thermophysicalModels/basicSolidThermo/directionalKSolidThermo/directionalKSolidThermo.C index c6a4de63dd41c317e253d486a96289a91bf3b472..e2185e45f5883c381a2cb9e902322e40769a9fa0 100644 --- a/src/thermophysicalModels/basicSolidThermo/directionalKSolidThermo/directionalKSolidThermo.C +++ b/src/thermophysicalModels/basicSolidThermo/directionalKSolidThermo/directionalKSolidThermo.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -136,12 +136,10 @@ void Foam::directionalKSolidThermo::init() { KValues_ = Field<vector>(subDict(typeName + "Coeffs").lookup("KValues")); - const fvMesh& mesh = K().mesh(); - // Determine transforms for cell centres - forAll(mesh.C(), cellI) + forAll(mesh_.C(), cellI) { - vector dir = mesh.C()[cellI] - coordSys_.origin(); + vector dir = mesh_.C()[cellI] - coordSys_.origin(); dir /= mag(dir); // Define local coordinate system with @@ -158,9 +156,9 @@ void Foam::directionalKSolidThermo::init() ccTransforms_[cellI] = cs.R(); } - forAll(mesh.C().boundaryField(), patchI) + forAll(mesh_.C().boundaryField(), patchI) { - const fvPatchVectorField& patchC = mesh.C().boundaryField()[patchI]; + const fvPatchVectorField& patchC = mesh_.C().boundaryField()[patchI]; fvPatchTensorField& patchT = ccTransforms_.boundaryField()[patchI]; tensorField tc(patchT.size()); @@ -192,13 +190,13 @@ void Foam::directionalKSolidThermo::init() IOobject ( "Kxx", - mesh.time().timeName(), - mesh, + mesh_.time().timeName(), + mesh_, IOobject::NO_READ, IOobject::AUTO_WRITE, false ), - mesh, + mesh_, dimless ); Kxx.internalField() = transform @@ -230,13 +228,13 @@ void Foam::directionalKSolidThermo::init() IOobject ( "Kyy", - mesh.time().timeName(), - mesh, + mesh_.time().timeName(), + mesh_, IOobject::NO_READ, IOobject::AUTO_WRITE, false ), - mesh, + mesh_, dimless ); Kyy.internalField() = transform @@ -268,13 +266,13 @@ void Foam::directionalKSolidThermo::init() IOobject ( "Kzz", - mesh.time().timeName(), - mesh, + mesh_.time().timeName(), + mesh_, IOobject::NO_READ, IOobject::AUTO_WRITE, false ), - mesh, + mesh_, dimless ); Kzz.internalField() = transform @@ -363,7 +361,7 @@ void Foam::directionalKSolidThermo::correct() } -const Foam::volSymmTensorField& +Foam::tmp<Foam::volSymmTensorField> Foam::directionalKSolidThermo::directionalK() const { return directionalK_; @@ -398,105 +396,6 @@ void Foam::directionalKSolidThermo::calculate() } -const Foam::volScalarField& Foam::directionalKSolidThermo::K() const -{ - forAll(KValues_, i) - { - const vector& v = KValues_[i]; - if - ( - v.x() != v.y() - || v.x() != v.z() - || v.y() != v.z() - ) - { - FatalErrorIn("directionalKSolidThermo::K() const") - << "Supplied K values " << KValues_ - << " are not isotropic." << exit(FatalError); - } - } - - // Get temperature interpolated properties (principal directions) - Field<vector> localK - ( - interpolateXY - ( - T_.internalField(), - TValues_, - KValues_ - ) - ); - - tmp<volScalarField> tK - ( - new volScalarField - ( - IOobject - ( - "K", - mesh_.time().timeName(), - mesh_, - IOobject::NO_READ, - IOobject::NO_WRITE - ), - mesh_, - dimEnergy/dimTime/(dimLength*dimTemperature) - ) - ); - volScalarField& K = tK(); - - K.internalField() = interpolateXY - ( - T_.internalField(), - TValues_, - KValues_.component(0)() - ); - - forAll(K.boundaryField(), patchI) - { - K.boundaryField()[patchI] == this->K(patchI)(); - } - - return tK; -} - - -Foam::tmp<Foam::scalarField> Foam::directionalKSolidThermo::K -( - const label patchI -) const -{ - forAll(KValues_, i) - { - const vector& v = KValues_[i]; - if - ( - v.x() != v.y() - || v.x() != v.z() - || v.y() != v.z() - ) - { - FatalErrorIn("directionalKSolidThermo::K() const") - << "Supplied K values " << KValues_ - << " are not isotropic." << exit(FatalError); - } - } - - return tmp<scalarField> - ( - new scalarField - ( - interpolateXY - ( - T_.boundaryField()[patchI], - TValues_, - KValues_.component(0)() - ) - ) - ); -} - - Foam::tmp<Foam::symmTensorField> Foam::directionalKSolidThermo::directionalK ( const label patchI diff --git a/src/thermophysicalModels/basicSolidThermo/directionalKSolidThermo/directionalKSolidThermo.H b/src/thermophysicalModels/basicSolidThermo/directionalKSolidThermo/directionalKSolidThermo.H index 6872bec26f5ecd06649d54237d86e4ef14fcdd53..c5c8ad9cc8288a1adfc7c72e103fe4d13b38ee52 100644 --- a/src/thermophysicalModels/basicSolidThermo/directionalKSolidThermo/directionalKSolidThermo.H +++ b/src/thermophysicalModels/basicSolidThermo/directionalKSolidThermo/directionalKSolidThermo.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -116,16 +116,24 @@ public: //- Access functions - //- Thermal conductivity [W/(m.K)] - virtual const volSymmTensorField& directionalK() const; + //- Thermal conductivity [W/m/K] + virtual tmp<volScalarField> K() const + { + notImplemented("directionalKSolidThermo::K() const"); + return tmp<volScalarField>(NULL); + } - //- Iostropic thermal conductivity [W/(m.K)] - virtual const volScalarField& K() const; + //- Thermal conductivity [W/m/K] + virtual tmp<volSymmTensorField> directionalK() const; - // Per patch calculation + // Per patch calculation //- Thermal conductivity [W//m/K] - virtual tmp<scalarField> K(const label patchI) const; + virtual tmp<scalarField> K(const label patchI) const + { + notImplemented("directionalKSolidThermo::K(const label) const"); + return tmp<scalarField>(NULL); + } //- Thermal conductivity [W//m/K] virtual tmp<symmTensorField> directionalK(const label) const; diff --git a/src/thermophysicalModels/basicSolidThermo/interpolatedSolidThermo/interpolatedSolidThermo.C b/src/thermophysicalModels/basicSolidThermo/interpolatedSolidThermo/interpolatedSolidThermo.C index bfabc2ed603b1728328aee1aedd25ebee3bc41da..def8dc6160e2df77d25ec775da1da57d3d801f01 100644 --- a/src/thermophysicalModels/basicSolidThermo/interpolatedSolidThermo/interpolatedSolidThermo.C +++ b/src/thermophysicalModels/basicSolidThermo/interpolatedSolidThermo/interpolatedSolidThermo.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -27,6 +27,88 @@ License #include "interpolateXY.H" +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::rho +( + const label patchI +) const +{ + return tmp<scalarField> + ( + new scalarField + ( + interpolateXY + ( + T_.boundaryField()[patchI], + TValues_, + rhoValues_ + ) + ) + ); +} + + +Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::emissivity +( + const label patchI +) const +{ + return tmp<scalarField> + ( + new scalarField + ( + interpolateXY + ( + T_.boundaryField()[patchI], + TValues_, + emissivityValues_ + ) + ) + ); +} + + +Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::kappa +( + const label patchI +) const +{ + return tmp<scalarField> + ( + new scalarField + ( + interpolateXY + ( + T_.boundaryField()[patchI], + TValues_, + kappaValues_ + ) + ) + ); +} + + +Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::sigmaS +( + const label patchI +) const +{ + return tmp<scalarField> + ( + new scalarField + ( + interpolateXY + ( + T_.boundaryField()[patchI], + TValues_, + sigmaSValues_ + ) + ) + ); +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::interpolatedSolidThermo::interpolatedSolidThermo @@ -57,6 +139,7 @@ Foam::interpolatedSolidThermo::interpolatedSolidThermo calculate(); } + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::interpolatedSolidThermo::~interpolatedSolidThermo() @@ -195,26 +278,6 @@ Foam::tmp<Foam::volScalarField> Foam::interpolatedSolidThermo::Hf() const } -Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::rho -( - const label patchI -) const -{ - return tmp<scalarField> - ( - new scalarField - ( - interpolateXY - ( - T_.boundaryField()[patchI], - TValues_, - rhoValues_ - ) - ) - ); -} - - Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::Cp ( const label patchI @@ -255,66 +318,6 @@ Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::Hf } -Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::emissivity -( - const label patchI -) const -{ - return tmp<scalarField> - ( - new scalarField - ( - interpolateXY - ( - T_.boundaryField()[patchI], - TValues_, - emissivityValues_ - ) - ) - ); -} - - -Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::kappa -( - const label patchI -) const -{ - return tmp<scalarField> - ( - new scalarField - ( - interpolateXY - ( - T_.boundaryField()[patchI], - TValues_, - kappaValues_ - ) - ) - ); -} - - -Foam::tmp<Foam::scalarField> Foam::interpolatedSolidThermo::sigmaS -( - const label patchI -) const -{ - return tmp<scalarField> - ( - new scalarField - ( - interpolateXY - ( - T_.boundaryField()[patchI], - TValues_, - sigmaSValues_ - ) - ) - ); -} - - bool Foam::interpolatedSolidThermo::read() { return read(dict_); diff --git a/src/thermophysicalModels/basicSolidThermo/interpolatedSolidThermo/interpolatedSolidThermo.H b/src/thermophysicalModels/basicSolidThermo/interpolatedSolidThermo/interpolatedSolidThermo.H index 15899c29a091cfb53e4a51d36e624a504d82b5a4..23e112db5a44159ef8cf65dc8eb99ed4d8fb7086 100644 --- a/src/thermophysicalModels/basicSolidThermo/interpolatedSolidThermo/interpolatedSolidThermo.H +++ b/src/thermophysicalModels/basicSolidThermo/interpolatedSolidThermo/interpolatedSolidThermo.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -60,6 +60,21 @@ private: const dictionary dict_; + // Helper functions + + //- Density [kg/m3] + tmp<scalarField> rho(const label patchI) const; + + //- Scatter coefficient [1/m] + tmp<scalarField> sigmaS(const label) const; + + //- Absorption coefficient [1/m] + tmp<scalarField> kappa(const label) const; + + //- Emissivity [] + tmp<scalarField> emissivity(const label) const; + + public: // Constructors @@ -98,24 +113,12 @@ public: // Per patch calculation - //- Density [kg/m3] - virtual tmp<scalarField> rho(const label patchI) const; - //- Specific heat capacity [J/kg/K)] virtual tmp<scalarField> Cp(const label patchI) const; //- Heat of formation [J/kg] virtual tmp<scalarField> Hf(const label patchI) const; - //- Scatter coefficient [1/m] - virtual tmp<scalarField> sigmaS(const label) const; - - //- Absorption coefficient [1/m] - virtual tmp<scalarField> kappa(const label) const; - - //- Emissivity [] - virtual tmp<scalarField> emissivity(const label) const; - // I-O diff --git a/src/thermophysicalModels/basicSolidThermo/isotropicKSolidThermo/isotropicKSolidThermo.C b/src/thermophysicalModels/basicSolidThermo/isotropicKSolidThermo/isotropicKSolidThermo.C index 7a8b659b88dd5bb784c8ebd9abd090457d21d9d4..1b15c88946923e6523bcb55e875acd813b4fda3e 100644 --- a/src/thermophysicalModels/basicSolidThermo/isotropicKSolidThermo/isotropicKSolidThermo.C +++ b/src/thermophysicalModels/basicSolidThermo/isotropicKSolidThermo/isotropicKSolidThermo.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -100,7 +100,6 @@ Foam::isotropicKSolidThermo::isotropicKSolidThermo(const fvMesh& mesh) void Foam::isotropicKSolidThermo::correct() { - // Correct K K_.internalField() = interpolateXY ( @@ -111,31 +110,30 @@ void Foam::isotropicKSolidThermo::correct() forAll(K_.boundaryField(), patchI) { - K_.boundaryField()[patchI] == this->K(patchI)(); + K_.boundaryField()[patchI] == interpolateXY + ( + T_.boundaryField()[patchI], + TValues_, + KValues_ + ); } interpolatedSolidThermo::calculate(); } +Foam::tmp<Foam::volScalarField> Foam::isotropicKSolidThermo::K() const +{ + return K_; +} + + Foam::tmp<Foam::scalarField> Foam::isotropicKSolidThermo::K ( const label patchI ) const { - - return tmp<scalarField> - ( - new scalarField - ( - interpolateXY - ( - T_.boundaryField()[patchI], - TValues_, - KValues_ - ) - ) - ); + return K_.boundaryField()[patchI]; } @@ -154,6 +152,7 @@ bool Foam::isotropicKSolidThermo::writeData(Ostream& os) const return ok && os.good(); } + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::isotropicKSolidThermo::~isotropicKSolidThermo() diff --git a/src/thermophysicalModels/basicSolidThermo/isotropicKSolidThermo/isotropicKSolidThermo.H b/src/thermophysicalModels/basicSolidThermo/isotropicKSolidThermo/isotropicKSolidThermo.H index 77f84f3ba63e39c4484b4d3f3e974d898d188490..d6acac3e91c1654837ef9e3b3b2052b2ad8e7c24 100644 --- a/src/thermophysicalModels/basicSolidThermo/isotropicKSolidThermo/isotropicKSolidThermo.H +++ b/src/thermophysicalModels/basicSolidThermo/isotropicKSolidThermo/isotropicKSolidThermo.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -87,17 +87,30 @@ public: // Access functions //- Constant access to K - virtual const volScalarField& K() const + virtual tmp<volScalarField> K() const; + + //- Thermal conductivity [W/m/K] + virtual tmp<volSymmTensorField> directionalK() const { - return K_; + notImplemented("directionalKSolidThermo::directionalK() const"); + return tmp<volSymmTensorField>(NULL); } - // Per patch calculation //- Thermal conductivity [W//m/K] virtual tmp<scalarField> K(const label patchI) const; + //- Thermal conductivity [W//m/K] + virtual tmp<symmTensorField> directionalK(const label) const + { + notImplemented + ( + "directionalKSolidThermo::directionalK(const label) const" + ); + return tmp<symmTensorField>(NULL); + } + // I-O diff --git a/src/thermophysicalModels/basicSolidThermo/solidMixtureThermo/solidMixtureThermo/solidMixtureThermo.C b/src/thermophysicalModels/basicSolidThermo/solidMixtureThermo/solidMixtureThermo/solidMixtureThermo.C index 024f6cfcedb8df8391a9742028f9e4cecabbe24d..0f78d32337846755d44d386e49bd5466ab32bde9 100644 --- a/src/thermophysicalModels/basicSolidThermo/solidMixtureThermo/solidMixtureThermo/solidMixtureThermo.C +++ b/src/thermophysicalModels/basicSolidThermo/solidMixtureThermo/solidMixtureThermo/solidMixtureThermo.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -63,6 +63,96 @@ void Foam::solidMixtureThermo<MixtureType>::calculate() } +template<class MixtureType> +Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::rho +( + const label patchI +) const +{ + const scalarField& patchT = T_.boundaryField()[patchI]; + const polyPatch& pp = mesh_.boundaryMesh()[patchI]; + const labelUList& cells = pp.faceCells(); + + tmp<scalarField> tRho(new scalarField(patchT.size())); + scalarField& Rho = tRho(); + + forAll(patchT, celli) + { + Rho[celli] = MixtureType::rho(patchT[celli], cells[celli]); + } + + return tRho; +} + + +template<class MixtureType> +Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::sigmaS +( + const label patchI +) const +{ + const scalarField& patchT = T_.boundaryField()[patchI]; + const polyPatch& pp = mesh_.boundaryMesh()[patchI]; + const labelUList& cells = pp.faceCells(); + + tmp<scalarField> tsigmaS(new scalarField(patchT.size())); + scalarField& sigmaS = tsigmaS(); + + forAll(patchT, celli) + { + sigmaS[celli] = + MixtureType::sigmaS(patchT[celli], cells[celli]); + } + + return tsigmaS; +} + + +template<class MixtureType> +Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::kappa +( + const label patchI +) const +{ + const scalarField& patchT = T_.boundaryField()[patchI]; + const polyPatch& pp = mesh_.boundaryMesh()[patchI]; + const labelUList& cells = pp.faceCells(); + + tmp<scalarField> tKappa(new scalarField(patchT.size())); + scalarField& kappa = tKappa(); + + forAll(patchT, celli) + { + kappa[celli] = + MixtureType::kappa(patchT[celli], cells[celli]); + } + + return tKappa; +} + + +template<class MixtureType> +Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::emissivity +( + const label patchI +) const +{ + const scalarField& patchT = T_.boundaryField()[patchI]; + const polyPatch& pp = mesh_.boundaryMesh()[patchI]; + const labelUList& cells = pp.faceCells(); + + tmp<scalarField> te(new scalarField(patchT.size())); + scalarField& e = te(); + + forAll(patchT, celli) + { + e[celli] = MixtureType::emissivity(patchT[celli], cells[celli]); + } + + return te; +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class MixtureType> @@ -117,6 +207,7 @@ Foam::solidMixtureThermo<MixtureType>::solidMixtureThermo calculate(); } + // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // template<class MixtureType> @@ -134,7 +225,7 @@ void Foam::solidMixtureThermo<MixtureType>::correct() template<class MixtureType> -const Foam::volScalarField& Foam::solidMixtureThermo<MixtureType>::K() const +Foam::tmp<Foam::volScalarField> Foam::solidMixtureThermo<MixtureType>::K() const { return K_; } @@ -261,7 +352,7 @@ Foam::solidMixtureThermo<MixtureType>::Hf() const template<class MixtureType> -Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::rho +Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::K ( const label patchI ) const @@ -270,15 +361,15 @@ Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::rho const polyPatch& pp = mesh_.boundaryMesh()[patchI]; const labelUList& cells = pp.faceCells(); - tmp<scalarField> tRho(new scalarField(patchT.size())); - scalarField& Rho = tRho(); + tmp<scalarField> tK(new scalarField(patchT.size())); + scalarField& K = tK(); forAll(patchT, celli) { - Rho[celli] = MixtureType::rho(patchT[celli], cells[celli]); + K[celli] = MixtureType::K(patchT[celli], cells[celli]); } - return tRho; + return tK; } @@ -326,28 +417,6 @@ Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::hs } -template<class MixtureType> -Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::K -( - const label patchI -) const -{ - const scalarField& patchT = T_.boundaryField()[patchI]; - const polyPatch& pp = mesh_.boundaryMesh()[patchI]; - const labelUList& cells = pp.faceCells(); - - tmp<scalarField> tK(new scalarField(patchT.size())); - scalarField& K = tK(); - - forAll(patchT, celli) - { - K[celli] = MixtureType::K(patchT[celli], cells[celli]); - } - - return tK; -} - - template<class MixtureType> Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::Hf ( @@ -370,74 +439,6 @@ Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::Hf } -template<class MixtureType> -Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::sigmaS -( - const label patchI -) const -{ - const scalarField& patchT = T_.boundaryField()[patchI]; - const polyPatch& pp = mesh_.boundaryMesh()[patchI]; - const labelUList& cells = pp.faceCells(); - - tmp<scalarField> tsigmaS(new scalarField(patchT.size())); - scalarField& sigmaS = tsigmaS(); - - forAll(patchT, celli) - { - sigmaS[celli] = - MixtureType::sigmaS(patchT[celli], cells[celli]); - } - - return tsigmaS; -} - - -template<class MixtureType> -Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::kappa -( - const label patchI -) const -{ - const scalarField& patchT = T_.boundaryField()[patchI]; - const polyPatch& pp = mesh_.boundaryMesh()[patchI]; - const labelUList& cells = pp.faceCells(); - - tmp<scalarField> tKappa(new scalarField(patchT.size())); - scalarField& kappa = tKappa(); - - forAll(patchT, celli) - { - kappa[celli] = - MixtureType::kappa(patchT[celli], cells[celli]); - } - - return tKappa; -} - - -template<class MixtureType> -Foam::tmp<Foam::scalarField> Foam::solidMixtureThermo<MixtureType>::emissivity -( - const label patchI -) const -{ - const scalarField& patchT = T_.boundaryField()[patchI]; - const polyPatch& pp = mesh_.boundaryMesh()[patchI]; - const labelUList& cells = pp.faceCells(); - - tmp<scalarField> te(new scalarField(patchT.size())); - scalarField& e = te(); - - forAll(patchT, celli) - { - e[celli] = MixtureType::emissivity(patchT[celli], cells[celli]); - } - - return te; -} - - template<class MixtureType> bool Foam::solidMixtureThermo<MixtureType>::read() { diff --git a/src/thermophysicalModels/basicSolidThermo/solidMixtureThermo/solidMixtureThermo/solidMixtureThermo.H b/src/thermophysicalModels/basicSolidThermo/solidMixtureThermo/solidMixtureThermo/solidMixtureThermo.H index 1e77c79a6b4a4c2894d18ec3063b8db682719ffd..100d371b99a8d9bd5c3c87c8196d6081a98472ae 100644 --- a/src/thermophysicalModels/basicSolidThermo/solidMixtureThermo/solidMixtureThermo/solidMixtureThermo.H +++ b/src/thermophysicalModels/basicSolidThermo/solidMixtureThermo/solidMixtureThermo/solidMixtureThermo.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation + \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -68,6 +68,16 @@ private: void calculate(); + // Per patch helpers to get mixture properties on a patch + + tmp<scalarField> rho(const label patchI) const; + + tmp<scalarField> sigmaS(const label patchI) const; + + tmp<scalarField> kappa(const label patchI) const; + + tmp<scalarField> emissivity(const label patchI) const; + public: //- Runtime type information @@ -89,6 +99,9 @@ public: // Member functions + //- Update properties + virtual void correct(); + //- Return the compostion of the solid mixture virtual MixtureType& composition() { @@ -101,32 +114,44 @@ public: return *this; } - //- Update properties - virtual void correct(); - // Access functions + // Derived thermal properties //- Thermal conductivity [W/m/K] - virtual const volScalarField& K() const; + virtual tmp<volScalarField> K() const; + //- Thermal conductivity [W/m/K] + virtual tmp<volSymmTensorField> directionalK() const + { + notImplemented("solidMixtureThermo::directionalK() const"); + return tmp<volSymmTensorField>(NULL); + } - // Derived properties + //- Specific heat capacity [J/(kg.K)] + virtual tmp<volScalarField> Cp() const; - //- Specific heat capacity [J/(kg.K)] - virtual tmp<volScalarField> Cp() const; + //- Sensible enthalpy [J/(kg.K)] + virtual tmp<volScalarField> hs() const; - //- Heat of formation [J/kg] - virtual tmp<volScalarField> Hf() const; + //- Heat of formation [J/kg] + virtual tmp<volScalarField> Hf() const; - //- Sensible enthalpy [J/(kg.K)] - virtual tmp<volScalarField> hs() const; + // Per patch calculation - // Patches variables + //- Thermal conductivity [W/(m.K)] + virtual tmp<scalarField> K(const label patchI) const; + //- Thermal conductivity [W/(m.K)] + virtual tmp<symmTensorField> directionalK(const label) const + { + notImplemented + ( + "solidMixtureThermo::directionalK(const label) const" + ); + return tmp<symmTensorField>(NULL); + } - //- Density [kg/m3] - virtual tmp<scalarField> rho(const label patchI) const; //- Specific heat capacity [J/(kg.K)] virtual tmp<scalarField> Cp(const label patchI) const; @@ -134,21 +159,9 @@ public: //- Sensible enthalpy [J/(kg.K)] virtual tmp<scalarField> hs(const label patchI) const; - //- Thermal conductivity [W/(m.K)] - virtual tmp<scalarField> K(const label patchI) const; - //- Heat of formation [J/kg] virtual tmp<scalarField> Hf(const label patchI) const; - //- Scatter coefficient [1/m] - virtual tmp<scalarField> sigmaS(const label patchI) const; - - //- Absorptivity [1/m] - virtual tmp<scalarField> kappa(const label patchI) const; - - //- Emissivity [] - virtual tmp<scalarField> emissivity(const label patchI) const; - //- Read thermophysicalProperties dictionary virtual bool read(); diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionLiquidHeater/Allrun b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionLiquidHeater/Allrun index 6e1c645ec0268f71fc520897dba3ad8cab0876b2..762810a181ef3c95bb62f1e7f85afc67ab37ab8b 100755 --- a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionLiquidHeater/Allrun +++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionLiquidHeater/Allrun @@ -42,7 +42,7 @@ runParallel `getApplication` 4 # Reconstruct for i in bottomWater topAir heater leftSolid rightSolid do - reconstructPar -region $i > log.reconstructPar.$i2 >&1 + reconstructPar -region $i > log.reconstructPar.$i 2>&1 done diff --git a/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionLiquidHeater/README.txt b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionLiquidHeater/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..8462b44418512ac3e5ff8ebd26a3429502f7b9aa --- /dev/null +++ b/tutorials/heatTransfer/chtMultiRegionFoam/multiRegionLiquidHeater/README.txt @@ -0,0 +1,16 @@ +To run with directional thermo: + +- compile chtMultiRegionFoam/solid/setRegionSolidFields.H with + + tmp<volSymmTensorField> tkappa = thermo.directionalK(); + const volSymmTensorField& kappa = tkappa(); + +- change in e.g. heater: + + - in constant/heater/solidThermophysicalProperties: + + thermoType directionalKSolidThermo; + + - in 0/heater/T: + + K directionalSolidThermo;