From c4d326325697b2fd9a4269cd120f4014a8765e62 Mon Sep 17 00:00:00 2001 From: Francois Henrotte <francois.henrotte@ulg.ac.be> Date: Mon, 18 Feb 2013 14:14:20 +0000 Subject: [PATCH] cross fields --- Mesh/cross3D.h | 11 +++ Mesh/directions3D.cpp | 215 ++++++++++++++++-------------------------- Mesh/directions3D.h | 43 +++------ Mesh/simple3D.cpp | 1 + Mesh/yamakawa.h | 6 ++ 5 files changed, 112 insertions(+), 164 deletions(-) diff --git a/Mesh/cross3D.h b/Mesh/cross3D.h index d1ebcc59af..8c4a3553ae 100644 --- a/Mesh/cross3D.h +++ b/Mesh/cross3D.h @@ -1,3 +1,13 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. +// +// Contributor(s): +// François Henrotte + +#ifndef _CROSS_3D_H_ +#define _CROSS_3D_H_ #include "stat_cwmtx.h" #include "stat_quatern.h" @@ -196,3 +206,4 @@ Matrix convert(const cross3D x){ +#endif diff --git a/Mesh/directions3D.cpp b/Mesh/directions3D.cpp index d15e6f2b86..78c7cdd7cf 100644 --- a/Mesh/directions3D.cpp +++ b/Mesh/directions3D.cpp @@ -6,12 +6,12 @@ // Contributor(s): // Tristan Carrier -#include "directions3D.h" +#include <fstream> #include "GModel.h" #include "BackgroundMesh.h" #include "meshGFaceDelaunayInsertion.h" -#include <fstream> #include "MTetrahedron.h" +#include "directions3D.h" #if defined(HAVE_PETSC) #include "dofManager.h" @@ -20,94 +20,6 @@ #include "linearSystemFull.h" #endif -/****************class Matrix****************/ - -Matrix::Matrix(){ - m11 = 1.0; - m21 = 0.0; - m31 = 0.0; - m12 = 0.0; - m22 = 1.0; - m32 = 0.0; - m13 = 0.0; - m23 = 0.0; - m33 = 1.0; -} - -Matrix::~Matrix(){} - -void Matrix::set_m11(double new_m11){ - m11 = new_m11; -} - -void Matrix::set_m21(double new_m21){ - m21 = new_m21; -} - -void Matrix::set_m31(double new_m31){ - m31 = new_m31; -} - -void Matrix::set_m12(double new_m12){ - m12 = new_m12; -} - -void Matrix::set_m22(double new_m22){ - m22 = new_m22; -} - -void Matrix::set_m32(double new_m32){ - m32 = new_m32; -} - -void Matrix::set_m13(double new_m13){ - m13 = new_m13; -} - -void Matrix::set_m23(double new_m23){ - m23 = new_m23; -} - -void Matrix::set_m33(double new_m33){ - m33 = new_m33; -} - -double Matrix::get_m11(){ - return m11; -} - -double Matrix::get_m21(){ - return m21; -} - -double Matrix::get_m31(){ - return m31; -} - -double Matrix::get_m12(){ - return m12; -} - -double Matrix::get_m22(){ - return m22; -} - -double Matrix::get_m32(){ - return m32; -} - -double Matrix::get_m13(){ - return m13; -} - -double Matrix::get_m23(){ - return m23; -} - -double Matrix::get_m33(){ - return m33; -} - /****************class Frame_field****************/ Frame_field::Frame_field(){} @@ -285,7 +197,6 @@ Matrix Frame_field::search(double x,double y,double z){ delete[] indices; delete[] distances; #endif - return field[index].second; } @@ -359,11 +270,11 @@ double Frame_field::get_ratio(GFace* gf,SPoint2 point){ return val; } -void Frame_field::print_segment(SPoint3 p1,SPoint3 p2,std::ofstream& file){ +void Frame_field::print_segment(SPoint3 p1,SPoint3 p2,double val1, double val2, std::ofstream& file){ file << "SL (" << p1.x() << ", " << p1.y() << ", " << p1.z() << ", " << p2.x() << ", " << p2.y() << ", " << p2.z() << ")" - << "{" << p1.z() << "," << p1.z() << "};\n"; + << "{" << val1 << "," << val2 << "};\n"; } void Frame_field::print_field1(){ @@ -403,12 +314,13 @@ void Frame_field::print_field1(){ p6 = SPoint3(vertex->x() - k*m.get_m13(), vertex->y() - k*m.get_m23(), vertex->z() - k*m.get_m33()); - print_segment(p,p1,file); - print_segment(p,p2,file); - print_segment(p,p3,file); - print_segment(p,p4,file); - print_segment(p,p5,file); - print_segment(p,p6,file); + double val1=10, val2=20; + print_segment(p,p1,val1,val2,file); + print_segment(p,p2,val1,val2,file); + print_segment(p,p3,val1,val2,file); + print_segment(p,p4,val1,val2,file); + print_segment(p,p5,val1,val2,file); + print_segment(p,p6,val1,val2,file); } file << "};\n"; } @@ -434,8 +346,6 @@ void Frame_field::print_field2(GRegion* gr){ vertex = element->getVertex(j); if(vertex->onWhat()->dim()>2){ m = search(vertex->x(),vertex->y(),vertex->z()); - //m = combine(vertex->x(),vertex->y(),vertex->z()); - p = SPoint3(vertex->x(),vertex->y(),vertex->z()); p1 = SPoint3(vertex->x() + k*m.get_m11(), vertex->y() + k*m.get_m21(), @@ -455,12 +365,13 @@ void Frame_field::print_field2(GRegion* gr){ p6 = SPoint3(vertex->x() - k*m.get_m13(), vertex->y() - k*m.get_m23(), vertex->z() - k*m.get_m33()); - print_segment(p,p1,file); - print_segment(p,p2,file); - print_segment(p,p3,file); - print_segment(p,p4,file); - print_segment(p,p5,file); - print_segment(p,p6,file); + double val1=10, val2=20; + print_segment(p,p1,val1,val2,file); + print_segment(p,p2,val1,val2,file); + print_segment(p,p3,val1,val2,file); + print_segment(p,p4,val1,val2,file); + print_segment(p,p5,val1,val2,file); + print_segment(p,p6,val1,val2,file); } } } @@ -470,9 +381,7 @@ void Frame_field::print_field2(GRegion* gr){ GRegion* Frame_field::test(){ GRegion* gr; GModel* model = GModel::current(); - gr = *(model->firstRegion()); - return gr; } @@ -480,15 +389,13 @@ void Frame_field::clear(){ Nearest_point::clear(); temp.clear(); field.clear(); - #if defined(HAVE_ANN) +#if defined(HAVE_ANN) delete duplicate; delete kd_tree; annClose(); - #endif +#endif } - -#include "yamakawa.h" #include "cross3D.h" CWTSSpaceVector<> convert(const SVector3 v){ @@ -504,27 +411,21 @@ ostream& operator<< (ostream &os, SVector3 &v) { return os; } -void Frame_field::init(GRegion* gr){ - // - MVertex* pVertex; - Matrix m; +void Frame_field::init(GRegion* gr){ CWTSSpaceVector<> Ex(1,0,0), Ey(0,1,0), Ez(0,0,1); - cross3D x(Ez, Ex); CWTSSpaceVector<> v(1,2,0), w(0,1,1.3); + cross3D x(Ez, Ex); cross3D y = cross3D(v, w); - Recombinator crossData; + //Recombinator crossData; crossData.build_vertex_to_vertices(gr); for(std::map<MVertex*, std::set<MVertex*> >::const_iterator iter = crossData.vertex_to_vertices.begin(); iter != crossData.vertex_to_vertices.end(); ++iter){ - pVertex = iter->first; - m = search(pVertex->x(), pVertex->y(), pVertex->z()); + MVertex* pVertex = iter->first; + Matrix m = search(pVertex->x(), pVertex->y(), pVertex->z()); // if(pVertex->onWhat()->dim() <= 2) - // m = search(pVertex->x(), pVertex->y(), pVertex->z()); - // else - // m = convert(y); crossField[pVertex->getNum()] = m; } } @@ -593,8 +494,8 @@ double Frame_field::smooth(GRegion* gr){ Matrix m, m0; double enew, eold; - Recombinator crossData; - crossData.build_vertex_to_vertices(gr); + // Recombinator crossData; + // crossData.build_vertex_to_vertices(gr); //std::cout << "NbVert= " << crossData.vertex_to_vertices.size() << std::endl ; double energy = 0; @@ -632,8 +533,8 @@ void Frame_field::save(GRegion* gr, const std::string& filename){ MVertex* pVertex; std::map<MVertex*,Matrix>::iterator it; Matrix m; - Recombinator crossData; - crossData.build_vertex_to_vertices(gr); + // Recombinator crossData; + // crossData.build_vertex_to_vertices(gr); double k = 0.04; std::ofstream file(filename.c_str()); @@ -652,32 +553,71 @@ void Frame_field::save(GRegion* gr, const std::string& filename){ p1 = SPoint3(pVertex->x() + k*m.get_m11(), pVertex->y() + k*m.get_m21(), pVertex->z() + k*m.get_m31()); - print_segment(p,p1,file); + print_segment(p,p1,pVertex->z(),pVertex->z(),file); p1 = SPoint3(pVertex->x() - k*m.get_m11(), pVertex->y() - k*m.get_m21(), pVertex->z() - k*m.get_m31()); - print_segment(p,p1,file); + print_segment(p,p1,pVertex->z(),pVertex->z(),file); p1 = SPoint3(pVertex->x() + k*m.get_m12(), pVertex->y() + k*m.get_m22(), pVertex->z() + k*m.get_m32()); - print_segment(p,p1,file); + print_segment(p,p1,pVertex->z(),pVertex->z(),file); p1 = SPoint3(pVertex->x() - k*m.get_m12(), pVertex->y() - k*m.get_m22(), pVertex->z() - k*m.get_m32()); - print_segment(p,p1,file); + print_segment(p,p1,pVertex->z(),pVertex->z(),file); p1 = SPoint3(pVertex->x() + k*m.get_m13(), pVertex->y() + k*m.get_m23(), pVertex->z() + k*m.get_m33()); - print_segment(p,p1,file); + print_segment(p,p1,pVertex->z(),pVertex->z(),file); p1 = SPoint3(pVertex->x() - k*m.get_m13(), pVertex->y() - k*m.get_m23(), pVertex->z() - k*m.get_m33()); - print_segment(p,p1,file); + print_segment(p,p1,pVertex->z(),pVertex->z(),file); } file << "};\n"; file.close(); } +void Frame_field::fillTreeVolume(GRegion* gr){ +#if defined(HAVE_ANN) + int n = crossData.vertex_to_vertices.size(); + std::cout << "Fillin ANN tree with " << n << " vertices" << std::endl; + annTreeData = annAllocPts(n,3); + int index=0; + for(std::map<MVertex*, std::set<MVertex*> >::iterator iter = crossData.vertex_to_vertices.begin(); + iter != crossData.vertex_to_vertices.end(); ++iter){ + MVertex* pVertex = iter->first; + annTreeData[index][0] = pVertex->x(); + annTreeData[index][1] = pVertex->y(); + annTreeData[index][2] = pVertex->z(); + vertIndices[index++] = pVertex->getNum(); + } + annTree = new ANNkd_tree(annTreeData,n,3); +#endif +} + +Matrix Frame_field::findNearestCross(double x,double y,double z){ +#if defined(HAVE_ANN) + ANNpoint query = annAllocPt(3); + ANNidxArray indices = new ANNidx[1]; + ANNdistArray distances = new ANNdist[1]; + query[0] = x; + query[1] = y; + query[2] = z; + double e = 0.0; + annTree->annkSearch(query,1,indices,distances,e); + annDeallocPt(query); + delete[] indices; + delete[] distances; + std::map<int, Matrix>::const_iterator it = crossField.find(vertIndices[indices[0]]); + //annTreeData[indices[0]] gives the coordinates + return it->second; +#else + return Matrix(); +#endif +} + void Frame_field::save_dist(const std::string& filename){ std::ofstream file(filename.c_str()); file << "View \"Distance\" {\n"; @@ -1291,7 +1231,8 @@ void Nearest_point::print_field(GRegion* gr){ z = vertex->z(); val = search(x,y,z,vec); if(val){ - print_segment(SPoint3(x+k*vec.x(),y+k*vec.y(),z+k*vec.z()),SPoint3(x-k*vec.x(),y-k*vec.y(),z-k*vec.z()),file); + print_segment(SPoint3(x+k*vec.x(),y+k*vec.y(),z+k*vec.z()), + SPoint3(x-k*vec.x(),y-k*vec.y(),z-k*vec.z()),file); } } } @@ -1331,10 +1272,14 @@ std::map<MVertex*,Matrix> Frame_field::temp; std::vector<std::pair<MVertex*,Matrix> > Frame_field::field; std::map<int, Matrix> Frame_field::crossField; std::map<MEdge, double, Less_Edge> Frame_field::crossDist; +Recombinator Frame_field::crossData; #if defined(HAVE_ANN) ANNpointArray Frame_field::duplicate; ANNkd_tree* Frame_field::kd_tree; +ANNpointArray Frame_field::annTreeData; +ANNkd_tree* Frame_field::annTree; +std::vector<int> Frame_field::vertIndices; #endif std::map<MVertex*,double> Size_field::boundary; diff --git a/Mesh/directions3D.h b/Mesh/directions3D.h index 87af72dce4..0f7a39ceca 100644 --- a/Mesh/directions3D.h +++ b/Mesh/directions3D.h @@ -6,39 +6,17 @@ // Contributor(s): // Tristan Carrier +#ifndef _DIRECTION_3D_H_ +#define _DIRECTION_3D_H_ + #include "GFace.h" #include "MEdge.h" #include "MElementOctree.h" #if defined(HAVE_ANN) #include <ANN/ANN.h> #endif - -class Matrix{ - private: - double m11,m21,m31,m12,m22,m32,m13,m23,m33; - public: - Matrix(); - ~Matrix(); - void set_m11(double); - void set_m21(double); - void set_m31(double); - void set_m12(double); - void set_m22(double); - void set_m32(double); - void set_m13(double); - void set_m23(double); - void set_m33(double); - double get_m11(); - double get_m21(); - double get_m31(); - double get_m12(); - double get_m22(); - double get_m32(); - double get_m13(); - double get_m23(); - double get_m33(); -}; - +#include "yamakawa.h" +#include "Matrix.h" struct lowerThan { bool operator() (const std::pair<int, Matrix>& lhs, const std::pair<int, Matrix>& rhs) const @@ -49,12 +27,15 @@ class Frame_field{ private: static std::map<MVertex*, Matrix> temp; static std::vector<std::pair<MVertex*, Matrix> > field; - //static std::set<std::pair<int, Matrix>, lowerThan> crossField; static std::map<int, Matrix> crossField; + //static std::map<MVertex*, Matrix, MVertexLessThanNum> crossField; static std::map<MEdge, double, Less_Edge> crossDist; #if defined(HAVE_ANN) static ANNpointArray duplicate; static ANNkd_tree* kd_tree; + static ANNpointArray annTreeData; + static ANNkd_tree* annTree; + static std::vector<int> vertIndices; #endif Frame_field(); public: @@ -67,10 +48,13 @@ class Frame_field{ static double get_ratio(GFace*,SPoint2); static void print_field1(); static void print_field2(GRegion*); - static void print_segment(SPoint3,SPoint3,std::ofstream&); + static void print_segment(SPoint3,SPoint3,double,double,std::ofstream&); + static Recombinator crossData; static void init(GRegion* gr); static double smooth(GRegion* gr); static double findBarycenter(std::map<MVertex*, std::set<MVertex*> >::const_iterator iter, Matrix &m0); + static void fillTreeVolume(GRegion* gr); + static Matrix findNearestCross(double x,double y,double z); static void save(GRegion* gr, const std::string &filename); static void save_energy(GRegion* gr, const std::string& filename); static void save_dist(const std::string& filename); @@ -114,3 +98,4 @@ class Nearest_point{ static void clear(); }; +#endif diff --git a/Mesh/simple3D.cpp b/Mesh/simple3D.cpp index 485c2c3ea6..25390cba6d 100644 --- a/Mesh/simple3D.cpp +++ b/Mesh/simple3D.cpp @@ -347,6 +347,7 @@ void Filler::treat_region(GRegion* gr){ RTree<Node*,double,3,double> rtree; Frame_field::init_region(gr); + std::cout << "Smoothing: energy = " << Frame_field::smooth(gr) << std::endl; Size_field::init_region(gr); Size_field::solve(gr); octree = new MElementOctree(gr->model()); diff --git a/Mesh/yamakawa.h b/Mesh/yamakawa.h index 5d609616b6..541fa26529 100755 --- a/Mesh/yamakawa.h +++ b/Mesh/yamakawa.h @@ -6,6 +6,10 @@ // Contributor(s): // Tristan Carrier +#ifndef _YAMAKAWA_H_ +#define _YAMAKAWA_H_ + + #include "GRegion.h" #include <set> @@ -316,3 +320,5 @@ class PostOp{ void build_vertex_to_pyramids(MElement*); void erase_vertex_to_pyramids(MElement*); }; + +#endif -- GitLab