From 13ea7fc73a49dd69696084b8232a7c5456fe232f Mon Sep 17 00:00:00 2001 From: laurence Date: Thu, 21 Mar 2013 10:36:27 +0000 Subject: [PATCH] ENH: Add new curvature calculation to surfaceFeatureExtract --- .../surfaceFeatureExtract.C | 485 +++++++++++++----- 1 file changed, 363 insertions(+), 122 deletions(-) diff --git a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C index f18bdda053..ef2d7f1426 100644 --- a/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C +++ b/applications/utilities/surface/surfaceFeatureExtract/surfaceFeatureExtract.C @@ -28,6 +28,11 @@ Description Extracts and writes surface features to file. All but the basic feature extraction is WIP. + Curvature calculation is an implementation of the algorithm from: + + "Estimating Curvatures and their Derivatives on Triangle Meshes" + by S. Rusinkiewicz + \*---------------------------------------------------------------------------*/ #include "argList.H" @@ -46,129 +51,383 @@ Description #include "treeDataEdge.H" #include "unitConversion.H" #include "plane.H" - -#ifdef ENABLE_CURVATURE -#include "buildCGALPolyhedron.H" -#include "CGALPolyhedronRings.H" -#include -#include -#include -#endif +#include "tensor2D.H" +#include "symmTensor2D.H" +#include "point.H" +#include "triadField.H" +#include "transform.H" using namespace Foam; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -#ifdef ENABLE_CURVATURE -scalarField calcCurvature(const triSurface& surf) +scalar calcVertexNormalWeight +( + const triFace& f, + const label pI, + const vector& fN, + const pointField& points +) { - scalarField k(surf.points().size(), 0); + label index = findIndex(f, pI); - Polyhedron P; - - buildCGALPolyhedron convert(surf); - P.delegate(convert); - - // Info<< "Created CGAL Polyhedron with " << label(P.size_of_vertices()) - // << " vertices and " << label(P.size_of_facets()) - // << " facets. " << endl; - - // The rest of this function adapted from - // CGAL-3.7/examples/Jet_fitting_3/Mesh_estimation.cpp - - //Vertex property map, with std::map - typedef std::map Vertex2int_map_type; - typedef boost::associative_property_map< Vertex2int_map_type > - Vertex_PM_type; - typedef T_PolyhedralSurf_rings Poly_rings; - - typedef CGAL::Monge_via_jet_fitting Monge_via_jet_fitting; - typedef Monge_via_jet_fitting::Monge_form Monge_form; - - std::vector in_points; //container for data points - - // default parameter values and global variables - unsigned int d_fitting = 2; - unsigned int d_monge = 2; - unsigned int min_nb_points = (d_fitting + 1)*(d_fitting + 2)/2; - - //initialize the tag of all vertices to -1 - Vertex_iterator vitb = P.vertices_begin(); - Vertex_iterator vite = P.vertices_end(); - - Vertex2int_map_type vertex2props; - Vertex_PM_type vpm(vertex2props); - - CGAL_For_all(vitb, vite) + if (index == -1) { - put(vpm, &(*vitb), -1); + FatalErrorIn("calcVertexNormals()") + << "Point not in face" << abort(FatalError); } - vite = P.vertices_end(); + const vector e1 = points[f[index]] - points[f[f.fcIndex(index)]]; + const vector e2 = points[f[index]] - points[f[f.rcIndex(index)]]; - label vertI = 0; + return mag(fN)/(magSqr(e1)*magSqr(e2) + VSMALL); +} - for (vitb = P.vertices_begin(); vitb != vite; vitb++) + +point randomPointInPlane(const plane& p) +{ + // Perturb base point + const point& refPt = p.refPoint(); + + // ax + by + cz + d = 0 + const FixedList& planeCoeffs = p.planeCoeffs(); + + const scalar perturbX = refPt.x() + 1e-3; + const scalar perturbY = refPt.y() + 1e-3; + const scalar perturbZ = refPt.z() + 1e-3; + + if (mag(planeCoeffs[2]) < SMALL) { - //initialize - Vertex* v = &(*vitb); - - //gather points around the vertex using rings - // From: gather_fitting_points(v, in_points, vpm); + if (mag(planeCoeffs[1]) < SMALL) { - std::vector gathered; - in_points.clear(); + const scalar x = + -1.0 + *( + planeCoeffs[3] + + planeCoeffs[1]*perturbY + + planeCoeffs[2]*perturbZ + )/planeCoeffs[0]; - Poly_rings::collect_enough_rings(v, min_nb_points, gathered, vpm); - - //store the gathered points - std::vector::iterator itb = gathered.begin(); - std::vector::iterator ite = gathered.end(); - - CGAL_For_all(itb, ite) - { - in_points.push_back((*itb)->point()); - } + return point + ( + x, + perturbY, + perturbZ + ); } - //skip if the nb of points is to small - if ( in_points.size() < min_nb_points ) - { - std::cerr - << "not enough pts for fitting this vertex" - << in_points.size() - << std::endl; + const scalar y = + -1.0 + *( + planeCoeffs[3] + + planeCoeffs[0]*perturbX + + planeCoeffs[2]*perturbZ + )/planeCoeffs[1]; + return point + ( + perturbX, + y, + perturbZ + ); + } + else + { + const scalar z = + -1.0 + *( + planeCoeffs[3] + + planeCoeffs[0]*perturbX + + planeCoeffs[1]*perturbY + )/planeCoeffs[2]; + + return point + ( + perturbX, + perturbY, + z + ); + } +} + + +triadField calcVertexCoordSys +( + const triSurface& surf, + const vectorField& pointNormals +) +{ + const pointField& points = surf.points(); + const Map