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