Salome HOME
Porting to OCCT development version: Standard_PI -> M_PI
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Tools.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 // File:        GEOMAlgo_Tools.cxx
23 // Created:     Mon Dec  6 11:35:29 2004
24 // Author:      Peter KURNEV
25
26 #include <GEOMAlgo_Tools.ixx>
27
28 #include <gp_Pnt.hxx>
29 #include <gp_Pnt2d.hxx>
30
31 #include <Geom_Surface.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom2d_Curve.hxx>
34 #include <GeomAdaptor_Surface.hxx>
35
36 #include <GeomAPI_ProjectPointOnSurf.hxx>
37
38 #include <TopAbs_ShapeEnum.hxx>
39
40 #include <TopoDS.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Iterator.hxx>
44
45 #include <TopTools_ListOfShape.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <TopTools_IndexedMapOfShape.hxx>
48
49 #include <BRep_Tool.hxx>
50 #include <BRep_Builder.hxx>
51 #include <BRepTools.hxx>
52
53 #include <BOPTools_Tools2D.hxx>
54 #include <IntTools_Context.hxx>
55
56 #include <GEOMAlgo_PassKeyShape.hxx>//qft
57 #include <GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx>//qft
58
59 static 
60   void GetCount(const TopoDS_Shape& aS,
61                 Standard_Integer& iCnt);
62
63 //=======================================================================
64 //function : IsCompositeShape
65 //purpose  : 
66 //=======================================================================
67 Standard_Boolean GEOMAlgo_Tools::IsCompositeShape(const TopoDS_Shape& aS)
68 {
69   Standard_Boolean bRet;
70   Standard_Integer iCnt;
71   TopoDS_Iterator aIt;
72   //
73   iCnt=0;
74   GetCount(aS, iCnt);
75   bRet=(iCnt>1);
76   //
77   return bRet;
78 }
79
80 //=======================================================================
81 //function : GetCount
82 //purpose  : 
83 //=======================================================================
84 void GetCount(const TopoDS_Shape& aS,
85               Standard_Integer& iCnt)
86 {
87   TopoDS_Iterator aIt;
88   TopAbs_ShapeEnum aTS;
89   //
90   aTS=aS.ShapeType();
91   //
92   if (aTS==TopAbs_SHAPE) {
93     return;
94   }
95   if (aTS!=TopAbs_COMPOUND) {
96     ++iCnt;
97     return;
98   }
99   //
100   aIt.Initialize(aS);
101   for (; aIt.More(); aIt.Next()) {
102     const TopoDS_Shape& aSx=aIt.Value();
103     GetCount(aSx, iCnt); 
104   }
105 }
106
107 //=======================================================================
108 //function : RefineSDShapes
109 //purpose  : 
110 //=======================================================================
111   Standard_Integer GEOMAlgo_Tools::RefineSDShapes(GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape& aMPKLE,
112                                                   const Standard_Real aTol,
113                                                   IntTools_Context& aCtx)
114 {
115   Standard_Integer i, aNbE, iErr, j, aNbEE, aNbToAdd;
116   TopTools_IndexedDataMapOfShapeListOfShape aMEE, aMSDE, aMEToAdd;
117   //
118   iErr=1;
119   //
120   aNbE=aMPKLE.Extent();
121   for (i=1; i<=aNbE; ++i) {
122     TopTools_ListOfShape& aLSDE=aMPKLE.ChangeFromIndex(i);
123     //
124     aMEE.Clear();
125     iErr=GEOMAlgo_Tools::FindSDShapes(aLSDE, aTol, aMEE, aCtx);
126     if (iErr) {
127       return iErr;
128     }
129     //
130     aNbEE=aMEE.Extent();
131     if (aNbEE==1) {
132       continue;  // nothing to do 
133     }
134     //
135     for (j=1; j<=aNbEE; ++j) {
136       TopTools_ListOfShape& aLEE=aMEE.ChangeFromIndex(j);
137       //
138       if (j==1) {
139         aLSDE.Clear();
140         aLSDE.Append(aLEE);
141       }
142       else {
143         const TopoDS_Shape& aE1=aLEE.First();
144         aMEToAdd.Add(aE1, aLEE);
145       }
146     }
147   }
148   //
149   aNbToAdd=aMEToAdd.Extent();
150   if (!aNbToAdd) {
151     return aNbToAdd;
152   }
153   //
154   for (i=1; i<=aNbToAdd; ++i) {
155     GEOMAlgo_PassKeyShape aPKE1;
156     //
157     const TopoDS_Shape& aE1=aMEToAdd.FindKey(i);
158     const TopTools_ListOfShape& aLE=aMEToAdd(i);
159     //
160     //qf
161     //aPKE1.SetIds(aE1);
162     aPKE1.SetShapes(aE1);
163     //qt
164     aMPKLE.Add(aPKE1, aLE);
165   }
166   //
167   return 0;
168 }
169 //=======================================================================
170 //function : FindSDShapes
171 //purpose  : 
172 //=======================================================================
173 Standard_Integer GEOMAlgo_Tools::FindSDShapes(const TopTools_ListOfShape& aLE,
174                                               const Standard_Real aTol,
175                                               TopTools_IndexedDataMapOfShapeListOfShape& aMEE,
176                                               IntTools_Context& aCtx)
177 {
178   Standard_Integer aNbE, aNbEProcessed, aNbESD, iErr;
179   TopTools_ListOfShape aLESD;
180   TopTools_ListIteratorOfListOfShape aIt, aIt1;
181   TopTools_IndexedMapOfShape aMProcessed;
182   TopAbs_ShapeEnum aType;
183   //
184   aNbE=aLE.Extent();
185   if (!aNbE) {
186     return 3; // Err
187   } 
188   //modified by NIZNHY-PKV Thu Dec 30 10:56:52 2004 f
189   if (aNbE==1) {
190     return 0; // Nothing to do
191   } 
192   //modified by NIZNHY-PKV Thu Dec 30 10:56:56 2004 t
193   //
194   while(1) {
195     aNbEProcessed=aMProcessed.Extent();
196     if (aNbEProcessed==aNbE) {
197       break;
198     }
199     //
200     aIt.Initialize(aLE);
201     for (; aIt.More(); aIt.Next()) {
202       const TopoDS_Shape& aS=aIt.Value();
203       //
204       if (aMProcessed.Contains(aS)) {
205         continue;
206       }
207       //
208       //modified by NIZNHY-PKV Thu Dec 30 10:57:01 2004 f
209       aType=aS.ShapeType();
210       if (aType==TopAbs_EDGE) {
211         const TopoDS_Edge& aE=TopoDS::Edge(aS);
212         if (BRep_Tool::Degenerated(aE)) {
213           aMProcessed.Add(aE);
214           continue;
215         }
216       }
217       //modified by NIZNHY-PKV Thu Dec 30 10:57:03 2004 t
218       //
219       aLESD.Clear();
220       iErr=GEOMAlgo_Tools::FindSDShapes(aS, aLE, aTol, aLESD, aCtx);
221       if (iErr) {
222         return 2; // Err
223       }
224       //
225       aNbESD=aLESD.Extent();
226       if (!aNbESD) {
227         return 1; // Err
228       }
229       //
230       aMEE.Add(aS, aLESD);
231       //
232       aIt1.Initialize(aLESD);
233       for (; aIt1.More(); aIt1.Next()) {
234         const TopoDS_Shape& aE1=aIt1.Value();
235         aMProcessed.Add(aE1);
236       }
237     }
238   }
239   return 0;
240 }
241 //=======================================================================
242 //function : FindSDShapes
243 //purpose  : 
244 //=======================================================================
245 Standard_Integer GEOMAlgo_Tools::FindSDShapes(const TopoDS_Shape& aE1,
246                                               const TopTools_ListOfShape& aLE,
247                                               const Standard_Real aTol,
248                                               TopTools_ListOfShape& aLESD,
249                                               IntTools_Context& aCtx)
250 {
251   Standard_Boolean bIsDone;
252   Standard_Real aTol2, aD2;
253   gp_Pnt aP1, aP2;
254   TopTools_ListIteratorOfListOfShape aIt;
255   //
256   aTol2=aTol*aTol;
257   GEOMAlgo_Tools::PointOnShape(aE1, aP1);
258   //
259   aIt.Initialize(aLE);
260   for (; aIt.More(); aIt.Next()) {
261     const TopoDS_Shape& aE2=aIt.Value();
262     if (aE2.IsSame(aE1)) {
263        aLESD.Append(aE2);
264     }
265     else {
266       bIsDone=GEOMAlgo_Tools::ProjectPointOnShape(aP1, aE2, aP2, aCtx);
267       if (!bIsDone) {
268         //return 1; 
269         continue; // jfa BUG 20361
270       }
271       aD2=aP1.SquareDistance(aP2);
272       if(aD2<aTol2) {
273         aLESD.Append(aE2);
274       }
275     }
276   }
277   return 0;
278 }
279
280 //=======================================================================
281 //function : ProjectPointOnShape
282 //purpose  : 
283 //=======================================================================
284 Standard_Boolean GEOMAlgo_Tools::ProjectPointOnShape(const gp_Pnt& aP1,
285                                                      const TopoDS_Shape& aS,
286                                                      gp_Pnt& aP2,
287                                                      IntTools_Context& aCtx)
288 {
289   Standard_Boolean bIsDone = Standard_False;
290   Standard_Real aT2;
291   TopAbs_ShapeEnum aType;
292   //
293   aType = aS.ShapeType();
294   switch (aType)
295     {
296     case TopAbs_EDGE:
297       {
298         const TopoDS_Edge& aE2 = TopoDS::Edge(aS);
299         //
300         if (BRep_Tool::Degenerated(aE2)) { // jfa
301           return Standard_True;
302         }
303         else {
304           Standard_Real f, l;
305           Handle(Geom_Curve) aC3D = BRep_Tool::Curve (aE2, f, l);
306           if (aC3D.IsNull()) {
307             return Standard_True;
308           }
309           bIsDone = aCtx.ProjectPointOnEdge(aP1, aE2, aT2);
310         }
311         if (!bIsDone) {
312           return bIsDone;
313         }
314         //
315         GEOMAlgo_Tools::PointOnEdge(aE2, aT2, aP2);
316       }
317       break;
318       //
319     case TopAbs_FACE:
320       {
321         const TopoDS_Face& aF2 = TopoDS::Face(aS);
322         GeomAPI_ProjectPointOnSurf& aProj = aCtx.ProjPS(aF2);
323         //
324         aProj.Perform(aP1);
325         bIsDone = aProj.IsDone();
326         if (!bIsDone) {
327           return bIsDone;
328         }
329         //
330         aP2 = aProj.NearestPoint(); 
331       }
332       break;
333       //  
334     default:
335       break; // Err
336     }
337   return bIsDone;
338 }
339 //=======================================================================
340 //function : PointOnShape
341 //purpose  : 
342 //=======================================================================
343 void GEOMAlgo_Tools::PointOnShape(const TopoDS_Shape& aS,
344                                   gp_Pnt& aP3D)
345 {
346   TopAbs_ShapeEnum aType;
347   //
348   aP3D.SetCoord(99.,99.,99.);
349   aType=aS.ShapeType();
350   switch(aType) {
351     case TopAbs_EDGE: {
352       const TopoDS_Edge& aE=TopoDS::Edge(aS);
353       GEOMAlgo_Tools::PointOnEdge(aE, aP3D);
354       }
355       break;
356       //
357     case TopAbs_FACE: {
358       const TopoDS_Face& aF=TopoDS::Face(aS);
359       GEOMAlgo_Tools::PointOnFace(aF, aP3D);
360       }
361       break;
362       //  
363     default:
364       break; // Err
365   }
366 }
367 //=======================================================================
368 //function : PointOnFace
369 //purpose  : 
370 //=======================================================================
371 void GEOMAlgo_Tools::PointOnFace(const TopoDS_Face& aF,
372                                  gp_Pnt& aP3D)
373 {
374   Standard_Real aU, aV, aUMin, aUMax, aVMin, aVMax;
375   //
376   BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
377   //
378   aU=BOPTools_Tools2D::IntermediatePoint(aUMin, aUMax); 
379   aV=BOPTools_Tools2D::IntermediatePoint(aVMin, aVMax); 
380   //
381   GEOMAlgo_Tools::PointOnFace(aF, aU, aV, aP3D);
382 }
383 //=======================================================================
384 //function : PointOnFace
385 //purpose  : 
386 //=======================================================================
387 void GEOMAlgo_Tools::PointOnFace(const TopoDS_Face& aF,
388                                  const Standard_Real aU,
389                                  const Standard_Real aV,
390                                  gp_Pnt& aP3D)
391 {
392   Handle(Geom_Surface) aS;
393   //
394   aS=BRep_Tool::Surface(aF);
395   aS->D0(aU, aV, aP3D);
396 }
397 //=======================================================================
398 //function : PointOnEdge
399 //purpose  : 
400 //=======================================================================
401 void GEOMAlgo_Tools::PointOnEdge(const TopoDS_Edge& aE,
402                                  gp_Pnt& aP3D)
403 {
404   Standard_Real aTx, aT1, aT2;
405   //
406   BRep_Tool::Curve(aE, aT1, aT2);
407   aTx=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
408   GEOMAlgo_Tools::PointOnEdge(aE, aTx, aP3D);
409 }
410 //=======================================================================
411 //function : PointOnEdge
412 //purpose  : 
413 //=======================================================================
414 void GEOMAlgo_Tools::PointOnEdge(const TopoDS_Edge& aE,
415                                  const Standard_Real aT,
416                                  gp_Pnt& aP3D)
417 {
418   Standard_Real aT1, aT2;
419   Handle(Geom_Curve) aC3D;
420   //
421   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
422   aC3D->D0(aT, aP3D);
423 }
424 //=======================================================================
425 //function : RefinePCurveForEdgeOnFace
426 //purpose  : 
427 //=======================================================================
428 void GEOMAlgo_Tools::RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE,
429                                                const TopoDS_Face& aF,
430                                                const Standard_Real aUMin, 
431                                                const Standard_Real aUMax) 
432 {
433   Standard_Real aT1, aT2, aTx, aUx, aTol;
434   gp_Pnt2d aP2D;
435   Handle(Geom_Surface) aS;
436   Handle(Geom2d_Curve) aC2D;
437   BRep_Builder aBB;
438   //
439   aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
440   if (!aC2D.IsNull()) {
441     if (BRep_Tool::IsClosed(aE, aF)) {
442       return;
443     }
444     aTx=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
445     aC2D->D0(aTx, aP2D);
446     aUx=aP2D.X();
447     if (aUx < aUMin || aUx > aUMax) {
448       // need to rebuild
449       Handle(Geom2d_Curve) aC2Dx;
450       //
451       aTol=BRep_Tool::Tolerance(aE);
452       aBB.UpdateEdge(aE, aC2Dx, aF, aTol); 
453     }
454   }
455 }
456 //=======================================================================
457 //function : IsUPeriodic
458 //purpose  : 
459 //=======================================================================
460 Standard_Boolean GEOMAlgo_Tools::IsUPeriodic(const  Handle(Geom_Surface) &aS)
461 {
462   Standard_Boolean bRet;
463   GeomAbs_SurfaceType aType;
464   GeomAdaptor_Surface aGAS;
465   //
466   aGAS.Load(aS);
467   aType=aGAS.GetType();
468   bRet=(aType==GeomAbs_Cylinder||
469         aType==GeomAbs_Cone ||
470         aType==GeomAbs_Sphere);
471   //
472   return bRet;
473 }