Back to index

salome-geom  6.5.0
GEOMAlgo_ShapeInfoFiller_1.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include <GEOMAlgo_ShapeInfoFiller.hxx>
00021 
00022 #include <Precision.hxx>
00023 
00024 #include <gp_Lin.hxx>
00025 #include <gp_XYZ.hxx>
00026 #include <gp_Ax1.hxx>
00027 #include <gp_Dir.hxx>
00028 #include <gp_Vec.hxx>
00029 #include <gp_Ax2.hxx>
00030 #include <gp_Ax3.hxx>
00031 
00032 #include <ElCLib.hxx>
00033 
00034 #include <TopoDS.hxx>
00035 #include <TopoDS_Vertex.hxx>
00036 #include <TopoDS_Edge.hxx>
00037 #include <TopoDS_Wire.hxx>
00038 #include <TopoDS_Face.hxx>
00039 #include <TopoDS_Iterator.hxx>
00040 
00041 #include <BRep_Tool.hxx>
00042 
00043 #include <TopExp.hxx>
00044 #include <TopExp_Explorer.hxx>
00045 
00046 #include <TopTools_MapOfShape.hxx>
00047 #include <TopTools_IndexedMapOfShape.hxx>
00048 #include <BRepTools_WireExplorer.hxx>
00049 
00050 #include <GEOMAlgo_ShapeInfo.hxx>
00051 #include <TColStd_MapOfInteger.hxx>
00052 #include <TColStd_IndexedMapOfInteger.hxx>
00053 
00054 //=======================================================================
00055 //function : FillDetails
00056 //purpose  :
00057 //=======================================================================
00058   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Solid& aSd)
00059 {
00060   Standard_Integer i, aNbF, aNbCyl, aNbCon, aNbPgn, aNbRct, aNbCrc, aNbX;
00061   TopoDS_Shape aFCyl, aFCon;
00062   TopTools_IndexedMapOfShape aMF;
00063   GEOMAlgo_KindOfName aKNF;
00064   //
00065   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aSd);
00066   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
00067   //
00068   TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
00069   //
00070   aNbF=aMF.Extent();
00071   if (!aNbF) {
00072     return;
00073   }
00074   //
00075   if (aNbF==1) {
00076     const TopoDS_Shape& aF=aMF(1);
00077     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
00078     aKNF=aInfoF.KindOfName(); // mb: sphere, torus
00079     if (aKNF==GEOMAlgo_KN_SPHERE ||
00080         aKNF==GEOMAlgo_KN_TORUS) {
00081       aInfo.SetKindOfName(aKNF);
00082       aInfo.SetLocation(aInfoF.Location());
00083       aInfo.SetPosition(aInfoF.Position());
00084       aInfo.SetRadius1(aInfoF.Radius1());
00085       if(aKNF==GEOMAlgo_KN_TORUS) {
00086         aInfo.SetRadius2(aInfoF.Radius2());
00087       }
00088       return;
00089     }
00090   }
00091   //
00092   aNbCyl=0;
00093   aNbCon=0;
00094   aNbPgn=0;
00095   aNbRct=0;
00096   aNbCrc=0;
00097   for (i=1; i<=aNbF; ++i) {
00098     const TopoDS_Shape& aF=aMF(i);
00099     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aF);
00100     aKNF=aInfoF.KindOfName();
00101     if (aKNF==GEOMAlgo_KN_CYLINDER) {
00102       aFCyl=aF;
00103       ++aNbCyl;
00104     }
00105     else if (aKNF==GEOMAlgo_KN_CONE) {
00106       aFCon=aF;
00107       ++aNbCon;
00108     }
00109     else if (aKNF==GEOMAlgo_KN_DISKCIRCLE) {
00110       ++aNbCrc;
00111     }
00112     else if (aKNF==GEOMAlgo_KN_POLYGON ||
00113             aKNF==GEOMAlgo_KN_TRIANGLE ||
00114             aKNF==GEOMAlgo_KN_QUADRANGLE) {
00115       ++aNbPgn;
00116     }
00117     else if (aKNF==GEOMAlgo_KN_RECTANGLE) {
00118       ++aNbPgn;
00119       ++aNbRct;
00120     }
00121   }
00122   //
00123   aNbX=aNbCyl+aNbCrc;
00124   if (aNbCyl==1 && aNbCrc==2 && aNbX==aNbF) {
00125     // cylinder (as they understand it)
00126     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCyl);
00127     aKNF=aInfoF.KindOfName();
00128     aInfo.SetKindOfName(aKNF);
00129     aInfo.SetLocation(aInfoF.Location());
00130     aInfo.SetPosition(aInfoF.Position());
00131     aInfo.SetRadius1(aInfoF.Radius1());
00132     aInfo.SetHeight(aInfoF.Height());
00133     return;
00134   }
00135   //
00136   aNbX=aNbCon+aNbCrc;
00137   if (aNbCon==1 && (aNbCrc==1 || aNbCrc==2) && aNbX==aNbF) {
00138     // cone
00139     GEOMAlgo_ShapeInfo& aInfoF=myMapInfo.ChangeFromKey(aFCon);
00140     aKNF=aInfoF.KindOfName();
00141     aInfo.SetKindOfName(aKNF);
00142     aInfo.SetLocation(aInfoF.Location());
00143     aInfo.SetPosition(aInfoF.Position());
00144     aInfo.SetRadius1(aInfoF.Radius1());
00145     aInfo.SetRadius2(aInfoF.Radius2());
00146     aInfo.SetHeight(aInfoF.Height());
00147     return;
00148   }
00149   //
00150   //modified by NIZNHY-PKV Wed Jan 11 11:04:31 2012f
00151   if (aNbF!=aNbPgn) {
00152     return;// -> GEOMAlgo_KN_UNKNOWN
00153   }
00154   //modified by NIZNHY-PKV Wed Jan 11 11:04:37 2012t
00155   if (aNbPgn!=6) {
00156     aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
00157     return;
00158   }
00159   // aNbPgn==6
00160   if (aNbPgn!=aNbRct) {
00161     aInfo.SetKindOfName(GEOMAlgo_KN_POLYHEDRON);
00162     return;
00163   }
00164   //===================================================
00165   // aNbRct=6;
00166   // box
00167   Standard_Integer j, aNbFi, aNbV, iMax, iMin, iMid;
00168   Standard_Real aDot, aLength, aWidth, aHeight, aDist[3];
00169   Standard_Real aDistMin, aDistMax;
00170   gp_Pnt aPi, aPc;
00171   gp_Dir aDir[3];
00172   gp_XYZ aXYZc;
00173   TColStd_IndexedMapOfInteger aMp;
00174   TopTools_IndexedMapOfShape aMV, aMFi;
00175   //
00176   // barycenter aPc
00177   TopExp::MapShapes(aSd, TopAbs_VERTEX, aMV);
00178   aNbV=aMV.Extent();
00179   if (aNbV!=8) {
00180     return;
00181   }
00182   //
00183   aXYZc.SetCoord(0.,0.,0.);
00184   for (i=1; i<=aNbV; ++i) {
00185     const TopoDS_Vertex& aVi=TopoDS::Vertex(aMV(i));
00186     aPi=BRep_Tool::Pnt(aVi);
00187     const gp_XYZ& aXYZ=aPi.XYZ();
00188     aXYZc=aXYZc+aXYZ;
00189   }
00190   //
00191   aXYZc.Divide(aNbV);
00192   aPc.SetXYZ(aXYZc);
00193   //
00194   // 3 faces
00195   for (i=1; i<=aNbF; ++i) {
00196     if (aMp.Contains(i)) {
00197       continue;
00198     }
00199     //
00200     const TopoDS_Shape& aFi=aMF(i);
00201     const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
00202     const gp_Dir& aDNi=aIFi.Position().Direction();
00203     //
00204     for (j=i+1; j<=aNbF; ++j) {
00205       if (aMp.Contains(j)) {
00206         continue;
00207       }
00208       //
00209       const TopoDS_Shape& aFj=aMF(j);
00210       const GEOMAlgo_ShapeInfo& aIFj=myMapInfo.FindFromKey(aFj);
00211       const gp_Dir& aDNj=aIFj.Position().Direction();
00212       //
00213       aDot=aDNi*aDNj;
00214       if (fabs(1.-aDot)<0.0001) {
00215         aMp.Add(i);
00216         aMp.Add(j);
00217         aMFi.Add(aFi);
00218         break;
00219       }
00220       //
00221     }
00222   }
00223   aNbFi=aMFi.Extent();
00224   if (aNbFi!=3) {
00225     return;
00226   }
00227   //
00228   aDistMin=1.e15;
00229   aDistMax=-aDistMin;
00230   for (i=0; i<aNbFi; ++i) {
00231     const TopoDS_Shape& aFi=aMFi(i+1);
00232     const GEOMAlgo_ShapeInfo& aIFi=myMapInfo.FindFromKey(aFi);
00233     aPi=aIFi.Location();
00234     aDist[i]=aPc.Distance(aPi);
00235     if (aDist[i]>aDistMax) {
00236       aDistMax=aDist[i];
00237       iMax=i;
00238     }
00239     if (aDist[i]<aDistMin) {
00240       aDistMin=aDist[i];
00241       iMin=i;
00242     }
00243     gp_Vec aVi(aPc, aPi);
00244     gp_Dir aDi(aVi);
00245     aDir[i]=aDi;
00246   }
00247   //
00248   if (iMax==iMin) {
00249     iMax=0;
00250     iMin=1;
00251   }
00252   iMid=3-iMax-iMin;
00253   //
00254   aLength=2.*aDist[iMax];
00255   aWidth=2.*aDist[iMid];
00256   aHeight=2.*aDist[iMin];
00257   //
00258   gp_Ax2 aAx2(aPc, aDir[iMin], aDir[iMax]);
00259   gp_Ax3 aAx3(aAx2);
00260   //
00261   aInfo.SetKindOfName(GEOMAlgo_KN_BOX);
00262   aInfo.SetLocation(aPc);
00263   aInfo.SetLength(aLength);
00264   aInfo.SetWidth(aWidth);
00265   aInfo.SetHeight(aHeight);
00266   aInfo.SetPosition(aAx3);
00267 }
00268 //=======================================================================
00269 //function : FillDetails
00270 //purpose  :
00271 //=======================================================================
00272   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
00273                                              const gp_Pln& aPln)
00274 {
00275   Standard_Integer aNbV, aNbE, i, j;
00276   Standard_Real aDot, aD0, aD1, aLength, aWidth;
00277   gp_Dir aDx[4], aDX;
00278   gp_Pnt aPx[4], aP, aPc;
00279   gp_XYZ aXYZc;
00280   TopExp_Explorer aExp;
00281   TopoDS_Shape aE;
00282   TopoDS_Wire aW;
00283   TopoDS_Edge aEx;
00284   TopoDS_Iterator aIt;
00285   TopTools_IndexedMapOfShape aMV;
00286   BRepTools_WireExplorer aWExp;
00287   GEOMAlgo_KindOfName aKN, aKNE;
00288   GEOMAlgo_KindOfShape aKS;
00289   //
00290   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
00291   aKN=GEOMAlgo_KN_UNKNOWN;
00292   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
00293   //
00294   aKS=aInfo.KindOfShape();
00295   if (aKS!=GEOMAlgo_KS_PLANE) {
00296     return;
00297   }
00298   //
00299   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
00300     aInfo.SetKindOfName(GEOMAlgo_KN_PLANE);
00301     return;
00302   }
00303   //
00304   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
00305   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
00306   //
00307   // 1. may be it is circle/ellipse
00308   if (aNbV==1 && aNbE==1) {
00309     aExp.Init(aF, TopAbs_EDGE);
00310     for (; aExp.More(); aExp.Next()) {
00311       aE=aExp.Current();
00312       break;
00313     }
00314     //
00315     const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
00316     aKNE=aInfoE.KindOfName();
00317     if (aKNE==GEOMAlgo_KN_CIRCLE) {
00318       aKN=GEOMAlgo_KN_DISKCIRCLE;
00319       aInfo.SetKindOfName(aKN);
00320       aInfo.SetRadius1(aInfoE.Radius1());
00321       aInfo.SetLocation(aInfoE.Location());
00322       aInfo.SetPosition(aInfoE.Position());
00323     }
00324     if (aKNE==GEOMAlgo_KN_ELLIPSE) {
00325       aKN=GEOMAlgo_KN_DISKELLIPSE;
00326       aInfo.SetKindOfName(aKN);
00327       aInfo.SetRadius1(aInfoE.Radius1());
00328       aInfo.SetRadius2(aInfoE.Radius2());
00329       aInfo.SetLocation(aInfoE.Location());
00330       aInfo.SetPosition(aInfoE.Position());
00331     }
00332   }
00333   //
00334   // 2. may be it is rectangle
00335   else  {
00336     aExp.Init(aF, TopAbs_EDGE);
00337     for (; aExp.More(); aExp.Next()) {
00338       aE=aExp.Current();
00339       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
00340       aKNE=aInfoE.KindOfName();
00341       if (aKNE!=GEOMAlgo_KN_SEGMENT) {
00342         return;
00343       }
00344     }
00345     //
00346     aInfo.SetKindOfName(GEOMAlgo_KN_POLYGON);
00347     //
00348     if (aNbV==3 && aNbE==3) {
00349       aInfo.SetKindOfName(GEOMAlgo_KN_TRIANGLE);
00350       //
00351       aXYZc.SetCoord(0.,0.,0.);
00352       TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
00353       for (i=1; i<=aNbV; ++i) {
00354         const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
00355         aP=BRep_Tool::Pnt(aV);
00356         const gp_XYZ& aXYZ=aP.XYZ();
00357         aXYZc=aXYZc+aXYZ;
00358         aPx[i-1]=aP;
00359       }
00360       aXYZc.Divide(3.);
00361       //
00362       aPc.SetXYZ(aXYZc);
00363       gp_Vec aVX(aPc, aPx[0]);
00364       aVX.Normalize();
00365       aDX.SetXYZ(aVX.XYZ());
00366       const gp_Dir& aDZ=aPln.Axis().Direction();
00367       //
00368       gp_Ax2 aAx2(aPc, aDZ, aDX);
00369       gp_Ax3 aAx3(aAx2);
00370       //
00371       aInfo.SetLocation(aPc);
00372       aInfo.SetPosition(aAx3);
00373       //
00374       return;
00375     }
00376     //
00377     if (!(aNbV==4 && aNbE==4)) {
00378       return;
00379     }
00380     //
00381     // aNbV==4 && aNbE==4 and all edges are segments
00382     aIt.Initialize(aF);
00383     for (; aIt.More(); aIt.Next()){
00384       aW=TopoDS::Wire(aIt.Value());
00385       break;
00386     }
00387     //
00388     aWExp.Init(aW, aF);
00389     for (i=0; aWExp.More(); aWExp.Next(), ++i) {
00390       aEx=aWExp.Current();
00391       const GEOMAlgo_ShapeInfo& aInfoEx=myMapInfo.FindFromKey(aEx);
00392       aDx[i]=aInfoEx.Direction();
00393       aPx[i]=aInfoEx.Location();
00394     }
00395     //
00396     for (i=0; i<4; ++i) {
00397       j=(i==3) ? 0 : i+1;
00398       aDot=aDx[i]*aDx[j];
00399       if (fabs (aDot) > myTolerance) {
00400         aInfo.SetKindOfName(GEOMAlgo_KN_QUADRANGLE);
00401         return;
00402       }
00403     }
00404     //
00405     // rectangle
00406     aInfo.SetKindOfName(GEOMAlgo_KN_RECTANGLE);
00407     //
00408     // shift location to the center and calc. sizes
00409     aXYZc.SetCoord(0.,0.,0.);
00410     TopExp::MapShapes(aF, TopAbs_VERTEX, aMV);
00411     for (i=1; i<=aNbV; ++i) {
00412       const TopoDS_Vertex& aV=TopoDS::Vertex(aMV(i));
00413       aP=BRep_Tool::Pnt(aV);
00414       const gp_XYZ& aXYZ=aP.XYZ();
00415       aXYZc=aXYZc+aXYZ;
00416     }
00417     //
00418     // Location : aPc in center of rectangle
00419     // Position : 0z is plane normal
00420     //            0x is along length
00421     //
00422     aXYZc.Divide(4.);
00423     aPc.SetXYZ(aXYZc);
00424     //
00425     gp_Lin aL0(aPx[0], aDx[0]);
00426     gp_Lin aL1(aPx[1], aDx[1]);
00427     //
00428     aD0=aL0.Distance(aPc);
00429     aD1=aL1.Distance(aPc);
00430     //
00431     aLength=aD0;
00432     aWidth =aD1;
00433     aDX=aL1.Direction();
00434     if (aD0<aD1) {
00435       aLength=aD1;
00436       aWidth =aD0;
00437       aDX=aL0.Direction();
00438     }
00439     //
00440     aLength=2.*aLength;
00441     aWidth =2.*aWidth;
00442     //
00443     aInfo.SetLocation(aPc);
00444     aInfo.SetLength(aLength);
00445     aInfo.SetWidth(aWidth);
00446     //
00447     const gp_Dir& aDZ=aPln.Axis().Direction();
00448     gp_Ax2 aAx2(aPc, aDZ, aDX);
00449     gp_Ax3 aAx3(aAx2);
00450     aInfo.SetPosition(aAx3);
00451   }
00452 
00453   return;
00454 }
00455 //=======================================================================
00456 //function : FillDetails
00457 //purpose  :
00458 //=======================================================================
00459   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
00460                                              const gp_Sphere& )
00461 {
00462   Standard_Integer aNbV, aNbE, aNbSE, aNbDE;
00463   TopoDS_Edge aE;
00464   TopExp_Explorer aExp;
00465   TopTools_MapOfShape aM;
00466   GEOMAlgo_KindOfShape aKS, aKSE;
00467   //
00468   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
00469   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
00470   //
00471   aKS=aInfo.KindOfShape();
00472   if (aKS!=GEOMAlgo_KS_SPHERE) {
00473     return;
00474   }
00475   //
00476   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
00477   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
00478   if (!(aNbV==2 && aNbE==3)) {
00479     return;
00480   }
00481   //
00482   aNbSE=0;
00483   aNbDE=0;
00484   aExp.Init(aF, TopAbs_EDGE);
00485   for (; aExp.More(); aExp.Next()) {
00486     aE=TopoDS::Edge(aExp.Current());
00487     if(aM.Add(aE)) {
00488       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
00489       aKSE=aInfoE.KindOfShape();
00490       //
00491       if (BRep_Tool::IsClosed(aE, aF)) {
00492         ++aNbSE;
00493       }
00494       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
00495         ++aNbDE;
00496       }
00497     }
00498   }
00499   //
00500   if (!(aNbSE==1 && aNbDE==2)) {
00501     return;
00502   }
00503   aInfo.SetKindOfName(GEOMAlgo_KN_SPHERE);
00504 }
00505 //=======================================================================
00506 //function : FillDetails
00507 //purpose  :
00508 //=======================================================================
00509   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
00510                                              const gp_Cone& )//aCone)
00511 {
00512   Standard_Integer aNbV, aNbE, aNbCE, aNbSE, aNbDE, i;
00513   Standard_Real aR[3], aHeight;
00514   gp_Pnt aPC[3], aPD, aPc, aPX[3];
00515   TopoDS_Vertex aVD;
00516   TopoDS_Edge aE;
00517   TopoDS_Iterator aIt;
00518   TopExp_Explorer aExp;
00519   TopTools_MapOfShape aM;
00520   GEOMAlgo_KindOfShape aKS, aKSE;
00521   GEOMAlgo_KindOfName aKN, aKNE;
00522   GEOMAlgo_KindOfClosed aKCE;
00523   //
00524   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
00525   aKN=GEOMAlgo_KN_UNKNOWN;
00526   aInfo.SetKindOfName(aKN);
00527   //
00528   aKS=aInfo.KindOfShape();
00529   if (aKS!=GEOMAlgo_KS_CONE) {
00530     return;
00531   }
00532   //
00533   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
00534     return;
00535   }
00536   //
00537   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
00538   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
00539   if (!(aNbV==2 && aNbE==3)) {
00540     return;
00541   }
00542   //
00543   i=0;
00544   aNbCE=0;
00545   aNbSE=0;
00546   aNbDE=0;
00547   aExp.Init(aF, TopAbs_EDGE);
00548   for (; aExp.More(); aExp.Next()) {
00549     aE=TopoDS::Edge(aExp.Current());
00550     if(aM.Add(aE)) {
00551       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
00552       aKNE=aInfoE.KindOfName();
00553       aKCE=aInfoE.KindOfClosed();
00554       aKSE=aInfoE.KindOfShape();
00555       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
00556         aPC[i]=aInfoE.Location();
00557         aR[i]=aInfoE.Radius1();
00558         //
00559         aIt.Initialize(aE);
00560         for (; aIt.More(); aIt.Next()) {
00561           aVD=TopoDS::Vertex(aIt.Value());
00562           break;
00563         }
00564         aPX[i]=BRep_Tool::Pnt(aVD);
00565         //
00566         ++i;
00567         ++aNbCE;
00568       }
00569       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
00570         if (BRep_Tool::IsClosed(aE, aF)) {
00571           ++aNbSE;
00572         }
00573       }
00574       else if (aKSE==GEOMAlgo_KS_DEGENERATED) {
00575         aIt.Initialize(aE);
00576         for (; aIt.More(); aIt.Next()) {
00577           aVD=TopoDS::Vertex(aIt.Value());
00578           break;
00579         }
00580         //
00581         aPD=BRep_Tool::Pnt(aVD);
00582         //
00583         ++aNbDE;
00584       }
00585     }
00586   }
00587   //
00588   if (!((aNbCE==2 || (aNbCE==1 && aNbDE==1)) && aNbSE==1)) {
00589     return;
00590   }
00591   //
00592   if (aNbDE==1) {
00593     aPC[1]=aPD;
00594     aR[1]=0.;
00595   }
00596   //
00597   aHeight=aPC[0].Distance(aPC[1]);
00598   //
00599   Standard_Real aRmin, aRmax;
00600   gp_Ax2 aAx2new;
00601   //
00602   if (aR[0]>aR[1]) {
00603     aRmin=aR[1];
00604     aRmax=aR[0];
00605     aPc=aPC[0];
00606     gp_Vec aVz(aPC[0], aPC[1]);
00607     gp_Vec aVx(aPC[0], aPX[0]);
00608     gp_Dir aDz(aVz);
00609     gp_Dir aDx(aVx);
00610     gp_Ax2 aAx2(aPc, aDz, aDx);
00611     aAx2new=aAx2;
00612   }
00613   else {
00614     aRmin=aR[0];
00615     aRmax=aR[1];
00616     aPc=aPC[1];
00617     gp_Vec aVz(aPC[1], aPC[0]);
00618     gp_Vec aVx(aPC[1], aPX[1]);
00619     gp_Dir aDz(aVz);
00620     gp_Dir aDx(aVx);
00621     gp_Ax2 aAx2(aPc, aDz, aDx);
00622     aAx2new=aAx2;
00623   }
00624   //
00625   gp_Ax3 aAx3(aAx2new);
00626   aInfo.SetLocation(aPc);
00627   aInfo.SetPosition(aAx3);
00628   aInfo.SetRadius1(aRmax);
00629   aInfo.SetRadius2(aRmin);
00630   aInfo.SetHeight(aHeight);
00631   //
00632   aInfo.SetKindOfName(GEOMAlgo_KN_CONE);
00633 }
00634 //=======================================================================
00635 //function : FillDetails
00636 //purpose  :
00637 //=======================================================================
00638   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
00639                                              const gp_Cylinder& aCyl)
00640 {
00641   Standard_Integer i, aNbV, aNbE, aNbCE, aNbSE;
00642   Standard_Real aT0, aT1, aHeight;
00643   gp_Pnt aPC[3], aPc;
00644   TopoDS_Edge aE;
00645   TopExp_Explorer aExp;
00646   TopTools_MapOfShape aM;
00647   GEOMAlgo_KindOfShape aKS;
00648   GEOMAlgo_KindOfName aKN, aKNE;
00649   GEOMAlgo_KindOfClosed aKCE;
00650   //
00651   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
00652   aKN=GEOMAlgo_KN_UNKNOWN;
00653   aInfo.SetKindOfName(aKN);
00654   //
00655   aKS=aInfo.KindOfShape();
00656   if (aKS!=GEOMAlgo_KS_CYLINDER) {
00657     return;
00658   }
00659   //
00660   if (aInfo.KindOfBounds()==GEOMAlgo_KB_INFINITE) {
00661     return;
00662   }
00663   //
00664   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
00665   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
00666   if (!(aNbV==2 && aNbE==3)) {
00667     return;
00668   }
00669   //
00670   i=0;
00671   aNbCE=0;
00672   aNbSE=0;
00673   aExp.Init(aF, TopAbs_EDGE);
00674   for (; aExp.More(); aExp.Next()) {
00675     aE=TopoDS::Edge(aExp.Current());
00676     if(aM.Add(aE)) {
00677       const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
00678       aKNE=aInfoE.KindOfName();
00679       aKCE=aInfoE.KindOfClosed();
00680       if (aKNE==GEOMAlgo_KN_CIRCLE && aKCE==GEOMAlgo_KC_CLOSED) {
00681         aPC[aNbCE]=aInfoE.Location();
00682         ++aNbCE;
00683       }
00684       else if (aKNE==GEOMAlgo_KN_SEGMENT) {
00685         if (BRep_Tool::IsClosed(aE, aF)) {
00686           ++aNbSE;
00687         }
00688       }
00689     }
00690   }
00691   //
00692   if (!(aNbCE==2 && aNbSE==1)) {
00693     return;
00694   }
00695   //
00696   const gp_Ax1& aAx1=aCyl.Axis();
00697   const gp_Dir& aDir=aAx1.Direction();
00698   const gp_Pnt& aPLoc=aAx1.Location();
00699   gp_Lin aLin(aPLoc, aDir);
00700   //
00701   aT0=ElCLib::Parameter(aLin, aPC[0]);
00702   aT1=ElCLib::Parameter(aLin, aPC[1]);
00703   //
00704   aPc=aPC[0];;
00705   if (aT0>aT1) {
00706     aPc=aPC[1];
00707   }
00708   aHeight=aPC[0].Distance(aPC[1]);
00709   //
00710   gp_Ax3 aAx3=aCyl.Position();
00711   aAx3.SetLocation(aPc);
00712   //
00713   aInfo.SetKindOfName(GEOMAlgo_KN_CYLINDER);
00714   aInfo.SetPosition(aAx3);
00715   aInfo.SetLocation(aPc);
00716   aInfo.SetHeight(aHeight);
00717 }
00718 
00719 //=======================================================================
00720 //function : FillDetails
00721 //purpose  :
00722 //=======================================================================
00723   void GEOMAlgo_ShapeInfoFiller::FillDetails(const TopoDS_Face& aF,
00724                                              const gp_Torus& )
00725 {
00726   Standard_Integer aNbV, aNbE, aNbSE;
00727   TopoDS_Edge aE;
00728   TopExp_Explorer aExp;
00729   TopTools_MapOfShape aM;
00730   GEOMAlgo_KindOfShape aKS;
00731   //
00732   GEOMAlgo_ShapeInfo& aInfo=myMapInfo.ChangeFromKey(aF);
00733   aInfo.SetKindOfName(GEOMAlgo_KN_UNKNOWN);
00734   //
00735   aKS=aInfo.KindOfShape();
00736   if (aKS!=GEOMAlgo_KS_TORUS) {
00737     return;
00738   }
00739   //
00740   aNbV=aInfo.NbSubShapes(TopAbs_VERTEX);
00741   aNbE=aInfo.NbSubShapes(TopAbs_EDGE);
00742   if (!(aNbV==1 && aNbE==2)) {
00743     return;
00744   }
00745   //
00746   aNbSE=0;
00747   aExp.Init(aF, TopAbs_EDGE);
00748   for (; aExp.More(); aExp.Next()) {
00749     aE=TopoDS::Edge(aExp.Current());
00750     if (aM.Add(aE)) {
00751       //const GEOMAlgo_ShapeInfo& aInfoE=myMapInfo.FindFromKey(aE);
00752       if (BRep_Tool::IsClosed(aE, aF)) {
00753         ++aNbSE;
00754       }
00755     }
00756   }
00757   //
00758   if (aNbSE!=2) {
00759     return;
00760   }
00761   aInfo.SetKindOfName(GEOMAlgo_KN_TORUS);
00762 }