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