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