Salome HOME
891b9c772b682e590f15cc4fccc6f64f0abe3b05
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_ShapeInfoFiller_1.cxx
1 #include <GEOMAlgo_ShapeInfoFiller.ixx>
2
3 #include <Precision.hxx>
4
5 #include <gp_Lin.hxx>
6 #include <gp_XYZ.hxx>
7 #include <gp_Ax1.hxx>
8 #include <gp_Dir.hxx>
9 #include <gp_Vec.hxx>
10 #include <gp_Ax2.hxx>
11 #include <gp_Ax3.hxx>
12
13 #include <ElCLib.hxx>
14
15 #include <TopoDS.hxx>
16 #include <TopoDS_Vertex.hxx>
17 #include <TopoDS_Edge.hxx>
18 #include <TopoDS_Wire.hxx>
19 #include <TopoDS_Face.hxx>
20 #include <TopoDS_Iterator.hxx>
21
22 #include <BRep_Tool.hxx>
23
24 #include <TopExp.hxx>
25 #include <TopExp_Explorer.hxx>
26
27 #include <TopTools_MapOfShape.hxx>
28 #include <TopTools_IndexedMapOfShape.hxx>
29 #include <BRepTools_WireExplorer.hxx>
30
31 #include <GEOMAlgo_ShapeInfo.hxx>
32 #include <TColStd_MapOfInteger.hxx>
33 #include <TColStd_IndexedMapOfInteger.hxx>
34
35 //=======================================================================
36 //function : FillDetails
37 //purpose  : 
38 //=======================================================================
39   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd)
40 {
41   Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX;
42   TopoDS_Shape aFCyl, aFCon;
43   TopTools_IndexedMapOfShape aMF;
44   GEOMAlgo_KindOfName aKNF;
45   //
46   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
47   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
48   //
49   TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
50   //
51   aNbF=aMF.Extent();
52   if (!aNbF) {
53     return;
54   }
55   //
56   if (aNbF==1) {
57     const TopoDS_Shape& aF=aMF(1);
58     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
59     aKNF=aInfoF.KindOfName(); // mb: sphere, torus
60     if (aKNF==GEOMAlgo_KN_SPHERE ||
61         aKNF==GEOMAlgo_KN_TORUS) {
62       aInfo.SetKindOfName(aKNF);
63       aInfo.SetLocation(aInfoF.Location());
64       aInfo.SetPosition(aInfoF.Position());
65       aInfo.SetRadius1(aInfoF.Radius1());
66       if(aKNF==GEOMAlgo_KN_TORUS) {
67         aInfo.SetRadius2(aInfoF.Radius2());
68       }
69       return;
70     }
71   }
72   //
73   aNbCyl=0;
74   aNbCon=0;
75   aNbPgn=0;
76   aNbRct=0;
77   aNbCrc=0;
78   for (i=1; i<=aNbF; ++i) {
79     const TopoDS_Shape& aF=aMF(i);
80     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
81     aKNF=aInfoF.KindOfName(); 
82     if (aKNF==GEOMAlgo_KN_CYLINDER) {
83       aFCyl=aF;
84       ++aNbCyl;
85     }
86     else if (aKNF==GEOMAlgo_KN_CONE) {
87       aFCon=aF;
88       ++aNbCon;
89     }
90     else if (aKNF==GEOMAlgo_KN_DISKCIRCLE) {
91       ++aNbCrc;
92     }
93     else if (aKNF==GEOMAlgo_KN_POLYGON ||
94             aKNF==GEOMAlgo_KN_TRIANGLE ||
95             aKNF==GEOMAlgo_KN_QUADRANGLE) {
96       ++aNbPgn;
97       
98     } 
99     else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
100       ++aNbPgn;
101       ++aNbRct;
102     }
103   }
104   //
105   aNbX=aNbCyl+aNbCrc;
106   if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
107     // cylinder (as they understand it)
108     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
109     aKNF=aInfoF.KindOfName(); 
110     aInfo.SetKindOfName(aKNF);
111     aInfo.SetLocation(aInfoF.Location());
112     aInfo.SetPosition(aInfoF.Position());
113     aInfo.SetRadius1(aInfoF.Radius1());
114     aInfo.SetHeight(aInfoF.Height());
115     return;
116   }
117   //
118   aNbX=aNbCon+aNbCrc;
119   if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
120     // cone
121     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
122     aKNF=aInfoF.KindOfName(); 
123     aInfo.SetKindOfName(aKNF);
124     aInfo.SetLocation(aInfoF.Location());
125     aInfo.SetPosition(aInfoF.Position());
126     aInfo.SetRadius1(aInfoF.Radius1());
127     aInfo.SetRadius2(aInfoF.Radius2());
128     aInfo.SetHeight(aInfoF.Height());
129     return;
130   }
131   //
132   if (aNbPgn!=6) {
133     aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
134     return;
135   }
136   if (aNbPgn!=aNbRct) {
137     aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
138     return;
139   }
140   //===================================================
141   // aNbRct=6;
142   // box
143   Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
144   Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
145   Standard_Real aDistMin, aDistMax;
146   gp_Pnt aPi, aPc;
147   gp_Dir aDir[3];
148   gp_XYZ aXYZc;
149   TColStd_IndexedMapOfInteger aMp;
150   TopTools_IndexedMapOfShape aMV, aMFi;
151   //
152   // barycenter aPc
153   TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
154   aNbV=aMV.Extent();
155   if (aNbV!=8) {
156     return;
157   }
158   //
159   aXYZc.SetCoord(0.,0.,0.);
160   for (i=1; i<=aNbV; ++i) {
161     const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
162     aPi=BRep_Tool::Pnt(aVi);
163     const gp_XYZ& aXYZ=aPi.XYZ();
164     aXYZc=aXYZc+aXYZ;
165   }
166   //
167   aXYZc.Divide(aNbV);
168   aPc.SetXYZ(aXYZc);
169   //
170   // 3 faces
171   for (i=1; i<=aNbF; ++i) {
172     if (aMp.Contains(i)) {
173       continue;
174     }
175     //
176     const TopoDS_Shape& aFi=aMF(i);
177     const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
178     const gp_Dir& aDNi=aIFi.Position().Direction();
179     //
180     for (j=i+1; j<=aNbF; ++j) {
181       if (aMp.Contains(j)) {
182         continue;
183       }
184       //
185       const TopoDS_Shape& aFj=aMF(j);
186       const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
187       const gp_Dir& aDNj=aIFj.Position().Direction();
188       //
189       aDot=aDNi*aDNj;
190       if (fabs(1.-aDot)<0.0001) {
191         aMp.Add(i);
192         aMp.Add(j);
193         aMFi.Add(aFi);
194         break;
195       }
196       //
197     }
198   }
199   aNbFi=aMFi.Extent();
200   if (aNbFi!=3) {
201     return;
202   }
203   //
204   aDistMin=1.e15;
205   aDistMax=-aDistMin;
206   for (i=0; i<aNbFi; ++i) {
207     const TopoDS_Shape& aFi=aMFi(i+1);
208     const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
209     aPi=aIFi.Location();
210     aDist[i]=aPc.Distance(aPi);
211     if (aDist[i]>aDistMax) {
212       aDistMax=aDist[i];
213       iMax=i;
214     }
215     if (aDist[i]<aDistMin) {
216       aDistMin=aDist[i];
217       iMin=i;
218     }
219     gp_Vec aVi(aPc, aPi);
220     gp_Dir aDi(aVi);
221     aDir[i]=aDi;
222   }
223   //
224   if (iMax==iMin) {
225     iMax=0;
226     iMin=1;
227   }
228   iMid=3-iMax-iMin;
229   //
230   aLength=2.*aDist[iMax];
231   aWidth=2.*aDist[iMid];
232   aHeight=2.*aDist[iMin];
233   //
234   gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
235   gp_Ax3 aAx3(aAx2);
236   //
237   aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
238   aInfo.SetLocation(aPc);
239   aInfo.SetLength(aLength);
240   aInfo.SetWidth(aWidth);
241   aInfo.SetHeight(aHeight);
242   aInfo.SetPosition(aAx3);
243 }
244 //=======================================================================
245 //function : FillDetails
246 //purpose  : 
247 //=======================================================================
248   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
249                                              const gp_Pln& aPln)
250 {
251   Standard_Integer aNbV, aNbE, i, j;
252   Standard_Real aDot, aD0, aD1, aLength, aWidth;
253   gp_Dir aDx[4], aDX;
254   gp_Pnt aPx[4], aP, aPc;
255   gp_XYZ aXYZc;
256   TopExp_Explorer aExp;
257   TopoDS_Shape aE;
258   TopoDS_Wire aW;
259   TopoDS_Edge aEx;
260   TopoDS_Iterator aIt;
261   TopTools_IndexedMapOfShape aMV;
262   BRepTools_WireExplorer aWExp;
263   GEOMAlgo_KindOfName aKN, aKNE;
264   GEOMAlgo_KindOfShape aKS;
265   //
266   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
267   aKN=GEOMAlgo_KN_UNKNOWN;
268   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
269   //
270   aKS=aInfo.KindOfShape();
271   if (aKS!=GEOMAlgo_KS_PLANE) {
272     return;
273   }
274   //
275   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
276     aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
277     return;
278   }
279   //
280   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
281   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
282   //
283   // 1. may be it is circle/ellipse
284   if (aNbV==1 && aNbE==1) {
285     aExp.Init(aF, TopAbs_EDGE);
286     for (; aExp.More(); aExp.Next()) {
287       aE=aExp.Current();
288       break;
289     }
290     //
291     const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
292     aKNE=aInfoE.KindOfName();
293     if (aKNE==GEOMAlgo_KN_CIRCLE) {
294       aKN=GEOMAlgo_KN_DISKCIRCLE;
295       aInfo.SetKindOfName(aKN);
296       aInfo.SetRadius1(aInfoE.Radius1());
297       aInfo.SetLocation(aInfoE.Location());
298       aInfo.SetPosition(aInfoE.Position());
299     }
300     if (aKNE==GEOMAlgo_KN_ELLIPSE) {
301       aKN=GEOMAlgo_KN_DISKELLIPSE;
302       aInfo.SetKindOfName(aKN);
303       aInfo.SetRadius1(aInfoE.Radius1());
304       aInfo.SetRadius2(aInfoE.Radius2());
305       aInfo.SetLocation(aInfoE.Location());
306       aInfo.SetPosition(aInfoE.Position());
307     }
308   }
309   //
310   // 2. may be it is rectangle
311   else  {
312     aExp.Init(aF, TopAbs_EDGE);
313     for (; aExp.More(); aExp.Next()) {
314       aE=aExp.Current();
315       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
316       aKNE=aInfoE.KindOfName();
317       if (aKNE!=GEOMAlgo_KN_SEGMENT) {
318         return;
319       }
320     }
321     //
322     aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
323     //
324     if (aNbV==3 && aNbE==3) {
325       aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
326       //
327       aXYZc.SetCoord(0.,0.,0.);
328       TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
329       for (i=1; i<=aNbV; ++i) {
330         const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
331         aP=BRep_Tool::Pnt(aV);
332         const gp_XYZ& aXYZ=aP.XYZ();
333         aXYZc=aXYZc+aXYZ;
334         aPx[i-1]=aP;
335       }
336       aXYZc.Divide(3.);
337       //
338       aPc.SetXYZ(aXYZc);
339       gp_Vec aVX(aPc, aPx[0]);
340       aVX.Normalize();
341       aDX.SetXYZ(aVX.XYZ());
342       const gp_Dir& aDZ=aPln.Axis().Direction();
343       //
344       gp_Ax2 aAx2(aPc, aDZ, aDX);
345       gp_Ax3 aAx3(aAx2);
346       //
347       aInfo.SetLocation(aPc);
348       aInfo.SetPosition(aAx3);
349       //
350       return;
351     }
352     //
353     if (!(aNbV==4 && aNbE==4)) {
354       return;
355     }
356     //
357     // aNbV==4 && aNbE==4 and all edges are segments
358     aIt.Initialize(aF);
359     for (; aIt.More(); aIt.Next()){
360       aW=TopoDS::Wire(aIt.Value());
361       break;
362     }
363     //
364     aWExp.Init(aW, aF);
365     for (i=0; aWExp.More(); aWExp.Next(), ++i) {
366       aEx=aWExp.Current();
367       const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
368       aDx[i]=aInfoEx.Direction();
369       aPx[i]=aInfoEx.Location();
370     }
371     //
372     for (i=0; i<4; ++i) {
373       j=(i==3) ? 0 : i+1;
374       aDot=aDx[i]*aDx[j];
375       if (fabs (aDot) > myTolerance) {
376         aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
377         return;
378       }
379     }
380     //
381     // rectangle 
382     aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
383     //
384     // shift location to the center and calc. sizes
385     aXYZc.SetCoord(0.,0.,0.);
386     TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
387     for (i=1; i<=aNbV; ++i) {
388       const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
389       aP=BRep_Tool::Pnt(aV);
390       const gp_XYZ& aXYZ=aP.XYZ();
391       aXYZc=aXYZc+aXYZ;
392     }
393     //
394     // Location : aPc in center of rectangle
395     // Position : 0z is plane normal
396     //            0x is along length
397     //
398     aXYZc.Divide(4.);
399     aPc.SetXYZ(aXYZc);
400     //
401     gp_Lin aL0(aPx[0], aDx[0]);
402     gp_Lin aL1(aPx[1], aDx[1]);
403     //
404     aD0=aL0.Distance(aPc);
405     aD1=aL1.Distance(aPc);
406     //
407     aLength=aD0;
408     aWidth =aD1;
409     aDX=aL1.Direction();
410     if (aD0<aD1) {
411       aLength=aD1;
412       aWidth =aD0;
413       aDX=aL0.Direction();
414     }
415     //
416     aLength=2.*aLength;
417     aWidth =2.*aWidth;
418     //
419     aInfo.SetLocation(aPc);
420     aInfo.SetLength(aLength);
421     aInfo.SetWidth(aWidth);
422     //
423     const gp_Dir& aDZ=aPln.Axis().Direction();
424     gp_Ax2 aAx2(aPc, aDZ, aDX);
425     gp_Ax3 aAx3(aAx2);
426     aInfo.SetPosition(aAx3);
427   }
428   
429   return;
430 }
431 //=======================================================================
432 //function : FillDetails
433 //purpose  : 
434 //=======================================================================
435   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
436                                              const gp_Sphere& )
437 {
438   Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
439   TopoDS_Edge aE; 
440   TopExp_Explorer aExp;
441   TopTools_MapOfShape aM; 
442   GEOMAlgo_KindOfShape aKS, aKSE;
443   //
444   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
445   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
446   //
447   aKS=aInfo.KindOfShape();
448   if (aKS!=GEOMAlgo_KS_SPHERE) {
449     return;
450   }
451   //
452   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
453   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
454   if (!(aNbV==2 && aNbE==3)) {
455     return;
456   }
457   //
458   aNbSE=0;
459   aNbDE=0;
460   aExp.Init(aF, TopAbs_EDGE);
461   for (; aExp.More(); aExp.Next()) {
462     aE=TopoDS::Edge(aExp.Current());
463     if(aM.Add(aE)) {
464       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
465       aKSE=aInfoE.KindOfShape();
466       //
467       if (BRep_Tool::IsClosed(aE, aF)) {
468         ++aNbSE;
469       }
470       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
471         ++aNbDE;
472       }
473     }
474   }
475   //
476   if (!(aNbSE==1 && aNbDE==2)) {
477     return;
478   }
479   aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
480 }
481 //=======================================================================
482 //function : FillDetails
483 //purpose  : 
484 //=======================================================================
485   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
486                                              const gp_Cone& )//aCone)
487 {
488   Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
489   Standard_Real aR[3], aHeight;
490   gp_Pnt aPC[3], aPD, aPc, aPX[3];
491   TopoDS_Vertex aVD;
492   TopoDS_Edge aE;
493   TopoDS_Iterator aIt;
494   TopExp_Explorer aExp;
495   TopTools_MapOfShape aM;
496   GEOMAlgo_KindOfShape aKS, aKSE;
497   GEOMAlgo_KindOfName aKN, aKNE;
498   GEOMAlgo_KindOfClosed aKCE;
499   //
500   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
501   aKN=GEOMAlgo_KN_UNKNOWN;
502   aInfo.SetKindOfName(aKN);
503   //
504   aKS=aInfo.KindOfShape();
505   if (aKS!=GEOMAlgo_KS_CONE) {
506     return;
507   }
508   //
509   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
510     return;
511   }
512   //
513   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
514   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
515   if (!(aNbV==2 && aNbE==3)) {
516     return;
517   }
518   //
519   i=0;
520   aNbCE=0;
521   aNbSE=0;
522   aNbDE=0;
523   aExp.Init(aF, TopAbs_EDGE);
524   for (; aExp.More(); aExp.Next()) {
525     aE=TopoDS::Edge(aExp.Current());
526     if(aM.Add(aE)) {
527       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
528       aKNE=aInfoE.KindOfName();
529       aKCE=aInfoE.KindOfClosed();
530       aKSE=aInfoE.KindOfShape();
531       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
532         aPC[i]=aInfoE.Location();
533         aR[i]=aInfoE.Radius1();
534         //
535         aIt.Initialize(aE);
536         for (; aIt.More(); aIt.Next()) {
537           aVD=TopoDS::Vertex(aIt.Value());
538           break;
539         }
540         aPX[i]=BRep_Tool::Pnt(aVD);
541         //
542         ++i;
543         ++aNbCE;
544       }
545       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
546         if (BRep_Tool::IsClosed(aE, aF)) {
547           ++aNbSE;
548         }
549       }
550       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
551         aIt.Initialize(aE);
552         for (; aIt.More(); aIt.Next()) {
553           aVD=TopoDS::Vertex(aIt.Value());
554           break;
555         }
556         //
557         aPD=BRep_Tool::Pnt(aVD);
558         //
559         ++aNbDE;
560       }
561     }
562   }
563   //
564   if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
565     return;
566   }
567   //
568   if (aNbDE==1) {
569     aPC[1]=aPD;
570     aR[1]=0.;
571   }
572   //
573   aHeight=aPC[0].Distance(aPC[1]);
574   //
575   Standard_Real aRmin, aRmax;
576   gp_Ax2 aAx2new;
577   //
578   if (aR[0]>aR[1]) {
579     aRmin=aR[1];
580     aRmax=aR[0];
581     aPc=aPC[0];
582     gp_Vec aVz(aPC[0], aPC[1]);
583     gp_Vec aVx(aPC[0], aPX[0]);
584     gp_Dir aDz(aVz);
585     gp_Dir aDx(aVx);
586     gp_Ax2 aAx2(aPc, aDz, aDx);
587     aAx2new=aAx2;
588   }
589   else {
590     aRmin=aR[0];
591     aRmax=aR[1];
592     aPc=aPC[1];
593     gp_Vec aVz(aPC[1], aPC[0]);
594     gp_Vec aVx(aPC[1], aPX[1]);
595     gp_Dir aDz(aVz);
596     gp_Dir aDx(aVx);
597     gp_Ax2 aAx2(aPc, aDz, aDx);
598     aAx2new=aAx2;
599   }
600   //
601   gp_Ax3 aAx3(aAx2new);
602   aInfo.SetLocation(aPc);
603   aInfo.SetPosition(aAx3);
604   aInfo.SetRadius1(aRmax);
605   aInfo.SetRadius2(aRmin);
606   aInfo.SetHeight(aHeight);
607   //
608   aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
609 }
610 //=======================================================================
611 //function : FillDetails
612 //purpose  : 
613 //=======================================================================
614   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
615                                              const gp_Cylinder& aCyl)
616 {
617   Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
618   Standard_Real aT0, aT1, aHeight;
619   gp_Pnt aPC[3], aPc;
620   TopoDS_Edge aE;
621   TopExp_Explorer aExp;
622   TopTools_MapOfShape aM;
623   GEOMAlgo_KindOfShape aKS;
624   GEOMAlgo_KindOfName aKN, aKNE;
625   GEOMAlgo_KindOfClosed aKCE;
626   // 
627   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
628   aKN=GEOMAlgo_KN_UNKNOWN;
629   aInfo.SetKindOfName(aKN);
630   //
631   aKS=aInfo.KindOfShape();
632   if (aKS!=GEOMAlgo_KS_CYLINDER) {
633     return;
634   }
635   //
636   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
637     return;
638   }
639   //
640   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
641   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
642   if (!(aNbV==2 && aNbE==3)) {
643     return;
644   }
645   //
646   i=0;
647   aNbCE=0;
648   aNbSE=0;
649   aExp.Init(aF, TopAbs_EDGE);
650   for (; aExp.More(); aExp.Next()) {
651     aE=TopoDS::Edge(aExp.Current());
652     if(aM.Add(aE)) {
653       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
654       aKNE=aInfoE.KindOfName();
655       aKCE=aInfoE.KindOfClosed();
656       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
657         aPC[aNbCE]=aInfoE.Location();
658         ++aNbCE;
659       }
660       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
661         if (BRep_Tool::IsClosed(aE, aF)) {
662           ++aNbSE;
663         }
664       }
665     }
666   }
667   //
668   if (!(aNbCE==2 && aNbSE==1)) {
669     return;
670   }
671   //
672   const gp_Ax1& aAx1=aCyl.Axis();
673   const gp_Dir& aDir=aAx1.Direction();
674   const gp_Pnt& aPLoc=aAx1.Location();
675   gp_Lin aLin(aPLoc, aDir);
676   //
677   aT0=ElCLib::Parameter(aLin, aPC[0]);
678   aT1=ElCLib::Parameter(aLin, aPC[1]);
679   //
680   aPc=aPC[0];;
681   if (aT0>aT1) {
682     aPc=aPC[1];
683   }
684   aHeight=aPC[0].Distance(aPC[1]);
685   //
686   gp_Ax3 aAx3=aCyl.Position();
687   aAx3.SetLocation(aPc);
688   //
689   aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
690   aInfo.SetPosition(aAx3);
691   aInfo.SetLocation(aPc);
692   aInfo.SetHeight(aHeight);
693 }
694
695 //=======================================================================
696 //function : FillDetails
697 //purpose  : 
698 //=======================================================================
699   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
700                                              const gp_Torus& )
701 {
702   Standard_Integer aNbV, aNbE, aNbSE;
703   TopoDS_Edge aE; 
704   TopExp_Explorer aExp;
705   TopTools_MapOfShape aM; 
706   GEOMAlgo_KindOfShape aKS;
707   //
708   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
709   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
710   //
711   aKS=aInfo.KindOfShape();
712   if (aKS!=GEOMAlgo_KS_TORUS) {
713     return;
714   }
715   //
716   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
717   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
718   if (!(aNbV==1 && aNbE==2)) {
719     return;
720   }
721   //
722   aNbSE=0;
723   aExp.Init(aF, TopAbs_EDGE);
724   for (; aExp.More(); aExp.Next()) {
725     aE=TopoDS::Edge(aExp.Current());
726     if (aM.Add(aE)) {
727       //const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
728       if (BRep_Tool::IsClosed(aE, aF)) {
729         ++aNbSE;
730       }
731     }
732   }
733   //
734   if (aNbSE!=2) {
735     return;
736   }
737   aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);
738 }