diff --git a/Plugin/CMakeLists.txt b/Plugin/CMakeLists.txt index 1f1c4b4fa472f14a1db70b9dbf4c299cb08c7f5c..76679dc7267b5a33d365dd4d025db18e52ff2268 100644 --- a/Plugin/CMakeLists.txt +++ b/Plugin/CMakeLists.txt @@ -23,7 +23,7 @@ set(SRC Probe.cpp MinMax.cpp HarmonicToTime.cpp ModulusPhase.cpp HomologyComputation.cpp - Distance.cpp ExtractEdges.cpp + Distance.cpp ExtractEdges.cpp NearestNeighbor.cpp AnalyseCurvedMesh.cpp ) diff --git a/Plugin/NearestNeighbor.cpp b/Plugin/NearestNeighbor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..78df0fff857841565405bc73f58d7ee398c0c8e2 --- /dev/null +++ b/Plugin/NearestNeighbor.cpp @@ -0,0 +1,97 @@ +// Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to <gmsh@geuz.org>. + +#include "GmshConfig.h" +#include "NearestNeighbor.h" + +#if defined(HAVE_ANN) +#include "ANN/ANN.h" +#endif + +StringXNumber NearestNeighborOptions_Number[] = { + {GMSH_FULLRC, "View", NULL, -1.}, +}; + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterNearestNeighborPlugin() + { + return new GMSH_NearestNeighborPlugin(); + } +} + +std::string GMSH_NearestNeighborPlugin::getHelp() const +{ + return "Plugin(NearestNeighbor) computes the distance from each " + "point in `View' to its nearest neighbor.\n\n" + "If `View' < 0, the plugin is run on the current view.\n\n" + "Plugin(NearestNeighbor) is executed in-place."; +} + +int GMSH_NearestNeighborPlugin::getNbOptions() const +{ + return sizeof(NearestNeighborOptions_Number) / sizeof(StringXNumber); +} + +StringXNumber *GMSH_NearestNeighborPlugin::getOption(int iopt) +{ + return &NearestNeighborOptions_Number[iopt]; +} + +PView *GMSH_NearestNeighborPlugin::execute(PView *v) +{ + int iView = (int)NearestNeighborOptions_Number[0].def; + + PView *v1 = getView(iView, v); + if(!v1) return v; + PViewData *data1 = v1->getData(); + + int totpoints = data1->getNumPoints(); + if(!totpoints){ + Msg::Error("View[%d] contains no points", v1->getNum()); + return 0; + } + +#if defined(HAVE_ANN) + ANNpointArray zeronodes = annAllocPts(totpoints, 4); + int k = 0, step = 0; + for(int ent = 0; ent < data1->getNumEntities(step); ent++){ + for(int ele = 0; ele < data1->getNumElements(step, ent); ele++){ + if(data1->skipElement(step, ent, ele)) continue; + int numNodes = data1->getNumNodes(step, ent, ele); + if(numNodes != 1) continue; + data1->getNode(step, ent, ele, 0, zeronodes[k][0], zeronodes[k][1], + zeronodes[k][2]); + k++; + } + } + ANNkd_tree *kdtree = new ANNkd_tree(zeronodes, totpoints, 3); + ANNidxArray index = new ANNidx[2]; + ANNdistArray dist = new ANNdist[2]; + + v1->setChanged(true); + for(int ent = 0; ent < data1->getNumEntities(step); ent++){ + for(int ele = 0; ele < data1->getNumElements(step, ent); ele++){ + if(data1->skipElement(step, ent, ele)) continue; + int numNodes = data1->getNumNodes(step, ent, ele); + if(numNodes != 1) continue; + double xyz[3]; + data1->getNode(step, ent, ele, 0, xyz[0], xyz[1], xyz[2]); + kdtree->annkSearch(xyz, 2, index, dist); + data1->setValue(step, ent, ele, 0, 0, sqrt(dist[1])); + } + } + + delete kdtree; + annDeallocPts(zeronodes); + delete [] index; + delete [] dist; +#endif + + data1->setName(v1->getData()->getName() + "_NearestNeighbor"); + data1->finalize(); + + return v1; +} diff --git a/Plugin/NearestNeighbor.h b/Plugin/NearestNeighbor.h new file mode 100644 index 0000000000000000000000000000000000000000..de6f5623bb9029a3883e55bae51599d489bd99b4 --- /dev/null +++ b/Plugin/NearestNeighbor.h @@ -0,0 +1,31 @@ +// Gmsh - Copyright (C) 1997-2010 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to <gmsh@geuz.org>. + +#ifndef _NEAREST_NEIGHBOR_H_ +#define _NEAREST_NEIGHBOR_H_ + +#include "Plugin.h" + +extern "C" +{ + GMSH_Plugin *GMSH_RegisterNearestNeighborPlugin(); +} + +class GMSH_NearestNeighborPlugin : public GMSH_PostPlugin +{ + public: + GMSH_NearestNeighborPlugin(){} + std::string getName() const { return "NearestNeighbor"; } + std::string getShortHelp() const + { + return "Compute distance to the nearest neighbor"; + } + std::string getHelp() const; + int getNbOptions() const; + StringXNumber *getOption(int iopt); + PView *execute(PView *); +}; + +#endif diff --git a/Plugin/PluginManager.cpp b/Plugin/PluginManager.cpp index d567ac00739e1c25741d53ef3b6111311ae5f9b9..8e221fe2748806f3e5ad357b07de917000b9b52b 100644 --- a/Plugin/PluginManager.cpp +++ b/Plugin/PluginManager.cpp @@ -30,6 +30,7 @@ #include "Divergence.h" #include "Annotate.h" #include "Distance.h" +#include "NearestNeighbor.h" #include "Remove.h" #include "MakeSimplex.h" #include "Smooth.h" @@ -46,7 +47,6 @@ #include "Probe.h" #include "GSHHS.h" #include "HomologyComputation.h" -#include "Distance.h" #include "ExtractEdges.h" // for testing purposes only :-) @@ -165,7 +165,7 @@ void PluginManager::registerDefaultPlugins() ("Skin", GMSH_RegisterSkinPlugin())); allPlugins.insert(std::pair<std::string, GMSH_Plugin*> ("MathEval", GMSH_RegisterMathEvalPlugin())); - allPlugins.insert(std::pair<std::string, GMSH_Plugin*> + allPlugins.insert(std::pair<std::string, GMSH_Plugin*> ("AnalyseCurvedMesh", GMSH_RegisterAnalyseCurvedMeshPlugin())); allPlugins.insert(std::pair<std::string, GMSH_Plugin*> ("ModifyComponent", GMSH_RegisterModifyComponentPlugin())); @@ -199,8 +199,6 @@ void PluginManager::registerDefaultPlugins() ("Curl", GMSH_RegisterCurlPlugin())); allPlugins.insert(std::pair<std::string, GMSH_Plugin*> ("Divergence", GMSH_RegisterDivergencePlugin())); - allPlugins.insert(std::pair<std::string, GMSH_Plugin*> - ("Distance", GMSH_RegisterDistancePlugin())); allPlugins.insert(std::pair<std::string, GMSH_Plugin*> ("Annotate", GMSH_RegisterAnnotatePlugin())); allPlugins.insert(std::pair<std::string, GMSH_Plugin*> @@ -230,6 +228,10 @@ void PluginManager::registerDefaultPlugins() #if defined(HAVE_SOLVER) allPlugins.insert(std::pair<std::string, GMSH_Plugin*> ("Distance", GMSH_RegisterDistancePlugin())); +#endif +#if defined(HAVE_ANN) + allPlugins.insert(std::pair<std::string, GMSH_Plugin*> + ("NearestNeighbor", GMSH_RegisterNearestNeighborPlugin())); #endif }