Salome HOME
CMake porting.
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Tools_1.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // File:    GEOMAlgo_Tools_1.cxx
20 // Created: Thu May  6 10:46:21 2010
21 // Author:  Peter KURNEV
22
23 #include <GEOMAlgo_Tools.hxx>
24
25 #include <NCollection_DataMap.hxx>
26
27 #include <gp_Pnt2d.hxx>
28 #include <gp_Pnt.hxx>
29
30 #include <Geom2dAdaptor_Curve.hxx>
31 #include <Geom2dInt_GInter.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_Surface.hxx>
35 #include <GeomAdaptor_Surface.hxx>
36
37 #include <IntRes2d_Domain.hxx>
38 #include <IntRes2d_IntersectionPoint.hxx>
39 #include <IntRes2d_Transition.hxx>
40
41 #include <TopoDS_Iterator.hxx>
42 #include <TopoDS_Face.hxx>
43 #include <TopoDS_Wire.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Vertex.hxx>
46 #include <TopExp_Explorer.hxx>
47
48 #include <BRep_Tool.hxx>
49 #include <BRep_Builder.hxx>
50
51 #include <TopTools_MapOfShape.hxx>
52 #include <TopTools_ShapeMapHasher.hxx>
53 #include <TopTools_ListOfShape.hxx>
54 #include <TopTools_DataMapOfShapeListOfShape.hxx>
55 #include <TopTools_ListOfShape.hxx>
56 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
57 #include <BRepTools.hxx>
58
59 static
60   inline Standard_Boolean IsEqual(const TopoDS_Shape& aS1,
61                                   const TopoDS_Shape& aS2) {
62   return TopTools_ShapeMapHasher::IsEqual(aS1, aS2);
63 }
64 //
65 static
66   Standard_Boolean CorrectWire(const TopoDS_Wire& aW,
67                                const TopoDS_Face& aF);
68
69 //=======================================================================
70 //function : CorrectWires
71 //purpose  :
72 //=======================================================================
73 Standard_Boolean GEOMAlgo_Tools::CorrectWires(const TopoDS_Shape& aShape)
74 {
75   Standard_Boolean bRet;
76   TopoDS_Iterator aItF;
77   TopExp_Explorer aExp;
78   TopTools_MapOfShape aMF;
79   GeomAdaptor_Surface aGAS;
80   GeomAbs_SurfaceType aTS;
81   TopLoc_Location aLoc;
82   //
83   bRet=Standard_False;
84   //
85   aExp.Init(aShape, TopAbs_FACE);
86   for (; aExp.More(); aExp.Next()) {
87     const TopoDS_Face& aF=*((TopoDS_Face*)&aExp.Current());
88     if (aMF.Add(aF)) {
89       const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF, aLoc);
90       aGAS.Load(aS);
91       aTS=aGAS.GetType();
92       //modified by NIZNHY-PKV Mon Jul 02 13:58:30 2012f
93       if (aTS==GeomAbs_Cylinder || aTS==GeomAbs_Plane || aTS==GeomAbs_BSplineSurface) {
94     //if (aTS==GeomAbs_Cylinder || aTS==GeomAbs_Plane) {
95         //modified by NIZNHY-PKV Mon Jul 02 13:58:33 2012t
96         aItF.Initialize(aF);
97         for (; aItF.More(); aItF.Next()) {
98           const TopoDS_Wire& aW=*((TopoDS_Wire*)&aItF.Value());
99           if (CorrectWire(aW, aF)) {
100            bRet=Standard_True;
101           }
102         }
103       }
104     }
105   }
106   return bRet;
107 }
108
109 //=======================================================================
110 //class: GEOMAlgo_InfoEdge
111 //purpose  :
112 //=======================================================================
113 class GEOMAlgo_InfoEdge {
114  public:
115   //
116   GEOMAlgo_InfoEdge() {
117     myErrorStatus=0;
118     myTolInt=1.0e-10;
119   };
120   //
121   ~GEOMAlgo_InfoEdge(){
122   };
123   //
124   void Init(const TopoDS_Edge& aE,
125             const TopoDS_Face& aF);
126   //
127   void SetTolInt(const Standard_Real aTolInt) {
128     myTolInt=aTolInt;
129   };
130   //
131   const Standard_Real TolInt() const {
132     return myTolInt;
133   }
134   //
135   const Geom2dAdaptor_Curve& Adaptor() const {
136     return myGAC2D;
137   }
138   //
139   const IntRes2d_Domain& Domain()const {
140     return myDomain;
141   }
142   //
143   const Handle(Geom2d_Curve)& CurveOnSurface()const {
144     return myC2D;
145   }
146   //
147   const Handle(Geom_Curve)& Curve()const {
148     return myC3D;
149   }
150   //
151   Standard_Integer ErrorStatus()const {
152     return myErrorStatus;
153   }
154   //
155  protected:
156   Standard_Integer myErrorStatus;
157   Standard_Real myTolInt;
158   Geom2dAdaptor_Curve myGAC2D;
159   IntRes2d_Domain myDomain;
160   Handle(Geom2d_Curve) myC2D;
161   Handle(Geom_Curve) myC3D;
162 };
163 //
164 typedef NCollection_DataMap<TopoDS_Shape, GEOMAlgo_InfoEdge> GEOMAlgo_DataMapOfShapeInfoEdge;
165 typedef GEOMAlgo_DataMapOfShapeInfoEdge::Iterator GEOMAlgo_DataMapIteratorOfDataMapOfShapeInfoEdge;
166
167 //=======================================================================
168 //function : Init
169 //purpose  :
170 //=======================================================================
171   void GEOMAlgo_InfoEdge::Init(const TopoDS_Edge& aE,
172                                const TopoDS_Face& aF)
173 {
174   Standard_Real aT1, aT2, aT1x, aT2x;
175   gp_Pnt2d aP2D1, aP2D2;
176   //
177   myErrorStatus=0;
178   //
179   myC3D=BRep_Tool::Curve(aE, aT1, aT2);
180   myC2D=BRep_Tool::CurveOnSurface(aE ,aF, aT1, aT2);
181   if (!myC2D.IsNull() && aT2>aT1) {
182     myGAC2D.Load(myC2D);
183     if(!myGAC2D.IsPeriodic()) {
184       aT1x=myGAC2D.FirstParameter();
185       aT2x=myGAC2D.LastParameter();
186       if(aT1x > aT1) {
187         aT1=aT1x;
188       }
189       if(aT2x < aT2) {
190         aT2=aT2x;
191       }
192     }
193     //
194     BRep_Tool::UVPoints(aE, aF, aP2D1, aP2D2);
195     myDomain.SetValues(aP2D1, aT1, myTolInt, aP2D2, aT2, myTolInt);
196   }
197   else {
198     myErrorStatus=10;
199     return;
200   }
201 }
202
203 //=======================================================================
204 //function : CorrectWire
205 //purpose  :
206 //=======================================================================
207 Standard_Boolean CorrectWire(const TopoDS_Wire& aW,
208                              const TopoDS_Face& aF)
209 {
210   Standard_Boolean bRet;
211   Standard_Real aTolInt;
212   Standard_Integer iErr, aNbV, aNbE;
213   TopoDS_Iterator aItW, aItE;
214   Geom2dInt_GInter aInter;
215   GEOMAlgo_DataMapOfShapeInfoEdge aDMEIE;
216   TopTools_DataMapOfShapeListOfShape aDMVLE;
217   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMVLE;
218   //
219   bRet=Standard_False;
220   aTolInt=1.0e-10;
221   //
222   aItW.Initialize(aW);
223   for (; aItW.More(); aItW.Next()) {
224     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
225
226     aItE.Initialize(aE);
227     for (aNbV=0; aItE.More(); aItE.Next(), ++aNbV) {
228     }
229     if (aNbV<2) {
230       return bRet; //
231     }
232     //
233     if (!aDMEIE.IsBound(aE)) {
234       GEOMAlgo_InfoEdge aInfoEdge;
235       //
236       aInfoEdge.Init (aE, aF);
237       iErr=aInfoEdge.ErrorStatus();
238       if (iErr) {
239         return bRet; //
240       }
241       //
242       aDMEIE.Bind(aE, aInfoEdge);
243     }
244     //
245     aItE.Initialize(aE);
246     for (; aItE.More(); aItE.Next()) {
247       const TopoDS_Shape& aV=aItE.Value();
248       if (aDMVLE.IsBound(aV)) {
249         TopTools_ListOfShape& aLE=aDMVLE.ChangeFind(aV);
250         aLE.Append(aE);
251       }
252       else {
253         TopTools_ListOfShape aLE;
254         aLE.Append(aE);
255         aDMVLE.Bind(aV, aLE);
256       }
257     }
258   }
259   //
260   // 2
261   Standard_Real aTolV, aD1, aD2, aDmax, aCoeff;
262   gp_Pnt aPV;
263   Handle(Geom_Surface) aS;
264   BRep_Builder aBB;
265   //
266   aCoeff=1.1;
267   aS=BRep_Tool::Surface(aF);
268   //
269   aItDMVLE.Initialize(aDMVLE);
270   for(; aItDMVLE.More(); aItDMVLE.Next()) {
271     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aItDMVLE.Key());
272     const TopTools_ListOfShape& aLE=aItDMVLE.Value();
273     aNbE=aLE.Extent();
274     if (aNbE!=2) {
275       continue;
276     }
277     //
278     aPV=BRep_Tool::Pnt(aV);
279     aTolV=BRep_Tool::Tolerance(aV);
280     //
281     const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aLE.First());
282     const GEOMAlgo_InfoEdge& aIE1=aDMEIE.Find(aE1);
283     const Geom2dAdaptor_Curve& aGAC1=aIE1.Adaptor();
284     const IntRes2d_Domain& aDomain1=aIE1.Domain();
285     //
286     const TopoDS_Edge& aE2=*((TopoDS_Edge*)&aLE.Last());
287     const GEOMAlgo_InfoEdge& aIE2=aDMEIE.Find(aE2);
288     const Geom2dAdaptor_Curve& aGAC2=aIE2.Adaptor();
289     const IntRes2d_Domain& aDomain2=aIE2.Domain();
290     //
291     aInter.Perform(aGAC1, aDomain1,aGAC2, aDomain2, aTolInt, aTolInt);
292     if(!aInter.IsDone()) {
293       continue;
294     }
295     //
296     Standard_Integer i, aNbP;
297     Standard_Real aIP_ParamOnFirst, aIP_ParamOnSecond, aDTresh, aDT;
298     gp_Pnt aP3D1, aP3D2;
299     gp_Pnt2d aP2D1, aP2D2;
300     IntRes2d_Transition aTr1, aTr2;
301     //
302     aDTresh=0.001;
303     //
304     aNbP=aInter.NbPoints();
305     for (i=1; i<=aNbP; ++i) {
306       const IntRes2d_IntersectionPoint& aIP = aInter.Point(i);
307       aIP_ParamOnFirst  = aIP.ParamOnFirst();
308       aIP_ParamOnSecond = aIP.ParamOnSecond();
309       aTr1 =aIP.TransitionOfFirst();
310       aTr2 =aIP.TransitionOfSecond();
311       if(aTr1.PositionOnCurve()==IntRes2d_Middle ||
312          aTr2.PositionOnCurve()==IntRes2d_Middle) {
313         //
314         const Handle(Geom_Curve)& aC3D1=aIE1.Curve();
315         if (!aC3D1.IsNull()) {
316           aP3D1=aC3D1->Value(aIP_ParamOnFirst);
317         }
318         else {
319           aP2D1=aGAC1.Value(aIP_ParamOnFirst);
320           aS->D0(aP2D1.X(), aP2D1.Y(), aP3D1);
321         }
322         //
323         const Handle(Geom_Curve)& aC3D2=aIE2.Curve();
324         if (!aC3D2.IsNull()) {
325           aP3D2=aC3D2->Value(aIP_ParamOnSecond);
326         }
327         else {
328           aP2D2=aGAC2.Value(aIP_ParamOnSecond);
329           aS->D0(aP2D2.X(), aP2D2.Y(), aP3D2);
330         }
331         //
332         aD1=aPV.Distance(aP3D1);
333         aD2=aPV.Distance(aP3D2);
334         aDmax=(aD1>aD2)? aD1 : aD2;
335         if (aDmax>aCoeff*aTolV) {
336           //modified by NIZNHY-PKV Mon Jul 02 13:56:35 2012f
337           aDT=10.*aTolV;
338           if (aDT<aDTresh) {
339             aDT=aDTresh;
340           }
341           if (aDmax<aDT){
342           //if (aDmax<10.*aTolV){
343           //modified by NIZNHY-PKV Mon Jul 02 13:56:40 2012t
344             aBB.UpdateVertex(aV, aDmax);
345             bRet=Standard_True;
346           }
347         }
348       }//
349     }//for (i=1; i<=aNbP; ++i) {
350   }//for(; aItDMVLE.More(); aItDMVLE.Next()) {
351   return bRet;
352 }