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