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