Salome HOME
Copyrights update 2015.
[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     for (i=0; i<4; ++i) {
420       j=(i==3) ? 0 : i+1;
421       aDot=aDx[i]*aDx[j];
422       if (fabs (aDot) > myTolerance) {
423         aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
424         return;
425       }
426     }
427     //
428     // rectangle
429     aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
430     //
431     // shift location to the center and calc. sizes
432     aXYZc.SetCoord(0.,0.,0.);
433     TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
434     for (i=1; i<=aNbV; ++i) {
435       const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
436       aP=BRep_Tool::Pnt(aV);
437       const gp_XYZ& aXYZ=aP.XYZ();
438       aXYZc=aXYZc+aXYZ;
439     }
440     //
441     // Location : aPc in center of rectangle
442     // Position : 0z is plane normal
443     //            0x is along length
444     //
445     aXYZc.Divide(4.);
446     aPc.SetXYZ(aXYZc);
447     //
448     gp_Lin aL0(aPx[0], aDx[0]);
449     gp_Lin aL1(aPx[1], aDx[1]);
450     //
451     aD0=aL0.Distance(aPc);
452     aD1=aL1.Distance(aPc);
453     //
454     aLength=aD0;
455     aWidth =aD1;
456     aDX=aL1.Direction();
457     if (aD0<aD1) {
458       aLength=aD1;
459       aWidth =aD0;
460       aDX=aL0.Direction();
461     }
462     //
463     aLength=2.*aLength;
464     aWidth =2.*aWidth;
465     //
466     aInfo.SetLocation(aPc);
467     aInfo.SetLength(aLength);
468     aInfo.SetWidth(aWidth);
469     //
470     const gp_Dir& aDZ=aPln.Axis().Direction();
471     gp_Ax2 aAx2(aPc, aDZ, aDX);
472     gp_Ax3 aAx3(aAx2);
473     aInfo.SetPosition(aAx3);
474   }
475
476   return;
477 }
478 //=======================================================================
479 //function : FillDetails
480 //purpose  :
481 //=======================================================================
482 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
483                                            const gp_Sphere& )
484 {
485   Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
486   TopoDS_Edge aE;
487   TopExp_Explorer aExp;
488   TopTools_MapOfShape aM;
489   GEOMAlgo_KindOfShape aKS, aKSE;
490   //
491   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
492   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
493   //
494   aKS=aInfo.KindOfShape();
495   if (aKS!=GEOMAlgo_KS_SPHERE) {
496     return;
497   }
498   //
499   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
500   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
501   if (!(aNbV==2 && aNbE==3)) {
502     return;
503   }
504   //
505   aNbSE=0;
506   aNbDE=0;
507   aExp.Init(aF, TopAbs_EDGE);
508   for (; aExp.More(); aExp.Next()) {
509     aE=TopoDS::Edge(aExp.Current());
510     if(aM.Add(aE)) {
511       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
512       aKSE=aInfoE.KindOfShape();
513       //
514       if (BRep_Tool::IsClosed(aE, aF)) {
515         ++aNbSE;
516       }
517       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
518         ++aNbDE;
519       }
520     }
521   }
522   //
523   if (!(aNbSE==1 && aNbDE==2)) {
524     return;
525   }
526   aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
527 }
528 //=======================================================================
529 //function : FillDetails
530 //purpose  :
531 //=======================================================================
532 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
533                                            const gp_Cone& )//aCone)
534 {
535   Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
536   Standard_Real aR[3], aHeight;
537   gp_Pnt aPC[3], aPD, aPc, aPX[3];
538   TopoDS_Vertex aVD;
539   TopoDS_Edge aE;
540   TopoDS_Iterator aIt;
541   TopExp_Explorer aExp;
542   TopTools_MapOfShape aM;
543   GEOMAlgo_KindOfShape aKS, aKSE;
544   GEOMAlgo_KindOfName aKN, aKNE;
545   GEOMAlgo_KindOfClosed aKCE;
546   //
547   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
548   aKN=GEOMAlgo_KN_UNKNOWN;
549   aInfo.SetKindOfName(aKN);
550   //
551   aKS=aInfo.KindOfShape();
552   if (aKS!=GEOMAlgo_KS_CONE) {
553     return;
554   }
555   //
556   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
557     return;
558   }
559   //
560   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
561   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
562   if (!(aNbV==2 && aNbE==3)) {
563     return;
564   }
565   //
566   i=0;
567   aNbCE=0;
568   aNbSE=0;
569   aNbDE=0;
570   aExp.Init(aF, TopAbs_EDGE);
571   for (; aExp.More(); aExp.Next()) {
572     aE=TopoDS::Edge(aExp.Current());
573     if(aM.Add(aE)) {
574       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
575       aKNE=aInfoE.KindOfName();
576       aKCE=aInfoE.KindOfClosed();
577       aKSE=aInfoE.KindOfShape();
578       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
579         aPC[i]=aInfoE.Location();
580         aR[i]=aInfoE.Radius1();
581         //
582         aIt.Initialize(aE);
583         for (; aIt.More(); aIt.Next()) {
584           aVD=TopoDS::Vertex(aIt.Value());
585           break;
586         }
587         aPX[i]=BRep_Tool::Pnt(aVD);
588         //
589         ++i;
590         ++aNbCE;
591       }
592       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
593         if (BRep_Tool::IsClosed(aE, aF)) {
594           ++aNbSE;
595         }
596       }
597       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
598         aIt.Initialize(aE);
599         for (; aIt.More(); aIt.Next()) {
600           aVD=TopoDS::Vertex(aIt.Value());
601           break;
602         }
603         //
604         aPD=BRep_Tool::Pnt(aVD);
605         //
606         ++aNbDE;
607       }
608     }
609   }
610   //
611   if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
612     return;
613   }
614   //
615   if (aNbDE==1) {
616     aPC[1]=aPD;
617     aR[1]=0.;
618   }
619   //
620   aHeight=aPC[0].Distance(aPC[1]);
621   //
622   Standard_Real aRmin, aRmax;
623   gp_Ax2 aAx2new;
624   //
625   if (aR[0]>aR[1]) {
626     aRmin=aR[1];
627     aRmax=aR[0];
628     aPc=aPC[0];
629     gp_Vec aVz(aPC[0], aPC[1]);
630     gp_Vec aVx(aPC[0], aPX[0]);
631     gp_Dir aDz(aVz);
632     gp_Dir aDx(aVx);
633     gp_Ax2 aAx2(aPc, aDz, aDx);
634     aAx2new=aAx2;
635   }
636   else {
637     aRmin=aR[0];
638     aRmax=aR[1];
639     aPc=aPC[1];
640     gp_Vec aVz(aPC[1], aPC[0]);
641     gp_Vec aVx(aPC[1], aPX[1]);
642     gp_Dir aDz(aVz);
643     gp_Dir aDx(aVx);
644     gp_Ax2 aAx2(aPc, aDz, aDx);
645     aAx2new=aAx2;
646   }
647   //
648   gp_Ax3 aAx3(aAx2new);
649   aInfo.SetLocation(aPc);
650   aInfo.SetPosition(aAx3);
651   aInfo.SetRadius1(aRmax);
652   aInfo.SetRadius2(aRmin);
653   aInfo.SetHeight(aHeight);
654   //
655   aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
656 }
657 //=======================================================================
658 //function : FillDetails
659 //purpose  :
660 //=======================================================================
661 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
662                                            const gp_Cylinder& aCyl)
663 {
664   Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
665   Standard_Real aT0, aT1, aHeight;
666   gp_Pnt aPC[3], aPc;
667   TopoDS_Edge aE;
668   TopExp_Explorer aExp;
669   TopTools_MapOfShape aM;
670   GEOMAlgo_KindOfShape aKS;
671   GEOMAlgo_KindOfName aKN, aKNE;
672   GEOMAlgo_KindOfClosed aKCE;
673   //
674   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
675   aKN=GEOMAlgo_KN_UNKNOWN;
676   aInfo.SetKindOfName(aKN);
677   //
678   aKS=aInfo.KindOfShape();
679   if (aKS!=GEOMAlgo_KS_CYLINDER) {
680     return;
681   }
682   //
683   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
684     return;
685   }
686   //
687   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
688   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
689   if (!(aNbV==2 && aNbE==3)) {
690     return;
691   }
692   //
693   i=0;
694   aNbCE=0;
695   aNbSE=0;
696   aExp.Init(aF, TopAbs_EDGE);
697   for (; aExp.More(); aExp.Next()) {
698     aE=TopoDS::Edge(aExp.Current());
699     if(aM.Add(aE)) {
700       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
701       aKNE=aInfoE.KindOfName();
702       aKCE=aInfoE.KindOfClosed();
703       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
704         aPC[aNbCE]=aInfoE.Location();
705         ++aNbCE;
706       }
707       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
708         if (BRep_Tool::IsClosed(aE, aF)) {
709           ++aNbSE;
710         }
711       }
712     }
713   }
714   //
715   if (!(aNbCE==2 && aNbSE==1)) {
716     return;
717   }
718   //
719   const gp_Ax1& aAx1=aCyl.Axis();
720   const gp_Dir& aDir=aAx1.Direction();
721   const gp_Pnt& aPLoc=aAx1.Location();
722   gp_Lin aLin(aPLoc, aDir);
723   //
724   aT0=ElCLib::Parameter(aLin, aPC[0]);
725   aT1=ElCLib::Parameter(aLin, aPC[1]);
726   //
727   aPc=aPC[0];;
728   if (aT0>aT1) {
729     aPc=aPC[1];
730   }
731   aHeight=aPC[0].Distance(aPC[1]);
732   //
733   gp_Ax3 aAx3=aCyl.Position();
734   aAx3.SetLocation(aPc);
735   //
736   aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
737   aInfo.SetPosition(aAx3);
738   aInfo.SetLocation(aPc);
739   aInfo.SetHeight(aHeight);
740 }
741
742 //=======================================================================
743 //function : FillDetails
744 //purpose  :
745 //=======================================================================
746 void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
747                                            const gp_Torus& )
748 {
749   Standard_Integer aNbV, aNbE, aNbSE;
750   TopoDS_Edge aE;
751   TopExp_Explorer aExp;
752   TopTools_MapOfShape aM;
753   GEOMAlgo_KindOfShape aKS;
754   //
755   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
756   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
757   //
758   aKS=aInfo.KindOfShape();
759   if (aKS!=GEOMAlgo_KS_TORUS) {
760     return;
761   }
762   //
763   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
764   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
765   if (!(aNbV==1 && aNbE==2)) {
766     return;
767   }
768   //
769   aNbSE=0;
770   aExp.Init(aF, TopAbs_EDGE);
771   for (; aExp.More(); aExp.Next()) {
772     aE=TopoDS::Edge(aExp.Current());
773     if (aM.Add(aE)) {
774       if (BRep_Tool::IsClosed(aE, aF)) {
775         ++aNbSE;
776       }
777     }
778   }
779   //
780   if (aNbSE!=2) {
781     return;
782   }
783   aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);
784 }
785 //modified by NIZNHY-PKV Tue Jul 03 13:29:41 2012f
786 //=======================================================================
787 //function : TreatStepSphere
788 //purpose  :
789 //=======================================================================
790 Standard_Boolean
791   GEOMAlgo_ShapeInfoFiller::TreatStepSphere(const TopoDS_Solid& aSd)
792 {
793   Standard_Boolean bRet, bIsAllowedType, bOnlyClosed, bIsEqual;
794   Standard_Integer j;
795   Standard_Real aTolAng, aTolLin;
796   Standard_Real aVolume, aVolumeS, dV, aArea, aAreaS, dA;
797   gp_Sphere aSphere[2];
798   GeomAbs_SurfaceType aST;
799   Handle(Geom_Surface) aS;
800   GeomAdaptor_Surface aGAS;
801   TopExp_Explorer aExp;
802   //
803   bRet=Standard_False;
804   aTolLin=Precision::Confusion();
805   aTolAng=Precision::Angular();
806   //
807   aExp.Init(aSd, TopAbs_FACE);
808   for (j=0; aExp.More(); aExp.Next(), ++j) {
809     const TopoDS_Face& aF=*((TopoDS_Face*)&aExp.Current());
810     aS=BRep_Tool::Surface(aF);
811     aGAS.Load(aS);
812     aST=aGAS.GetType();
813     bIsAllowedType=GEOMAlgo_ShapeInfoFiller::IsAllowedType(aST);
814     if (!bIsAllowedType) {
815       return bRet;
816     }
817     //
818     if (aST!=GeomAbs_Sphere) {
819       return bRet;
820     }
821     //
822     aSphere[j]=aGAS.Sphere();
823   }
824   //
825   bIsEqual=IsEqual(aSphere[0], aSphere[1], aTolLin);
826   if (!bIsEqual) {
827     return bRet;
828   }
829   //
830   //--------------------------------
831   GProp_GProps aGProps;
832   //
833   bOnlyClosed=Standard_False;
834   //
835   aVolume=aSphere[0].Volume();
836   //
837   BRepGProp::VolumeProperties(aSd, aGProps,  bOnlyClosed);
838   aVolumeS=aGProps.Mass();
839   if (aVolumeS<0.) {
840     aVolumeS=-aVolumeS;
841   }
842   //
843   dV=fabs(aVolumeS-aVolume);
844   if (dV>aTolLin) {
845     return bRet;
846   }
847   //--------------------------------
848   aArea=aSphere[0].Area();
849   //
850   BRepGProp::SurfaceProperties(aSd, aGProps);
851   aAreaS=aGProps.Mass();
852   //
853   dA=fabs(aAreaS-aArea);
854   if (dA>aTolLin) {
855     return bRet;
856   }
857   //
858   //--------------------------------
859   gp_Pnt aP0;
860   gp_Ax3 aAx3;
861   Standard_Real aR1;
862   //
863   aP0=aSphere[0].Location();
864   aAx3=aSphere[0].Position();
865   aR1=aSphere[0].Radius();
866   //
867   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
868   //
869   aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
870   aInfo.SetLocation(aP0);
871   aInfo.SetPosition(aAx3);
872   aInfo.SetRadius1(aR1);
873   //
874   return !bRet;// true
875 }
876 //=======================================================================
877 //function : IsEqual
878 //purpose  :
879 //=======================================================================
880 Standard_Boolean IsEqual(const gp_Sphere& aSp1,
881                          const gp_Sphere& aSp2,
882                          const Standard_Real aTolLin)
883 {
884   Standard_Boolean bRet;
885   Standard_Real aR1, aR2, aD2;
886   //
887   bRet=Standard_False;
888   aR1=aSp1.Radius();
889   aR2=aSp2.Radius();
890   if (fabs(aR1-aR2)>aTolLin) {
891     return bRet;
892   }
893   //
894   const gp_Pnt& aPC1=aSp1.Position().Location();
895   const gp_Pnt& aPC2=aSp2.Position().Location();
896   //
897   aD2=aPC1.SquareDistance(aPC2);
898   bRet=(aD2<aTolLin*aTolLin);
899   //
900   return bRet;
901 }
902 //modified by NIZNHY-PKV Tue Jul 03 13:29:43 2012t