X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FINTERP_KERNEL%2FPlanarIntersector.txx;h=f5a9ae7298aa01722bdae885b7c7f12f2e123afe;hb=b219559763498c4bd10c730cd3d2c62b1eed45db;hp=df6593a0192990e70ce58f8845e188220dfddd71;hpb=48782c06022ca2caa36f849cb5a29ea4fe2aaa83;p=tools%2Fmedcoupling.git diff --git a/src/INTERP_KERNEL/PlanarIntersector.txx b/src/INTERP_KERNEL/PlanarIntersector.txx index df6593a01..f5a9ae729 100644 --- a/src/INTERP_KERNEL/PlanarIntersector.txx +++ b/src/INTERP_KERNEL/PlanarIntersector.txx @@ -1,21 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. // -// This library 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 -// Lesser General Public License for more details. +// This library 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 +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// Author : Anthony Geay (CEA/DEN) #ifndef __PLANARINTERSECTOR_TXX__ #define __PLANARINTERSECTOR_TXX__ @@ -29,9 +30,9 @@ namespace INTERP_KERNEL { template - PlanarIntersector::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double medianPlane, bool doRotate, int orientation, int printLevel): + PlanarIntersector::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): _meshT(meshT),_meshS(meshS), - _dim_caracteristic(dimCaracteristic),_precision(precision),_median_plane(medianPlane), + _dim_caracteristic(dimCaracteristic),_max_distance_3Dsurf_intersect(md3DSurf),_min_dot_btw_3Dsurf_intersect(minDot3DSurf),_precision(precision),_median_plane(medianPlane), _do_rotate(doRotate),_orientation(orientation),_print_level(printLevel) { _connectT=meshT.getConnectivityPtr(); @@ -69,7 +70,7 @@ namespace INTERP_KERNEL int ibox=0; for(long icell=0; icell::max(); } //updating the bounding box with each node of the element - for (int j=0; j::coo2C(conn[OTT::conn2C(conn_index[icell]+j)]); for(int idim=0; idim void PlanarIntersector::getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes) @@ -127,12 +128,12 @@ namespace INTERP_KERNEL \param bbox vector containing the bounding boxes */ template - void PlanarIntersector::adjustBoundingBoxes(std::vector& bbox, double Surf3DAdjustmentEps) + void PlanarIntersector::adjustBoundingBoxes(std::vector& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs) { /* We build the segment tree for locating possible matching intersections*/ - long size = bbox.size()/(2*SPACEDIM); - for (int i=0; i::max(); for(int idim=0; idim void PlanarIntersector::getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) { - int nbNodesT=_connIndexT[OTT::ind2C(icellT)+1]-_connIndexT[OTT::ind2C(icellT)]; + ConnType nbNodesT=_connIndexT[OTT::ind2C(icellT)+1]-_connIndexT[OTT::ind2C(icellT)]; coordsT.resize(SPACEDIM*nbNodesT); for (ConnType iT=0; iT void PlanarIntersector::getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) { - int nbNodesS=_connIndexS[OTT::ind2C(icellS)+1]-_connIndexS[OTT::ind2C(icellS)]; + ConnType nbNodesS=_connIndexS[OTT::ind2C(icellS)+1]-_connIndexS[OTT::ind2C(icellS)]; coordsS.resize(SPACEDIM*nbNodesS); for (ConnType iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; } + + /*! + * @param icellT id in target mesh in format of MyMeshType. + * @param offset is a value in C format that indicates the number of circular permutation. + * @param coordsT output val that stores coordinates of the target cell automatically resized to the right length. + */ + template + void PlanarIntersector::getRealTargetCoordinatesPermute(ConnType icellT, ConnType offset, std::vector& coordsT) + { + ConnType nbNodesT=_connIndexT[OTT::ind2C(icellT)+1]-_connIndexT[OTT::ind2C(icellT)]; + coordsT.resize(SPACEDIM*nbNodesT); + for (ConnType iTTmp=0; iTTmp::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; + } + } + + /*! + * @param icellS id in source mesh in format of MyMeshType. + * @param offset is a value in C format that indicates the number of circular permutation. + * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. + */ + template + void PlanarIntersector::getRealSourceCoordinatesPermute(ConnType icellS, ConnType offset, std::vector& coordsS) + { + ConnType nbNodesS=_connIndexS[OTT::ind2C(icellS)+1]-_connIndexS[OTT::ind2C(icellS)]; + coordsS.resize(SPACEDIM*nbNodesS); + for (ConnType iSTmp=0; iSTmp::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; + } + } /*! * @param icellT id in target mesh in format of MyMeshType. @@ -188,58 +225,6 @@ namespace INTERP_KERNEL template void PlanarIntersector::getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector& coordsT, std::vector& coordsS, int& orientation) { - /*double epsilon=_precision*_dim_caracteristic; - coordsT.resize(SPACEDIM*nbNodesT); - coordsS.resize(SPACEDIM*nbNodesS); - int nb_dist_NodesT=nbNodesT; - int nb_dist_NodesS=nbNodesS; - int i_last = nbNodesT - 1; - const double * Pi_last=_coordsT +_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+i_last)]; - - for (int iT=0; iT::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)]); - if(distance2(Pi_last, PiT)>epsilon) - { - for (int idim=0; idim::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+i_last)]); - for (int iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)]); - if(distance2(Pi_last, PiS)>epsilon) - { - for (int idim=0; idim= 3) - { - std::cout << std::endl << "Cell coordinates (possibly after projection)" << std::endl; - std::cout << std::endl << "icellT= " << icellT << ", nb nodes T= " << nbNodesT << std::endl; - for(int iT =0; iT< nbNodesT; iT++) - {for (int idim=0; idim + double PlanarIntersector::getValueRegardingOption(double val) const + { + if(_orientation==0) + return val; + if(_orientation==2) + return fabs(val); + if (( val > 0.0 && _orientation==1) || ( val < 0.0 && _orientation==-1 )) + return _orientation*val; + return 0.; + } template - int PlanarIntersector::projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB) + int PlanarIntersector::projectionThis(double *Coords_A, double *Coords_B, ConnType nb_NodesA, ConnType nb_NodesB) { - return projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_median_plane,_do_rotate); + return Projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_max_distance_3Dsurf_intersect,_min_dot_btw_3Dsurf_intersect,_median_plane,_do_rotate); } template - int PlanarIntersector::projection(double *Coords_A, double *Coords_B, - int nb_NodesA, int nb_NodesB, double epsilon, double median_plane, bool do_rotate) + int PlanarIntersector::Projection(double *Coords_A, double *Coords_B, + ConnType nb_NodesA, ConnType nb_NodesB, double epsilon, double md3DSurf, double minDot3DSurf, double median_plane, bool do_rotate) { double normal_A[3]={0,0,0}; double normal_B[3]={0,0,0}; @@ -284,11 +289,12 @@ namespace INTERP_KERNEL bool same_orientation; //Find the normal to cells A and B - int i_A1=1; - while(i_A1(Coords_A,&Coords_A[SPACEDIM*i_A1])< epsilon) i_A1++; - int i_A2=i_A1+1; + ConnType i_A1(1); + while(i_A1(Coords_A,&Coords_A[SPACEDIM*i_A1])< epsilon) + i_A1++; + ConnType i_A2(i_A1+1); crossprod(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); - double normA = sqrt(dotprod(normal_A,normal_A)); + double normA(sqrt(dotprod(normal_A,normal_A))); while(i_A2(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); @@ -296,11 +302,12 @@ namespace INTERP_KERNEL normA = sqrt(dotprod(normal_A,normal_A)); } - int i_B1=1; - while(i_B1(Coords_B,Coords_B+SPACEDIM*i_B1)< epsilon) i_B1++; - int i_B2=i_B1+1; + ConnType i_B1(1); + while(i_B1(Coords_B,Coords_B+SPACEDIM*i_B1)< epsilon) + i_B1++; + ConnType i_B2(i_B1+1); crossprod(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); - double normB = sqrt(dotprod(normal_B,normal_B)); + double normB(sqrt(dotprod(normal_B,normal_B))); while(i_B2(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); @@ -308,66 +315,99 @@ namespace INTERP_KERNEL normB = sqrt(dotprod(normal_B,normal_B)); } + //fabien option + if(md3DSurf>0.) + { + double coords_GA[3]; + for(int i=0;i<3;i++) + { + coords_GA[i]=0.; + for (int j=0;jmd3DSurf) + return 0; + } if(i_A2(normal_A,normal_B)>=0; + + double dotProd(dotprod(normal_A,normal_B)/(normA*normB)); + + if(fabs(dotProd)=0); if(!same_orientation) - for(int idim =0; idim< SPACEDIM; idim++) normal_A[idim] *=-1; + for(int idim =0; idim< SPACEDIM; idim++) + normal_A[idim] *=-1; - double normB= sqrt(dotprod(normal_B,normal_B)); + double normBB(sqrt(dotprod(normal_B,normal_B))); for(int idim =0; idim< SPACEDIM; idim++) - linear_comb[idim] = median_plane*normal_A[idim]/normA + (1-median_plane)*normal_B[idim]/normB; + linear_comb[idim] = median_plane*normal_A[idim]/normA + (1-median_plane)*normal_B[idim]/normBB; double norm= sqrt(dotprod(linear_comb,linear_comb)); //Necessarily: norm>epsilon, no need to check - for(int idim =0; idim< SPACEDIM; idim++) linear_comb[idim]/=norm; + for(int idim =0; idim< SPACEDIM; idim++) + linear_comb[idim]/=norm; //Project the nodes of A and B on the median plane - for(int i_A=0; i_A(&Coords_A[SPACEDIM*i_A],linear_comb); for(int idim =0; idim< SPACEDIM; idim++) Coords_A[SPACEDIM*i_A+idim] -= proj*linear_comb[idim]; } - for(int i_B=0; i_B(Coords_B+SPACEDIM*i_B,linear_comb); for(int idim =0; idim< SPACEDIM; idim++) Coords_B[SPACEDIM*i_B+idim] -= proj*linear_comb[idim]; } - //Buid the matrix sending A into the Oxy plane and apply it to A and B + //Build the matrix sending A into the Oxy plane and apply it to A and B if(do_rotate) { TranslationRotationMatrix rotation; //rotate3DTriangle(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2], rotation); - rotate3DTriangle(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2, rotation); - for (int i=0; i(Coords_A,&Coords_A[i_A1])= " << distance2(Coords_A,&Coords_A[i_A1]) << std::endl; std::cout << "abs(normal_A) = " << fabs(normal_A[0]) << " ; " <(&Coords_B[0],&Coords_B[i_B1])= " << distance2(Coords_B,Coords_B+i_B1) << std::endl; std::cout << "normal_B = " << normal_B[0] << " ; " << normal_B[1] << " ; " << normal_B[2] << std::endl; - return 1; } } template - void PlanarIntersector::rotate3DTriangle(double* PP1, double*PP2, double*PP3, + void PlanarIntersector::Rotate3DTriangle(double* PP1, double*PP2, double*PP3, TranslationRotationMatrix& rotation_matrix) { //initializes