Salome HOME
Update copyright
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Tools_1.cxx
1 // Copyright (C) 2007-2011  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 //              <pkv@irinox>
23
24 #include <GEOMAlgo_Tools.ixx>
25 //
26 #include <NCollection_DataMap.hxx>
27
28 #include <gp_Pnt2d.hxx>
29 #include <gp_Pnt.hxx>
30
31 #include <Geom2dAdaptor_Curve.hxx>
32 #include <Geom2dInt_GInter.hxx>
33 #include <Geom2d_Curve.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_Surface.hxx>
36 #include <GeomAdaptor_Surface.hxx>
37
38 #include <IntRes2d_Domain.hxx>
39 #include <IntRes2d_IntersectionPoint.hxx>
40 #include <IntRes2d_Transition.hxx>
41
42 #include <TopoDS_Iterator.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Wire.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Vertex.hxx>
47 #include <TopExp_Explorer.hxx>
48
49 #include <BRep_Tool.hxx>
50 #include <BRep_Builder.hxx>
51
52 #include <TopTools_MapOfShape.hxx>
53 #include <TopTools_ShapeMapHasher.hxx>
54 #include <TopTools_ListOfShape.hxx>
55 #include <TopTools_DataMapOfShapeListOfShape.hxx>
56 #include <TopTools_ListOfShape.hxx>
57 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
58 #include <BRepTools.hxx>
59
60 static 
61   inline Standard_Boolean IsEqual(const TopoDS_Shape& aS1, 
62                                   const TopoDS_Shape& aS2) {
63   return TopTools_ShapeMapHasher::IsEqual(aS1, aS2);
64 }
65 //
66 static
67   Standard_Boolean CorrectWire(const TopoDS_Wire& aW,
68                                const TopoDS_Face& aF);
69
70 //=======================================================================
71 //function : CorrectWires
72 //purpose  : 
73 //=======================================================================
74   Standard_Boolean GEOMAlgo_Tools::CorrectWires(const TopoDS_Shape& aShape)
75 {
76   Standard_Boolean bRet;
77   TopoDS_Iterator aItF;
78   TopExp_Explorer aExp;
79   TopTools_MapOfShape aMF;
80   GeomAdaptor_Surface aGAS;
81   GeomAbs_SurfaceType aTS;
82   TopLoc_Location aLoc; 
83   //
84   bRet=Standard_False;
85   //
86   aExp.Init(aShape, TopAbs_FACE);
87   for (; aExp.More(); aExp.Next()) {
88     const TopoDS_Face& aF=*((TopoDS_Face*)&aExp.Current());
89     if (aMF.Add(aF)) {
90       const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF, aLoc);
91       aGAS.Load(aS);
92       aTS=aGAS.GetType();
93       if (aTS==GeomAbs_Cylinder || aTS==GeomAbs_Plane) {
94         aItF.Initialize(aF);
95         for (; aItF.More(); aItF.Next()) {
96           const TopoDS_Wire& aW=*((TopoDS_Wire*)&aItF.Value());
97           if (CorrectWire(aW, aF)) {
98            bRet=Standard_True;
99           }
100         }
101       }
102     }
103   }
104   return bRet;
105 }
106 //=======================================================================
107 //class: GEOMAlgo_InfoEdge
108 //purpose  : 
109 //=======================================================================
110 class GEOMAlgo_InfoEdge {
111  public:
112   //
113   GEOMAlgo_InfoEdge() {
114     myErrorStatus=0;
115     myTolInt=1.0e-10;
116   };
117   //
118   ~GEOMAlgo_InfoEdge(){
119   };
120   //
121   void Init(const TopoDS_Edge& aE, 
122             const TopoDS_Face& aF);
123   //
124   void SetTolInt(const Standard_Real aTolInt) {
125     myTolInt=aTolInt;
126   };
127   //
128   const Standard_Real TolInt() const {
129     return myTolInt;
130   }
131   //
132   const Geom2dAdaptor_Curve& Adaptor() const {
133     return myGAC2D;
134   }
135   //
136   const IntRes2d_Domain& Domain()const {
137     return myDomain;
138   }
139   //
140   const Handle(Geom2d_Curve)& CurveOnSurface()const {
141     return myC2D;
142   }
143   //
144   const Handle(Geom_Curve)& Curve()const {
145     return myC3D;
146   }
147   //
148   Standard_Integer ErrorStatus()const {
149     return myErrorStatus;
150   }
151   //
152  protected:
153   Standard_Integer myErrorStatus;
154   Standard_Real myTolInt;
155   Geom2dAdaptor_Curve myGAC2D;
156   IntRes2d_Domain myDomain;
157   Handle(Geom2d_Curve) myC2D;
158   Handle(Geom_Curve) myC3D;
159 };
160 //
161 typedef NCollection_DataMap<TopoDS_Shape, GEOMAlgo_InfoEdge> GEOMAlgo_DataMapOfShapeInfoEdge; 
162 typedef GEOMAlgo_DataMapOfShapeInfoEdge::Iterator GEOMAlgo_DataMapIteratorOfDataMapOfShapeInfoEdge; 
163
164 //=======================================================================
165 //function : Init
166 //purpose  : 
167 //=======================================================================
168   void GEOMAlgo_InfoEdge::Init(const TopoDS_Edge& aE, 
169                                const TopoDS_Face& aF)
170 {
171   Standard_Real aT1, aT2, aT1x, aT2x;
172   gp_Pnt2d aP2D1, aP2D2;
173   //
174   myErrorStatus=0;
175   //
176   myC3D=BRep_Tool::Curve(aE, aT1, aT2);
177   myC2D=BRep_Tool::CurveOnSurface(aE ,aF, aT1, aT2);
178   if (!myC2D.IsNull() && aT2>aT1) {
179     myGAC2D.Load(myC2D);
180     if(!myGAC2D.IsPeriodic()) {
181       aT1x=myGAC2D.FirstParameter();
182       aT2x=myGAC2D.LastParameter();
183       if(aT1x > aT1) {
184         aT1=aT1x;
185       }
186       if(aT2x < aT2) {
187         aT2=aT2x;
188       }
189     }
190     //
191     BRep_Tool::UVPoints(aE, aF, aP2D1, aP2D2);
192     myDomain.SetValues(aP2D1, aT1, myTolInt, aP2D2, aT2, myTolInt);
193   }
194   else {
195     myErrorStatus=10;
196     return;
197   }
198 }
199 //=======================================================================
200 //function : CorrectWire
201 //purpose  : 
202 //=======================================================================
203 Standard_Boolean CorrectWire(const TopoDS_Wire& aW,
204                              const TopoDS_Face& aF)
205 {
206   Standard_Boolean bRet;
207   Standard_Real aTolInt;
208   Standard_Integer iErr, aNbV, aNbE;
209   TopoDS_Iterator aItW, aItE;
210   Geom2dInt_GInter aInter;
211   GEOMAlgo_DataMapOfShapeInfoEdge aDMEIE;
212   TopTools_DataMapOfShapeListOfShape aDMVLE;
213   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMVLE;
214   //
215   bRet=Standard_False;
216   aTolInt=1.0e-10;
217   //
218   aItW.Initialize(aW);
219   for (; aItW.More(); aItW.Next()) {
220     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
221     
222     aItE.Initialize(aE);
223     for (aNbV=0; aItE.More(); aItE.Next(), ++aNbV) {
224     }
225     if (aNbV<2) {
226       return bRet; //
227     }
228     //
229     if (!aDMEIE.IsBound(aE)) {
230       GEOMAlgo_InfoEdge aInfoEdge;
231       //
232       aInfoEdge.Init (aE, aF);
233       iErr=aInfoEdge.ErrorStatus();
234       if (iErr) {
235         return bRet; //
236       }
237       //
238       aDMEIE.Bind(aE, aInfoEdge);
239     }
240     //
241     aItE.Initialize(aE);
242     for (; aItE.More(); aItE.Next()) {
243       const TopoDS_Shape& aV=aItE.Value();
244       if (aDMVLE.IsBound(aV)) {
245         TopTools_ListOfShape& aLE=aDMVLE.ChangeFind(aV);
246         aLE.Append(aE);
247       }
248       else {
249         TopTools_ListOfShape aLE;
250         aLE.Append(aE);
251         aDMVLE.Bind(aV, aLE);
252       }
253     }
254   }
255   //
256   // 2
257   Standard_Real aTolV, aD1, aD2, aDmax, aCoeff;
258   gp_Pnt aPV;
259   Handle(Geom_Surface) aS;
260   BRep_Builder aBB;
261   //
262   aCoeff=1.1;
263   aS=BRep_Tool::Surface(aF);
264   //
265   aItDMVLE.Initialize(aDMVLE);
266   for(; aItDMVLE.More(); aItDMVLE.Next()) {
267     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aItDMVLE.Key());
268     const TopTools_ListOfShape& aLE=aItDMVLE.Value();
269     aNbE=aLE.Extent();
270     if (aNbE!=2) {
271       continue;
272     }
273     //
274     aPV=BRep_Tool::Pnt(aV);
275     aTolV=BRep_Tool::Tolerance(aV);
276     //
277     const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aLE.First());
278     const GEOMAlgo_InfoEdge& aIE1=aDMEIE.Find(aE1); 
279     const Geom2dAdaptor_Curve& aGAC1=aIE1.Adaptor();
280     const IntRes2d_Domain& aDomain1=aIE1.Domain();
281     //
282     const TopoDS_Edge& aE2=*((TopoDS_Edge*)&aLE.Last()); 
283     const GEOMAlgo_InfoEdge& aIE2=aDMEIE.Find(aE2);
284     const Geom2dAdaptor_Curve& aGAC2=aIE2.Adaptor();
285     const IntRes2d_Domain& aDomain2=aIE2.Domain();
286     //
287     aInter.Perform(aGAC1, aDomain1,aGAC2, aDomain2, aTolInt, aTolInt);
288     if(!aInter.IsDone()) { 
289       continue;
290     }
291     //
292     Standard_Integer i, aNbP;
293     Standard_Real aIP_ParamOnFirst, aIP_ParamOnSecond;
294     gp_Pnt aP3D1, aP3D2;
295     gp_Pnt2d aP2D1, aP2D2;
296     IntRes2d_Transition aTr1, aTr2;
297     //
298     aNbP=aInter.NbPoints();
299     for (i=1; i<=aNbP; ++i) {
300       const IntRes2d_IntersectionPoint& aIP = aInter.Point(i);
301       aIP_ParamOnFirst  = aIP.ParamOnFirst();
302       aIP_ParamOnSecond = aIP.ParamOnSecond();
303       aTr1 =aIP.TransitionOfFirst();
304       aTr2 =aIP.TransitionOfSecond();
305       if(aTr1.PositionOnCurve()==IntRes2d_Middle ||
306          aTr2.PositionOnCurve()==IntRes2d_Middle) {
307         //
308         const Handle(Geom_Curve)& aC3D1=aIE1.Curve();
309         if (!aC3D1.IsNull()) {
310           aP3D1=aC3D1->Value(aIP_ParamOnFirst);
311         }
312         else {
313           aP2D1=aGAC1.Value(aIP_ParamOnFirst);
314           aS->D0(aP2D1.X(), aP2D1.Y(), aP3D1);
315         }
316         //
317         const Handle(Geom_Curve)& aC3D2=aIE2.Curve();   
318         if (!aC3D2.IsNull()) {
319           aP3D2=aC3D2->Value(aIP_ParamOnSecond);
320         }
321         else {
322           aP2D2=aGAC2.Value(aIP_ParamOnSecond);
323           aS->D0(aP2D2.X(), aP2D2.Y(), aP3D2);
324         }
325         //
326         aD1=aPV.Distance(aP3D1);
327         aD2=aPV.Distance(aP3D2);
328         aDmax=(aD1>aD2)? aD1 : aD2;
329         if (aDmax>aCoeff*aTolV) {
330           if (aDmax<10.*aTolV){
331             aBB.UpdateVertex(aV, aDmax);
332             bRet=Standard_True;
333           }
334         }
335       }//
336     }//for (i=1; i<=aNbP; ++i) {
337   }//for(; aItDMVLE.More(); aItDMVLE.Next()) {
338   return bRet;
339 }
340
341