Salome HOME
Merge branch 'BR_H2018_3' into BR_2018_V8_5
[modules/hydro.git] / src / HYDROData / HYDROData_LCM_FaceClassifier.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROData_LCM_FaceClassifier.h"
20
21 #include <HYDROData_LandCoverMap.h>
22 #include <HYDROData_Tool.h>
23
24 #include <Bnd_Box2d.hxx> 
25 #include <BRepTools.hxx>
26 #include <BRepBndLib.hxx>
27 #include <Bnd_Box.hxx>
28 #include <NCollection_UBTree.hxx>
29 #include <NCollection_UBTreeFiller.hxx>
30 #include <BRepTopAdaptor_FClass2d.hxx>
31 #include <TopoDS.hxx>
32 #include <TopTools_IndexedMapOfShape.hxx>
33 #include <Geom_Plane.hxx>
34 #include <BRep_Tool.hxx>
35 #include <Geom_Surface.hxx>
36 #include <ElSLib.hxx>
37 #include <Message_ProgressSentry.hxx>
38
39
40 Standard_Boolean HYDROData_FaceClassifier_BndBoxTreeSelector::Accept (const Standard_Integer& theObj)
41 {
42   if (theObj > myMapF2Class2d.Extent())
43     return Standard_False;
44
45   const TopoDS_Face& f = TopoDS::Face(myMapF2Class2d.FindKey(theObj));
46   if(f.IsNull()) 
47     return Standard_False;
48
49   BRepTopAdaptor_FClass2d* class2d = myMapF2Class2d.FindFromKey(f);  
50
51   Handle(Geom_Plane) Pl = HYDROData_LCM_FaceClassifier::GetPlane(f);
52   Standard_Real u, v;
53   ElSLib::Parameters(Pl->Pln(), gp_Pnt(myP.X(), myP.Y(), 0.0), u, v);
54   TopAbs_State aState = class2d->Perform( gp_Pnt2d(u, v), Standard_False );
55
56   if (aState == TopAbs_IN)
57   {
58     myResFaces.Append(f);
59     myStop = 1; //no more faces includes this point; quit
60     return Standard_True;
61   }
62   else if (aState == TopAbs_ON)
63   {
64     myResFaces.Append(f);
65     return Standard_True;
66   }
67
68   return Standard_False;
69
70 }
71
72 Handle(Geom_Plane) HYDROData_LCM_FaceClassifier::GetPlane(const TopoDS_Face& F)
73 {
74   TopLoc_Location L;
75   Handle(Geom_Surface) S = BRep_Tool::Surface(F, L);
76   Handle(Geom_Plane) Pl = Handle(Geom_Plane)::DownCast(S->Transformed(L.Transformation()));
77   return Pl;
78 }
79
80 void HYDROData_LCM_FaceClassifier::Classify( const std::vector<gp_XY>& thePoints, 
81                                              std::vector<std::set <QString> >& theTypes,
82                                              std::vector<NCollection_Map<TopoDS_Face> >* theFaces) const
83 {
84   HYDROData_LandCoverMap::Explorer anIt( *myLCM );
85   HYDROData_MapOfFaceToStricklerType aMapF2ST;
86   TopTools_IndexedMapOfShape aFaces; 
87   for( ; anIt.More(); anIt.Next() )
88   {
89     const TopoDS_Face& F = anIt.Face();
90     aMapF2ST.Add(F, anIt.StricklerType());
91     aFaces.Add(F);
92   }
93
94   HYDROData_FaceClassifier_BndBoxTree aTree;
95   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFiller (aTree);
96   NCollection_IndexedDataMap<TopoDS_Face, BRepTopAdaptor_FClass2d*> aMapF2Class2d;
97
98   int NbF = aFaces.Extent();
99   std::vector<BRepTopAdaptor_FClass2d*> fclass2dpointers;
100   fclass2dpointers.reserve(NbF);
101
102   for (int i = 1; i <= NbF; i++)
103   {
104     Bnd_Box b3d;
105     const TopoDS_Face& F = TopoDS::Face(aFaces(i));
106     BRepBndLib::Add(F, b3d);
107     Bnd_Box2d NB;
108     NB.Update(b3d.CornerMin().X(), b3d.CornerMin().Y(), b3d.CornerMax().X(), b3d.CornerMax().Y() );
109     aTreeFiller.Add(i, NB);
110     BRepTopAdaptor_FClass2d* aClass2d = new BRepTopAdaptor_FClass2d( F, 1E-7 );
111     aMapF2Class2d.Add(F, aClass2d);
112     fclass2dpointers.push_back(aClass2d);
113   }
114
115   aTreeFiller.Fill();
116
117   size_t pntsize = thePoints.size();
118   theTypes.reserve(pntsize);
119   if (theFaces) {
120     theFaces->resize(pntsize);
121   }
122
123   Message_ProgressSentry aPSentry (HYDROData_Tool::GetSIProgress(), "Classify", 0, pntsize - 1, 1);
124
125   Standard_Integer aSel = 0;
126   for (size_t i = 0; i < pntsize && aPSentry.More(); i++, aPSentry.Next())
127   {
128     std::set<QString> aSet;
129  
130     HYDROData_FaceClassifier_BndBoxTreeSelector aSelector(aMapF2Class2d);
131     const gp_Pnt2d& pnt2d = thePoints[i]; 
132     aSelector.SetCurrentPoint(pnt2d);
133     aSel = aTree.Select(aSelector); 
134     if (aSel > 0)
135     {
136       const NCollection_List<TopoDS_Face>& rf = aSelector.GetResFaces();
137       NCollection_List<TopoDS_Face>::Iterator it(rf);
138       for (;it.More();it.Next())
139       {
140         const TopoDS_Face& f = it.Value();
141         QString aST = aMapF2ST.FindFromKey(f);
142         aSet.insert(aST);
143         if (theFaces)
144           (*theFaces)[i].Add(f);
145       }      
146     }
147
148     theTypes.push_back(aSet);
149   }
150
151   for (size_t i = 0; i < fclass2dpointers.size(); i++)
152     delete fclass2dpointers[i];
153 }
154
155