]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMAlgo/GEOMAlgo_ShapeInfoFiller_1.cxx
Salome HOME
Fix for test case geom/bugs_05/F7
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_ShapeInfoFiller_1.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
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
20 #include <GEOMAlgo_ShapeInfoFiller.hxx>
21
22 #include <Precision.hxx>
23 #include <TColStd_MapOfInteger.hxx>
24 #include <TColStd_IndexedMapOfInteger.hxx>
25
26 #include <gp_Lin.hxx>
27 #include <gp_XYZ.hxx>
28 #include <gp_Ax1.hxx>
29 #include <gp_Dir.hxx>
30 #include <gp_Vec.hxx>
31 #include <gp_Ax2.hxx>
32 #include <gp_Ax3.hxx>
33
34 #include <ElCLib.hxx>
35
36 #include <GeomAdaptor_Surface.hxx>
37
38 #include <TopoDS.hxx>
39 #include <TopoDS_Vertex.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Wire.hxx>
42 #include <TopoDS_Face.hxx>
43 #include <TopoDS_Iterator.hxx>
44
45 #include <BRep_Tool.hxx>
46
47 #include <TopExp.hxx>
48 #include <TopExp_Explorer.hxx>
49
50 #include <TopTools_MapOfShape.hxx>
51 #include <TopTools_IndexedMapOfShape.hxx>
52
53 #include <BRepTools_WireExplorer.hxx>
54 #include <BRepGProp.hxx>
55 #include <GProp_GProps.hxx>
56
57 #include <GEOMAlgo_ShapeInfo.hxx>
58
59 static
60   Standard_Boolean IsEqual(const gp_Sphere& aSp1,
61                            const gp_Sphere& aSp2,
62                            const Standard_Real aTolDst);
63
64 //=======================================================================
65 //function : FillDetails
66 //purpose  :
67 //=======================================================================
68 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd)
69 {
70   Standard_Boolean bIsStepSphere;
71   Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX;
72   TopoDS_Shape aFCyl, aFCon;
73   TopTools_IndexedMapOfShape aMF;
74   GEOMAlgo_KindOfName aKNF;
75   //
76   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
77   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
78   //
79   TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
80   //
81   aNbF=aMF.Extent();
82   if (!aNbF) {
83     return;
84   }
85   //
86   if (aNbF==1) {
87     const TopoDS_Shape& aF=aMF(1);
88     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
89     aKNF=aInfoF.KindOfName(); // mb: sphere, torus
90     if (aKNF==GEOMAlgo_KN_SPHERE ||
91         aKNF==GEOMAlgo_KN_TORUS) {
92       aInfo.SetKindOfName(aKNF);
93       aInfo.SetLocation(aInfoF.Location());
94       aInfo.SetPosition(aInfoF.Position());
95       aInfo.SetRadius1(aInfoF.Radius1());
96       if(aKNF==GEOMAlgo_KN_TORUS) {
97         aInfo.SetRadius2(aInfoF.Radius2());
98       }
99       return;
100     }
101   }
102   //modified by NIZNHY-PKV Tue Jul 03 13:23:55 2012f
103   else if (aNbF==2) {
104     // specific solid that should be treated as a sphere
105     bIsStepSphere=TreatStepSphere(aSd);
106     if (bIsStepSphere) {
107       return;
108     }
109   }
110   //modified by NIZNHY-PKV Tue Jul 03 13:23:57 2012t
111   //
112   aNbCyl=0;
113   aNbCon=0;
114   aNbPgn=0;
115   aNbRct=0;
116   aNbCrc=0;
117   for (i=1; i<=aNbF; ++i) {
118     const TopoDS_Shape& aF=aMF(i);
119     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
120     aKNF=aInfoF.KindOfName();
121     if (aKNF==GEOMAlgo_KN_CYLINDER) {
122       aFCyl=aF;
123       ++aNbCyl;
124     }
125     else if (aKNF==GEOMAlgo_KN_CONE) {
126       aFCon=aF;
127       ++aNbCon;
128     }
129     else if (aKNF==GEOMAlgo_KN_DISKCIRCLE) {
130       ++aNbCrc;
131     }
132     else if (aKNF==GEOMAlgo_KN_POLYGON ||
133              aKNF==GEOMAlgo_KN_TRIANGLE ||
134              aKNF==GEOMAlgo_KN_QUADRANGLE) {
135       ++aNbPgn;
136     }
137     else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
138       ++aNbPgn;
139       ++aNbRct;
140     }
141   }
142   //
143   aNbX=aNbCyl+aNbCrc;
144   if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
145     // cylinder (as they understand it)
146     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
147     aKNF=aInfoF.KindOfName();
148     aInfo.SetKindOfName(aKNF);
149     aInfo.SetLocation(aInfoF.Location());
150     aInfo.SetPosition(aInfoF.Position());
151     aInfo.SetRadius1(aInfoF.Radius1());
152     aInfo.SetHeight(aInfoF.Height());
153     return;
154   }
155   //
156   aNbX=aNbCon+aNbCrc;
157   if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
158     // cone
159     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
160     aKNF=aInfoF.KindOfName();
161     aInfo.SetKindOfName(aKNF);
162     aInfo.SetLocation(aInfoF.Location());
163     aInfo.SetPosition(aInfoF.Position());
164     aInfo.SetRadius1(aInfoF.Radius1());
165     aInfo.SetRadius2(aInfoF.Radius2());
166     aInfo.SetHeight(aInfoF.Height());
167     return;
168   }
169   //
170   if (aNbF!=aNbPgn) {
171     return;// -> GEOMAlgo_KN_UNKNOWN
172   }
173   if (aNbPgn!=6) {
174     aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
175     return;
176   }
177   // aNbPgn==6
178   if (aNbPgn!=aNbRct) {
179     aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
180     return;
181   }
182   //===================================================
183   // aNbRct=6;
184   // box
185   Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
186   Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
187   Standard_Real aDistMin, aDistMax;
188   gp_Pnt aPi, aPc;
189   gp_Dir aDir[3];
190   gp_XYZ aXYZc;
191   TColStd_IndexedMapOfInteger aMp;
192   TopTools_IndexedMapOfShape aMV, aMFi;
193   //
194   // barycenter aPc
195   TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
196   aNbV=aMV.Extent();
197   if (aNbV!=8) {
198     return;
199   }
200   //
201   aXYZc.SetCoord(0.,0.,0.);
202   for (i=1; i<=aNbV; ++i) {
203     const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
204     aPi=BRep_Tool::Pnt(aVi);
205     const gp_XYZ& aXYZ=aPi.XYZ();
206     aXYZc=aXYZc+aXYZ;
207   }
208   //
209   aXYZc.Divide(aNbV);
210   aPc.SetXYZ(aXYZc);
211   //
212   // 3 faces
213   for (i=1; i<=aNbF; ++i) {
214     if (aMp.Contains(i)) {
215       continue;
216     }
217     //
218     const TopoDS_Shape& aFi=aMF(i);
219     const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
220     const gp_Dir& aDNi=aIFi.Position().Direction();
221     //
222     for (j=i+1; j<=aNbF; ++j) {
223       if (aMp.Contains(j)) {
224         continue;
225       }
226       //
227       const TopoDS_Shape& aFj=aMF(j);
228       const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
229       const gp_Dir& aDNj=aIFj.Position().Direction();
230       //
231       aDot=aDNi*aDNj;
232       //modified by NIZNHY-PKV Tue Jul 03 10:01:56 2012f
233       if (aDot<0.) {
234         aDot=-aDot;
235       }
236       //modified by NIZNHY-PKV Tue Jul 03 10:01:52 2012t
237       if (fabs(1.-aDot)<0.0001) {
238         aMp.Add(i);
239         aMp.Add(j);
240         aMFi.Add(aFi);
241         break;
242       }
243       //
244     }
245   }
246   aNbFi=aMFi.Extent();
247   if (aNbFi!=3) {
248     return;
249   }
250   //
251   aDistMin=1.e15;
252   aDistMax=-aDistMin;
253   for (i=0; i<aNbFi; ++i) {
254     const TopoDS_Shape& aFi=aMFi(i+1);
255     const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
256     aPi=aIFi.Location();
257     aDist[i]=aPc.Distance(aPi);
258     if (aDist[i]>aDistMax) {
259       aDistMax=aDist[i];
260       iMax=i;
261     }
262     if (aDist[i]<aDistMin) {
263       aDistMin=aDist[i];
264       iMin=i;
265     }
266     gp_Vec aVi(aPc, aPi);
267     gp_Dir aDi(aVi);
268     aDir[i]=aDi;
269   }
270   //
271   if (iMax==iMin) {
272     iMax=0;
273     iMin=1;
274   }
275   iMid=3-iMax-iMin;
276   //
277   aLength=2.*aDist[iMax];
278   aWidth=2.*aDist[iMid];
279   aHeight=2.*aDist[iMin];
280   //
281   gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
282   gp_Ax3 aAx3(aAx2);
283   //
284   aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
285   aInfo.SetLocation(aPc);
286   aInfo.SetLength(aLength);
287   aInfo.SetWidth(aWidth);
288   aInfo.SetHeight(aHeight);
289   aInfo.SetPosition(aAx3);
290 }
291 //=======================================================================
292 //function : FillDetails
293 //purpose  :
294 //=======================================================================
295 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
296                                            const gp_Pln& aPln)
297 {
298   Standard_Integer aNbV, aNbE, i, j;
299   Standard_Real aDot, aD0, aD1, aLength, aWidth;
300   gp_Dir aDx[4], aDX;
301   gp_Pnt aPx[4], aP, aPc;
302   gp_XYZ aXYZc;
303   TopExp_Explorer aExp;
304   TopoDS_Shape aE;
305   TopoDS_Wire aW;
306   TopoDS_Edge aEx;
307   TopoDS_Iterator aIt;
308   TopTools_IndexedMapOfShape aMV;
309   BRepTools_WireExplorer aWExp;
310   GEOMAlgo_KindOfName aKN, aKNE;
311   GEOMAlgo_KindOfShape aKS;
312   //
313   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
314   aKN=GEOMAlgo_KN_UNKNOWN;
315   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
316   //
317   aKS=aInfo.KindOfShape();
318   if (aKS!=GEOMAlgo_KS_PLANE) {
319     return;
320   }
321   //
322   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
323     aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
324     return;
325   }
326   //
327   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
328   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
329   //
330   // 1. may be it is circle/ellipse
331   if (aNbV==1 && aNbE==1) {
332     aExp.Init(aF, TopAbs_EDGE);
333     for (; aExp.More(); aExp.Next()) {
334       aE=aExp.Current();
335       break;
336     }
337     //
338     const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
339     aKNE=aInfoE.KindOfName();
340     if (aKNE==GEOMAlgo_KN_CIRCLE) {
341       aKN=GEOMAlgo_KN_DISKCIRCLE;
342       aInfo.SetKindOfName(aKN);
343       aInfo.SetRadius1(aInfoE.Radius1());
344       aInfo.SetLocation(aInfoE.Location());
345       aInfo.SetPosition(aInfoE.Position());
346     }
347     if (aKNE==GEOMAlgo_KN_ELLIPSE) {
348       aKN=GEOMAlgo_KN_DISKELLIPSE;
349       aInfo.SetKindOfName(aKN);
350       aInfo.SetRadius1(aInfoE.Radius1());
351       aInfo.SetRadius2(aInfoE.Radius2());
352       aInfo.SetLocation(aInfoE.Location());
353       aInfo.SetPosition(aInfoE.Position());
354     }
355   }
356   //
357   // 2. may be it is rectangle
358   else  {
359     aExp.Init(aF, TopAbs_EDGE);
360     for (; aExp.More(); aExp.Next()) {
361       aE=aExp.Current();
362       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
363       aKNE=aInfoE.KindOfName();
364       if (aKNE!=GEOMAlgo_KN_SEGMENT) {
365         return;
366       }
367     }
368     //
369     aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
370     //
371     if (aNbV==3 && aNbE==3) {
372       aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
373       //
374       aXYZc.SetCoord(0.,0.,0.);
375       TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
376       for (i=1; i<=aNbV; ++i) {
377         const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
378         aP=BRep_Tool::Pnt(aV);
379         const gp_XYZ& aXYZ=aP.XYZ();
380         aXYZc=aXYZc+aXYZ;
381         aPx[i-1]=aP;
382       }
383       aXYZc.Divide(3.);
384       //
385       aPc.SetXYZ(aXYZc);
386       gp_Vec aVX(aPc, aPx[0]);
387       aVX.Normalize();
388       aDX.SetXYZ(aVX.XYZ());
389       const gp_Dir& aDZ=aPln.Axis().Direction();
390       //
391       gp_Ax2 aAx2(aPc, aDZ, aDX);
392       gp_Ax3 aAx3(aAx2);
393       //
394       aInfo.SetLocation(aPc);
395       aInfo.SetPosition(aAx3);
396       //
397       return;
398     }
399     //
400     if (!(aNbV==4 && aNbE==4)) {
401       return;
402     }
403     //
404     // aNbV==4 && aNbE==4 and all edges are segments
405     aIt.Initialize(aF);
406     for (; aIt.More(); aIt.Next()){
407       aW=TopoDS::Wire(aIt.Value());
408       break;
409     }
410     //
411     aWExp.Init(aW, aF);
412     for (i=0; aWExp.More(); aWExp.Next(), ++i) {
413       aEx=aWExp.Current();
414       const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
415       aDx[i]=aInfoEx.Direction();
416       aPx[i]=aInfoEx.Location();
417     }
418     //
419     Standard_Boolean isRectangle = Standard_True;
420     for (i=0; i<4; ++i) {
421       j=(i==3) ? 0 : i+1;
422       aDot=aDx[i]*aDx[j];
423       if (fabs (aDot) > myTolerance) {
424         isRectangle = Standard_False;
425         break;
426       }
427     }
428     //
429     // rectangle
430     // shift location to the center
431     aXYZc.SetCoord(0.,0.,0.);
432     TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
433     for (i=1; i<=aNbV; ++i) {
434       const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
435       aP=BRep_Tool::Pnt(aV);
436       const gp_XYZ& aXYZ=aP.XYZ();
437       aXYZc=aXYZc+aXYZ;
438     }
439     //
440     // Location : aPc in center of rectangle
441     // Position : 0z is plane normal
442     //            0x is along the first edge (quadrangle) or
443     //            along length (rectangle)
444     //
445     aXYZc.Divide(4.);
446     aPc.SetXYZ(aXYZc);
447     aDX=aDx[0];
448     aInfo.SetLocation(aPc);
449
450     if (isRectangle) {
451       // Calculate sizes
452       gp_Lin aL0(aPx[0], aDx[0]);
453       gp_Lin aL1(aPx[1], aDx[1]);
454       //
455       aD0=aL0.Distance(aPc);
456       aD1=aL1.Distance(aPc);
457       //
458       aLength=aD1;
459       aWidth =aD0;
460
461       if (aD0>aD1) {
462         aLength=aD0;
463         aWidth =aD1;
464         aDX=aDx[1];
465       }
466       //
467       aLength=2.*aLength;
468       aWidth =2.*aWidth;
469       //
470       aInfo.SetLength(aLength);
471       aInfo.SetWidth(aWidth);
472       aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
473     } else {
474       aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
475     }
476     //
477     const gp_Dir& aDZ=aPln.Axis().Direction();
478     gp_Ax2 aAx2(aPc, aDZ, aDX);
479     gp_Ax3 aAx3(aAx2);
480     aInfo.SetPosition(aAx3);
481   }
482
483   return;
484 }
485 //=======================================================================
486 //function : FillDetails
487 //purpose  :
488 //=======================================================================
489 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
490                                            const gp_Sphere& )
491 {
492   Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
493   TopoDS_Edge aE;
494   TopExp_Explorer aExp;
495   TopTools_MapOfShape aM;
496   GEOMAlgo_KindOfShape aKS, aKSE;
497   //
498   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
499   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
500   //
501   aKS=aInfo.KindOfShape();
502   if (aKS!=GEOMAlgo_KS_SPHERE) {
503     return;
504   }
505   //
506   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
507   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
508   if (!(aNbV==2 && aNbE==3)) {
509     return;
510   }
511   //
512   aNbSE=0;
513   aNbDE=0;
514   aExp.Init(aF, TopAbs_EDGE);
515   for (; aExp.More(); aExp.Next()) {
516     aE=TopoDS::Edge(aExp.Current());
517     if(aM.Add(aE)) {
518       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
519       aKSE=aInfoE.KindOfShape();
520       //
521       if (BRep_Tool::IsClosed(aE, aF)) {
522         ++aNbSE;
523       }
524       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
525         ++aNbDE;
526       }
527     }
528   }
529   //
530   if (!(aNbSE==1 && aNbDE==2)) {
531     return;
532   }
533   aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
534 }
535 //=======================================================================
536 //function : FillDetails
537 //purpose  :
538 //=======================================================================
539 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
540                                            const gp_Cone& )//aCone)
541 {
542   Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
543   Standard_Real aR[3], aHeight;
544   gp_Pnt aPC[3], aPD, aPc, aPX[3];
545   TopoDS_Vertex aVD;
546   TopoDS_Edge aE;
547   TopoDS_Iterator aIt;
548   TopExp_Explorer aExp;
549   TopTools_MapOfShape aM;
550   GEOMAlgo_KindOfShape aKS, aKSE;
551   GEOMAlgo_KindOfName aKN, aKNE;
552   GEOMAlgo_KindOfClosed aKCE;
553   //
554   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
555   aKN=GEOMAlgo_KN_UNKNOWN;
556   aInfo.SetKindOfName(aKN);
557   //
558   aKS=aInfo.KindOfShape();
559   if (aKS!=GEOMAlgo_KS_CONE) {
560     return;
561   }
562   //
563   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
564     return;
565   }
566   //
567   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
568   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
569   if (!(aNbV==2 && aNbE==3)) {
570     return;
571   }
572   //
573   i=0;
574   aNbCE=0;
575   aNbSE=0;
576   aNbDE=0;
577   aExp.Init(aF, TopAbs_EDGE);
578   for (; aExp.More(); aExp.Next()) {
579     aE=TopoDS::Edge(aExp.Current());
580     if(aM.Add(aE)) {
581       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
582       aKNE=aInfoE.KindOfName();
583       aKCE=aInfoE.KindOfClosed();
584       aKSE=aInfoE.KindOfShape();
585       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
586         aPC[i]=aInfoE.Location();
587         aR[i]=aInfoE.Radius1();
588         //
589         aIt.Initialize(aE);
590         for (; aIt.More(); aIt.Next()) {
591           aVD=TopoDS::Vertex(aIt.Value());
592           break;
593         }
594         aPX[i]=BRep_Tool::Pnt(aVD);
595         //
596         ++i;
597         ++aNbCE;
598       }
599       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
600         if (BRep_Tool::IsClosed(aE, aF)) {
601           ++aNbSE;
602         }
603       }
604       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
605         aIt.Initialize(aE);
606         for (; aIt.More(); aIt.Next()) {
607           aVD=TopoDS::Vertex(aIt.Value());
608           break;
609         }
610         //
611         aPD=BRep_Tool::Pnt(aVD);
612         //
613         ++aNbDE;
614       }
615     }
616   }
617   //
618   if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
619     return;
620   }
621   //
622   if (aNbDE==1) {
623     aPC[1]=aPD;
624     aR[1]=0.;
625   }
626   //
627   aHeight=aPC[0].Distance(aPC[1]);
628   //
629   Standard_Real aRmin, aRmax;
630   gp_Ax2 aAx2new;
631   //
632   if (aR[0]>aR[1]) {
633     aRmin=aR[1];
634     aRmax=aR[0];
635     aPc=aPC[0];
636     gp_Vec aVz(aPC[0], aPC[1]);
637     gp_Vec aVx(aPC[0], aPX[0]);
638     gp_Dir aDz(aVz);
639     gp_Dir aDx(aVx);
640     gp_Ax2 aAx2(aPc, aDz, aDx);
641     aAx2new=aAx2;
642   }
643   else {
644     aRmin=aR[0];
645     aRmax=aR[1];
646     aPc=aPC[1];
647     gp_Vec aVz(aPC[1], aPC[0]);
648     gp_Vec aVx(aPC[1], aPX[1]);
649     gp_Dir aDz(aVz);
650     gp_Dir aDx(aVx);
651     gp_Ax2 aAx2(aPc, aDz, aDx);
652     aAx2new=aAx2;
653   }
654   //
655   gp_Ax3 aAx3(aAx2new);
656   aInfo.SetLocation(aPc);
657   aInfo.SetPosition(aAx3);
658   aInfo.SetRadius1(aRmax);
659   aInfo.SetRadius2(aRmin);
660   aInfo.SetHeight(aHeight);
661   //
662   aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
663 }
664 //=======================================================================
665 //function : FillDetails
666 //purpose  :
667 //=======================================================================
668 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
669                                            const gp_Cylinder& aCyl)
670 {
671   Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
672   Standard_Real aT0, aT1, aHeight;
673   gp_Pnt aPC[3], aPc;
674   TopoDS_Edge aE;
675   TopExp_Explorer aExp;
676   TopTools_MapOfShape aM;
677   GEOMAlgo_KindOfShape aKS;
678   GEOMAlgo_KindOfName aKN, aKNE;
679   GEOMAlgo_KindOfClosed aKCE;
680   //
681   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
682   aKN=GEOMAlgo_KN_UNKNOWN;
683   aInfo.SetKindOfName(aKN);
684   //
685   aKS=aInfo.KindOfShape();
686   if (aKS!=GEOMAlgo_KS_CYLINDER) {
687     return;
688   }
689   //
690   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
691     return;
692   }
693   //
694   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
695   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
696   if (!(aNbV==2 && aNbE==3)) {
697     return;
698   }
699   //
700   i=0;
701   aNbCE=0;
702   aNbSE=0;
703   aExp.Init(aF, TopAbs_EDGE);
704   for (; aExp.More(); aExp.Next()) {
705     aE=TopoDS::Edge(aExp.Current());
706     if(aM.Add(aE)) {
707       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
708       aKNE=aInfoE.KindOfName();
709       aKCE=aInfoE.KindOfClosed();
710       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
711         aPC[aNbCE]=aInfoE.Location();
712         ++aNbCE;
713       }
714       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
715         if (BRep_Tool::IsClosed(aE, aF)) {
716           ++aNbSE;
717         }
718       }
719     }
720   }
721   //
722   if (!(aNbCE==2 && aNbSE==1)) {
723     return;
724   }
725   //
726   const gp_Ax1& aAx1=aCyl.Axis();
727   const gp_Dir& aDir=aAx1.Direction();
728   const gp_Pnt& aPLoc=aAx1.Location();
729   gp_Lin aLin(aPLoc, aDir);
730   //
731   aT0=ElCLib::Parameter(aLin, aPC[0]);
732   aT1=ElCLib::Parameter(aLin, aPC[1]);
733   //
734   aPc=aPC[0];;
735   if (aT0>aT1) {
736     aPc=aPC[1];
737   }
738   aHeight=aPC[0].Distance(aPC[1]);
739   //
740   gp_Ax3 aAx3=aCyl.Position();
741   aAx3.SetLocation(aPc);
742   //
743   aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
744   aInfo.SetPosition(aAx3);
745   aInfo.SetLocation(aPc);
746   aInfo.SetHeight(aHeight);
747 }
748
749 //=======================================================================
750 //function : FillDetails
751 //purpose  :
752 //=======================================================================
753 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
754                                            const gp_Torus& )
755 {
756   Standard_Integer aNbV, aNbE, aNbSE;
757   TopoDS_Edge aE;
758   TopExp_Explorer aExp;
759   TopTools_MapOfShape aM;
760   GEOMAlgo_KindOfShape aKS;
761   //
762   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
763   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
764   //
765   aKS=aInfo.KindOfShape();
766   if (aKS!=GEOMAlgo_KS_TORUS) {
767     return;
768   }
769   //
770   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
771   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
772   if (!(aNbV==1 && aNbE==2)) {
773     return;
774   }
775   //
776   aNbSE=0;
777   aExp.Init(aF, TopAbs_EDGE);
778   for (; aExp.More(); aExp.Next()) {
779     aE=TopoDS::Edge(aExp.Current());
780     if (aM.Add(aE)) {
781       if (BRep_Tool::IsClosed(aE, aF)) {
782         ++aNbSE;
783       }
784     }
785   }
786   //
787   if (aNbSE!=2) {
788     return;
789   }
790   aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);
791 }
792 //modified by NIZNHY-PKV Tue Jul 03 13:29:41 2012f
793 //=======================================================================
794 //function : TreatStepSphere
795 //purpose  :
796 //=======================================================================
797 Standard_Boolean
798   GEOMAlgo_ShapeInfoFiller::TreatStepSphere(const TopoDS_Solid& aSd)
799 {
800   Standard_Boolean bRet, bIsAllowedType, bOnlyClosed, bIsEqual;
801   Standard_Integer j;
802   Standard_Real aTolAng, aTolLin;
803   Standard_Real aVolume, aVolumeS, dV, aArea, aAreaS, dA;
804   gp_Sphere aSphere[2];
805   GeomAbs_SurfaceType aST;
806   Handle(Geom_Surface) aS;
807   GeomAdaptor_Surface aGAS;
808   TopExp_Explorer aExp;
809   //
810   bRet=Standard_False;
811   aTolLin=Precision::Confusion();
812   aTolAng=Precision::Angular();
813   //
814   aExp.Init(aSd, TopAbs_FACE);
815   for (j=0; aExp.More(); aExp.Next(), ++j) {
816     const TopoDS_Face& aF=*((TopoDS_Face*)&aExp.Current());
817     aS=BRep_Tool::Surface(aF);
818     aGAS.Load(aS);
819     aST=aGAS.GetType();
820     bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aST);
821     if (!bIsAllowedType) {
822       return bRet;
823     }
824     //
825     if (aST!=GeomAbs_Sphere) {
826       return bRet;
827     }
828     //
829     aSphere[j]=aGAS.Sphere();
830   }
831   //
832   bIsEqual=IsEqual(aSphere[0], aSphere[1], aTolLin);
833   if (!bIsEqual) {
834     return bRet;
835   }
836   //
837   //--------------------------------
838   GProp_GProps aGProps;
839   //
840   bOnlyClosed=Standard_False;
841   //
842   aVolume=aSphere[0].Volume();
843   //
844   BRepGProp::VolumeProperties(aSd, aGProps,  bOnlyClosed);
845   aVolumeS=aGProps.Mass();
846   if (aVolumeS<0.) {
847     aVolumeS=-aVolumeS;
848   }
849   //
850   dV=fabs(aVolumeS-aVolume);
851   if (dV>aTolLin) {
852     return bRet;
853   }
854   //--------------------------------
855   aArea=aSphere[0].Area();
856   //
857   BRepGProp::SurfaceProperties(aSd, aGProps);
858   aAreaS=aGProps.Mass();
859   //
860   dA=fabs(aAreaS-aArea);
861   if (dA>aTolLin) {
862     return bRet;
863   }
864   //
865   //--------------------------------
866   gp_Pnt aP0;
867   gp_Ax3 aAx3;
868   Standard_Real aR1;
869   //
870   aP0=aSphere[0].Location();
871   aAx3=aSphere[0].Position();
872   aR1=aSphere[0].Radius();
873   //
874   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
875   //
876   aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
877   aInfo.SetLocation(aP0);
878   aInfo.SetPosition(aAx3);
879   aInfo.SetRadius1(aR1);
880   //
881   return !bRet;// true
882 }
883 //=======================================================================
884 //function : IsEqual
885 //purpose  :
886 //=======================================================================
887 Standard_Boolean IsEqual(const gp_Sphere& aSp1,
888                          const gp_Sphere& aSp2,
889                          const Standard_Real aTolLin)
890 {
891   Standard_Boolean bRet;
892   Standard_Real aR1, aR2, aD2;
893   //
894   bRet=Standard_False;
895   aR1=aSp1.Radius();
896   aR2=aSp2.Radius();
897   if (fabs(aR1-aR2)>aTolLin) {
898     return bRet;
899   }
900   //
901   const gp_Pnt& aPC1=aSp1.Position().Location();
902   const gp_Pnt& aPC2=aSp2.Position().Location();
903   //
904   aD2=aPC1.SquareDistance(aPC2);
905   bRet=(aD2<aTolLin*aTolLin);
906   //
907   return bRet;
908 }
909 //modified by NIZNHY-PKV Tue Jul 03 13:29:43 2012t