Salome HOME
97bdbb03e2fe601daf62e86019ec14642b517b21
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Tools.cxx
1 // File:        GEOMAlgo_Tools.cxx
2 // Created:     Mon Dec  6 11:35:29 2004
3 // Author:      Peter KURNEV
4 //              <pkv@irinox>
5
6 #include <GEOMAlgo_Tools.ixx>
7
8 #include <gp_Pnt.hxx>
9 #include <gp_Pnt2d.hxx>
10
11 #include <Geom_Surface.hxx>
12 #include <Geom_Curve.hxx>
13 #include <Geom2d_Curve.hxx>
14 #include <GeomAdaptor_Surface.hxx>
15
16 #include <GeomAPI_ProjectPointOnSurf.hxx>
17
18 #include <TopAbs_ShapeEnum.hxx>
19
20 #include <TopoDS.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopoDS_Edge.hxx>
23
24 #include <TopTools_ListOfShape.hxx>
25 #include <TopTools_ListIteratorOfListOfShape.hxx>
26 #include <TopTools_IndexedMapOfShape.hxx>
27
28 #include <BRep_Tool.hxx>
29 #include <BRep_Builder.hxx>
30 #include <BRepTools.hxx>
31
32 #include <BOPTools_Tools2D.hxx>
33 #include <IntTools_Context.hxx>
34
35 #include <GEOMAlgo_PassKey.hxx>
36 #include <GEOMAlgo_IndexedDataMapOfPassKeyListOfShape.hxx>
37 //
38 //=======================================================================
39 //function : RefineSDShapes
40 //purpose  : 
41 //=======================================================================
42 Standard_Integer GEOMAlgo_Tools::RefineSDShapes(GEOMAlgo_IndexedDataMapOfPassKeyListOfShape &aMPKLE,
43                                                 const Standard_Real aTol,
44                                                 IntTools_Context& aCtx)
45 {
46   Standard_Integer i, aNbE, iErr, j, aNbEE, aNbToAdd;
47   TopTools_IndexedDataMapOfShapeListOfShape aMEE, aMSDE, aMEToAdd;
48   //
49   iErr=1;
50   //
51   aNbE=aMPKLE.Extent();
52   for (i=1; i<=aNbE; ++i) {
53     TopTools_ListOfShape& aLSDE=aMPKLE.ChangeFromIndex(i);
54     //
55     aMEE.Clear();
56     iErr=GEOMAlgo_Tools::FindSDShapes(aLSDE, aTol, aMEE, aCtx);
57     if (iErr) {
58       return iErr;
59     }
60     //
61     aNbEE=aMEE.Extent();
62     if (aNbEE==1) {
63       continue;  // nothing to do 
64     }
65     //
66     for (j=1; j<=aNbEE; ++j) {
67       TopTools_ListOfShape& aLEE=aMEE.ChangeFromIndex(j);
68       //
69       if (j==1) {
70         aLSDE.Clear();
71         aLSDE.Append(aLEE);
72       }
73       else {
74         const TopoDS_Shape& aE1=aLEE.First();
75         aMEToAdd.Add(aE1, aLEE);
76       }
77     }
78   }
79   //
80   aNbToAdd=aMEToAdd.Extent();
81   if (!aNbToAdd) {
82     return aNbToAdd;
83   }
84   //
85   for (i=1; i<=aNbToAdd; ++i) {
86     GEOMAlgo_PassKey aPKE1;
87     //
88     const TopoDS_Shape& aE1=aMEToAdd.FindKey(i);
89     const TopTools_ListOfShape& aLE=aMEToAdd(i);
90     //
91     aPKE1.SetIds(aE1);
92     aMPKLE.Add(aPKE1, aLE);
93   }
94   //
95   return 0;
96 }
97 //=======================================================================
98 //function : FindSDShapes
99 //purpose  : 
100 //=======================================================================
101 Standard_Integer GEOMAlgo_Tools::FindSDShapes(const TopTools_ListOfShape& aLE,
102                                               const Standard_Real aTol,
103                                               TopTools_IndexedDataMapOfShapeListOfShape& aMEE,
104                                               IntTools_Context& aCtx)
105 {
106   Standard_Integer aNbE, aNbEProcessed, aNbESD, iErr;
107   TopTools_ListOfShape aLESD;
108   TopTools_ListIteratorOfListOfShape aIt, aIt1;
109   TopTools_IndexedMapOfShape aMProcessed;
110   TopAbs_ShapeEnum aType;
111   //
112   aNbE=aLE.Extent();
113   if (!aNbE) {
114     return 3; // Err
115   } 
116   //modified by NIZNHY-PKV Thu Dec 30 10:56:52 2004 f
117   if (aNbE==1) {
118     return 0; // Nothing to do
119   } 
120   //modified by NIZNHY-PKV Thu Dec 30 10:56:56 2004 t
121   //
122   while(1) {
123     aNbEProcessed=aMProcessed.Extent();
124     if (aNbEProcessed==aNbE) {
125       break;
126     }
127     //
128     aIt.Initialize(aLE);
129     for (; aIt.More(); aIt.Next()) {
130       const TopoDS_Shape& aS=aIt.Value();
131       //
132       if (aMProcessed.Contains(aS)) {
133         continue;
134       }
135       //
136       //modified by NIZNHY-PKV Thu Dec 30 10:57:01 2004 f
137       aType=aS.ShapeType();
138       if (aType==TopAbs_EDGE) {
139         const TopoDS_Edge& aE=TopoDS::Edge(aS);
140         if (BRep_Tool::Degenerated(aE)) {
141           aMProcessed.Add(aE);
142           continue;
143         }
144       }
145       //modified by NIZNHY-PKV Thu Dec 30 10:57:03 2004 t
146       //
147       aLESD.Clear();
148       iErr=GEOMAlgo_Tools::FindSDShapes(aS, aLE, aTol, aLESD, aCtx);
149       if (iErr) {
150         return 2; // Err
151       }
152       //
153       aNbESD=aLESD.Extent();
154       if (!aNbESD) {
155         return 1; // Err
156       }
157       //
158       aMEE.Add(aS, aLESD);
159       //
160       aIt1.Initialize(aLESD);
161       for (; aIt1.More(); aIt1.Next()) {
162         const TopoDS_Shape& aE1=aIt1.Value();
163         aMProcessed.Add(aE1);
164       }
165     }
166   }
167   return 0;
168 }
169 //=======================================================================
170 //function : FindSDShapes
171 //purpose  : 
172 //=======================================================================
173 Standard_Integer GEOMAlgo_Tools::FindSDShapes(const TopoDS_Shape& aE1,
174                                               const TopTools_ListOfShape& aLE,
175                                               const Standard_Real aTol,
176                                               TopTools_ListOfShape& aLESD,
177                                               IntTools_Context& aCtx)
178 {
179   Standard_Boolean bIsDone;
180   Standard_Real aTol2, aD2;
181   gp_Pnt aP1, aP2;
182   TopTools_ListIteratorOfListOfShape aIt;
183   //
184   aTol2=aTol*aTol;
185   GEOMAlgo_Tools::PointOnShape(aE1, aP1);
186   //
187   aIt.Initialize(aLE);
188   for (; aIt.More(); aIt.Next()) {
189     const TopoDS_Shape& aE2=aIt.Value();
190     if (aE2.IsSame(aE1)) {
191        aLESD.Append(aE2);
192     }
193     else {
194       bIsDone=GEOMAlgo_Tools::ProjectPointOnShape(aP1, aE2, aP2, aCtx);
195       if (!bIsDone) {
196         return 1; 
197       }
198       aD2=aP1.SquareDistance(aP2);
199       if(aD2<aTol2) {
200         aLESD.Append(aE2);
201       }
202     }
203   }
204   return 0;
205 }
206
207 //=======================================================================
208 //function : ProjectPointOnShape
209 //purpose  : 
210 //=======================================================================
211 Standard_Boolean GEOMAlgo_Tools::ProjectPointOnShape(const gp_Pnt& aP1,
212                                                      const TopoDS_Shape& aS,
213                                                      gp_Pnt& aP2,
214                                                      IntTools_Context& aCtx)
215 {
216   Standard_Boolean bIsDone=Standard_False;
217   Standard_Real aT2;
218   TopAbs_ShapeEnum aType;
219   //
220   aType=aS.ShapeType();
221   switch(aType) {
222     case TopAbs_EDGE: {
223       const TopoDS_Edge& aE2=TopoDS::Edge(aS);
224       //
225       bIsDone=aCtx.ProjectPointOnEdge(aP1, aE2, aT2);
226       if (!bIsDone) {
227         return bIsDone;
228       }
229       //
230       GEOMAlgo_Tools::PointOnEdge(aE2, aT2, aP2);
231     }
232       break;
233       //
234     case TopAbs_FACE: {
235       const TopoDS_Face& aF2=TopoDS::Face(aS);
236       GeomAPI_ProjectPointOnSurf& aProj=aCtx.ProjPS(aF2);
237       //
238       aProj.Perform(aP1);
239       bIsDone=aProj.IsDone();
240       if (!bIsDone) {
241         return bIsDone;
242       }
243       //
244       aP2=aProj.NearestPoint(); 
245     }
246       break;
247       //  
248     default:
249       break; // Err
250   }
251   return bIsDone;
252 }
253 //=======================================================================
254 //function : PointOnShape
255 //purpose  : 
256 //=======================================================================
257 void GEOMAlgo_Tools::PointOnShape(const TopoDS_Shape& aS,
258                                   gp_Pnt& aP3D)
259 {
260   TopAbs_ShapeEnum aType;
261   //
262   aP3D.SetCoord(99.,99.,99.);
263   aType=aS.ShapeType();
264   switch(aType) {
265     case TopAbs_EDGE: {
266       const TopoDS_Edge& aE=TopoDS::Edge(aS);
267       GEOMAlgo_Tools::PointOnEdge(aE, aP3D);
268       }
269       break;
270       //
271     case TopAbs_FACE: {
272       const TopoDS_Face& aF=TopoDS::Face(aS);
273       GEOMAlgo_Tools::PointOnFace(aF, aP3D);
274       }
275       break;
276       //  
277     default:
278       break; // Err
279   }
280 }
281 //=======================================================================
282 //function : PointOnFace
283 //purpose  : 
284 //=======================================================================
285 void GEOMAlgo_Tools::PointOnFace(const TopoDS_Face& aF,
286                                  gp_Pnt& aP3D)
287 {
288   Standard_Real aU, aV, aUMin, aUMax, aVMin, aVMax;
289   //
290   BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
291   //
292   aU=BOPTools_Tools2D::IntermediatePoint(aUMin, aUMax); 
293   aV=BOPTools_Tools2D::IntermediatePoint(aVMin, aVMax); 
294   //
295   GEOMAlgo_Tools::PointOnFace(aF, aU, aV, aP3D);
296 }
297 //=======================================================================
298 //function : PointOnFace
299 //purpose  : 
300 //=======================================================================
301 void GEOMAlgo_Tools::PointOnFace(const TopoDS_Face& aF,
302                                  const Standard_Real aU,
303                                  const Standard_Real aV,
304                                  gp_Pnt& aP3D)
305 {
306   Handle(Geom_Surface) aS;
307   //
308   aS=BRep_Tool::Surface(aF);
309   aS->D0(aU, aV, aP3D);
310 }
311 //=======================================================================
312 //function : PointOnEdge
313 //purpose  : 
314 //=======================================================================
315 void GEOMAlgo_Tools::PointOnEdge(const TopoDS_Edge& aE,
316                                  gp_Pnt& aP3D)
317 {
318   Standard_Real aTx, aT1, aT2;
319   //
320   BRep_Tool::Curve(aE, aT1, aT2);
321   aTx=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
322   GEOMAlgo_Tools::PointOnEdge(aE, aTx, aP3D);
323 }
324 //=======================================================================
325 //function : PointOnEdge
326 //purpose  : 
327 //=======================================================================
328 void GEOMAlgo_Tools::PointOnEdge(const TopoDS_Edge& aE,
329                                  const Standard_Real aT,
330                                  gp_Pnt& aP3D)
331 {
332   Standard_Real aT1, aT2;
333   Handle(Geom_Curve) aC3D;
334   //
335   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
336   aC3D->D0(aT, aP3D);
337 }
338 //=======================================================================
339 //function : RefinePCurveForEdgeOnFace
340 //purpose  : 
341 //=======================================================================
342 void GEOMAlgo_Tools::RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE,
343                                                const TopoDS_Face& aF,
344                                                const Standard_Real aUMin, 
345                                                const Standard_Real aUMax) 
346 {
347   Standard_Real aT1, aT2, aTx, aUx, aTol, aTwoPI;
348   gp_Pnt2d aP2D;
349   Handle(Geom_Surface) aS;
350   Handle(Geom2d_Curve) aC2D;
351   BRep_Builder aBB;
352   //
353   aTwoPI=PI+PI;
354   //
355   aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
356   if (!aC2D.IsNull()) {
357     if (BRep_Tool::IsClosed(aE, aF)) {
358       return;
359     }
360     aTx=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
361     aC2D->D0(aTx, aP2D);
362     aUx=aP2D.X();
363     if (aUx < aUMin || aUx > aUMax) {
364       // need to rebuild
365       Handle(Geom2d_Curve) aC2Dx;
366       //
367       aTol=BRep_Tool::Tolerance(aE);
368       aBB.UpdateEdge(aE, aC2Dx, aF, aTol); 
369     }
370   }
371 }
372 //=======================================================================
373 //function : IsUPeriodic
374 //purpose  : 
375 //=======================================================================
376 Standard_Boolean GEOMAlgo_Tools::IsUPeriodic(const  Handle(Geom_Surface) &aS)
377 {
378   Standard_Boolean bRet;
379   GeomAbs_SurfaceType aType;
380   GeomAdaptor_Surface aGAS;
381   //
382   aGAS.Load(aS);
383   aType=aGAS.GetType();
384   bRet=(aType==GeomAbs_Cylinder||
385         aType==GeomAbs_Cone ||
386         aType==GeomAbs_Sphere);
387   //
388   return bRet;
389 }