Back to index

salome-geom  6.5.0
GEOMAlgo_FinderShapeOn2.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File:        GEOMAlgo_FinderShapeOn2.cxx
00024 // Created:     Fri Mar  4 10:31:06 2005
00025 // Author:      Peter KURNEV
00026 //              <pkv@irinox>
00027 //
00028 #include <GEOMAlgo_FinderShapeOn2.hxx>
00029 #include <math.h>
00030 
00031 
00032 #include <Precision.hxx>
00033 #include <TColStd_Array1OfInteger.hxx>
00034 #include <TColStd_MapOfInteger.hxx>
00035 
00036 #include <gp_Trsf.hxx>
00037 #include <gp_Cylinder.hxx>
00038 #include <gp_Pnt.hxx>
00039 
00040 #include <TColgp_Array1OfPnt.hxx>
00041 
00042 #include <Poly_Array1OfTriangle.hxx>
00043 #include <Poly_Triangle.hxx>
00044 #include <Poly_PolygonOnTriangulation.hxx>
00045 #include <Poly_Triangulation.hxx>
00046 #include <Poly_Polygon3D.hxx>
00047 
00048 #include <Geom_Curve.hxx>
00049 #include <Geom_Surface.hxx>
00050 #include <GeomAdaptor_Surface.hxx>
00051 #include <GeomAbs_SurfaceType.hxx>
00052 #include <GeomAdaptor_Curve.hxx>
00053 #include <GeomAbs_CurveType.hxx>
00054 
00055 #include <TopAbs_State.hxx>
00056 
00057 #include <TopLoc_Location.hxx>
00058 #include <TopoDS.hxx>
00059 #include <TopoDS_Shape.hxx>
00060 #include <TopoDS_Vertex.hxx>
00061 #include <TopoDS_Face.hxx>
00062 #include <TopoDS_Edge.hxx>
00063 
00064 #include <TopExp.hxx>
00065 #include <TopExp_Explorer.hxx>
00066 
00067 #include <TopTools_IndexedMapOfShape.hxx>
00068 
00069 #include <BRep_Tool.hxx>
00070 #include <BRepLib_MakeEdge.hxx>
00071 
00072 #include <GEOMAlgo_ListIteratorOfListOfPnt.hxx>
00073 
00074 #include <GEOMAlgo_SurfaceTools.hxx>
00075 #include <GEOMAlgo_StateCollector.hxx>
00076 #include <GEOMAlgo_FinderShapeOn.hxx>
00077 
00078 #include <GEOMAlgo_PassKey.hxx>
00079 #include <GEOMAlgo_DataMapOfPassKeyInteger.hxx>
00080 #include <GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger.hxx>
00081 
00082 //=======================================================================
00083 //function : GEOMAlgo_FinderShapeOn1
00084 //purpose  :
00085 //=======================================================================
00086   GEOMAlgo_FinderShapeOn2::GEOMAlgo_FinderShapeOn2()
00087 :
00088   GEOMAlgo_ShapeAlgo()
00089 {
00090   myTolerance=0.0001;
00091   myShapeType=TopAbs_VERTEX;
00092   myState=GEOMAlgo_ST_UNKNOWN;
00093   myNbPntsMin=3;
00094   myNbPntsMax=0;
00095 }
00096 //=======================================================================
00097 //function : ~
00098 //purpose  :
00099 //=======================================================================
00100   GEOMAlgo_FinderShapeOn2::~GEOMAlgo_FinderShapeOn2()
00101 {
00102 }
00103 //=======================================================================
00104 //function : SetClsf
00105 //purpose  :
00106 //=======================================================================
00107   void GEOMAlgo_FinderShapeOn2::SetClsf(const Handle(GEOMAlgo_Clsf)& aClsf)
00108 {
00109   myClsf=aClsf;
00110 }
00111 //=======================================================================
00112 //function : Clsf
00113 //purpose  :
00114 //=======================================================================
00115   const Handle(GEOMAlgo_Clsf)& GEOMAlgo_FinderShapeOn2::Clsf() const
00116 {
00117   return myClsf;
00118 }
00119 //=======================================================================
00120 //function : SetShapeType
00121 //purpose  :
00122 //=======================================================================
00123   void GEOMAlgo_FinderShapeOn2::SetShapeType(const TopAbs_ShapeEnum aType)
00124 {
00125   myShapeType=aType;
00126 }
00127 //=======================================================================
00128 //function : ShapeType
00129 //purpose  :
00130 //=======================================================================
00131   TopAbs_ShapeEnum GEOMAlgo_FinderShapeOn2::ShapeType()const
00132 {
00133   return myShapeType;
00134 }
00135 //=======================================================================
00136 //function : SetState
00137 //purpose  :
00138 //=======================================================================
00139   void GEOMAlgo_FinderShapeOn2::SetState(const GEOMAlgo_State aState)
00140 {
00141   myState=aState;
00142 }
00143 //=======================================================================
00144 //function : State
00145 //purpose  :
00146 //=======================================================================
00147   GEOMAlgo_State GEOMAlgo_FinderShapeOn2::State() const
00148 {
00149   return myState;
00150 }
00151 //=======================================================================
00152 //function : SetNbPntsMin
00153 //purpose  :
00154 //=======================================================================
00155   void GEOMAlgo_FinderShapeOn2::SetNbPntsMin(const Standard_Integer aNb)
00156 {
00157   myNbPntsMin=aNb;
00158 }
00159 //=======================================================================
00160 //function : NbPntsMin
00161 //purpose  :
00162 //=======================================================================
00163   Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMin()const
00164 {
00165   return myNbPntsMin;
00166 }
00167 //=======================================================================
00168 //function : SetNbPntsMax
00169 //purpose  :
00170 //=======================================================================
00171   void GEOMAlgo_FinderShapeOn2::SetNbPntsMax(const Standard_Integer aNb)
00172 {
00173   myNbPntsMax=aNb;
00174 }
00175 //=======================================================================
00176 //function : NbPntsMax
00177 //purpose  :
00178 //=======================================================================
00179   Standard_Integer GEOMAlgo_FinderShapeOn2::NbPntsMax()const
00180 {
00181   return myNbPntsMax;
00182 }
00183 //=======================================================================
00184 // function: MSS
00185 // purpose:
00186 //=======================================================================
00187   const GEOMAlgo_IndexedDataMapOfShapeState& GEOMAlgo_FinderShapeOn2::MSS() const
00188 {
00189   return myMSS;
00190 }
00191 //=======================================================================
00192 // function: Shapes
00193 // purpose:
00194 //=======================================================================
00195   const TopTools_ListOfShape& GEOMAlgo_FinderShapeOn2::Shapes() const
00196 {
00197   Standard_Integer i, aNb;
00198   TopTools_ListOfShape* pL;
00199   //
00200   pL=(TopTools_ListOfShape*) &myLS;
00201   pL->Clear();
00202   //
00203   aNb=myMSS.Extent();
00204   for (i=1; i<=aNb; ++i) {
00205     const TopoDS_Shape& aS=myMSS.FindKey(i);
00206     if (aS.ShapeType()==myShapeType) {
00207       pL->Append(aS);
00208     }
00209   }
00210   return myLS;
00211 }
00212 //=======================================================================
00213 //function : Perform
00214 //purpose  :
00215 //=======================================================================
00216   void GEOMAlgo_FinderShapeOn2::Perform()
00217 {
00218   myErrorStatus=0;
00219   myWarningStatus=0;
00220   myLS.Clear();
00221   myMSS.Clear();
00222   //
00223   CheckData();
00224   if(myErrorStatus) {
00225     return;
00226   }
00227   //
00228   // Initialize the context
00229   GEOMAlgo_ShapeAlgo::Perform();
00230   //
00231   myClsf->SetTolerance(myTolerance);
00232   //
00233   // 1
00234   ProcessVertices();
00235   if(myErrorStatus) {
00236     return;
00237   }
00238   if (myShapeType==TopAbs_VERTEX) {
00239     return;
00240   }
00241   //
00242   // 2
00243   ProcessEdges();
00244   if(myErrorStatus) {
00245     return;
00246   }
00247   if (myShapeType==TopAbs_EDGE) {
00248     return;
00249   }
00250   //
00251   // 3
00252   ProcessFaces();
00253   if(myErrorStatus) {
00254     return;
00255   }
00256   if (myShapeType==TopAbs_FACE) {
00257     return;
00258   }
00259   //
00260   // 4
00261   ProcessSolids();
00262   //
00263 }
00264 //=======================================================================
00265 //function : CheckData
00266 //purpose  :
00267 //=======================================================================
00268   void GEOMAlgo_FinderShapeOn2::CheckData()
00269 {
00270   Standard_Integer iErr;
00271   //
00272   myErrorStatus=0;
00273   //
00274   if(myClsf.IsNull()) {
00275     myErrorStatus=10; // myClsf=NULL
00276     return;
00277   }
00278   //
00279   myClsf->CheckData();
00280   iErr=myClsf->ErrorStatus();
00281   if (iErr) {
00282     myErrorStatus=41; // invalid data for classifier
00283     return;
00284   }
00285   //
00286   if (myShape.IsNull()) {
00287     myErrorStatus=11; // myShape=NULL
00288     return;
00289   }
00290   //
00291   if (!(myShapeType==TopAbs_VERTEX ||
00292         myShapeType==TopAbs_EDGE ||
00293         myShapeType==TopAbs_FACE ||
00294         myShapeType==TopAbs_SOLID)) {
00295     myErrorStatus=12; // unallowed sub-shape type
00296     return;
00297   }
00298   //
00299   if (myState==GEOMAlgo_ST_UNKNOWN ||
00300       myState==GEOMAlgo_ST_INOUT) {
00301     myErrorStatus=13; // unallowed state type
00302     return;
00303   }
00304 }
00305 //=======================================================================
00306 //function : ProcessVertices
00307 //purpose  :
00308 //=======================================================================
00309   void GEOMAlgo_FinderShapeOn2::ProcessVertices()
00310 {
00311   myErrorStatus=0;
00312   //
00313   Standard_Boolean bIsConformState;
00314   Standard_Integer i, aNb, iErr;
00315   gp_Pnt aP;
00316   TopTools_IndexedMapOfShape aM;
00317   TopAbs_State aSt;
00318   //
00319   TopExp::MapShapes(myShape, TopAbs_VERTEX, aM);
00320   aNb=aM.Extent();
00321   for (i=1; i<=aNb; ++i) {
00322     const TopoDS_Vertex& aV=TopoDS::Vertex(aM(i));
00323     aP=BRep_Tool::Pnt(aV);
00324     //
00325     myClsf->SetPnt(aP);
00326     myClsf->Perform();
00327     iErr=myClsf->ErrorStatus();
00328     if (iErr) {
00329       myErrorStatus=40; // point can not be classified
00330       return;
00331     }
00332     //
00333     aSt=myClsf->State();
00334     bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
00335     //
00336     if (myShapeType==TopAbs_VERTEX){
00337       if (bIsConformState) {
00338         myMSS.Add(aV, aSt);
00339       }
00340     }
00341     else if (bIsConformState || aSt==TopAbs_ON) {
00342       myMSS.Add(aV, aSt);
00343     }
00344   }
00345 }
00346 //=======================================================================
00347 //function : ProcessEdges
00348 //purpose  :
00349 //=======================================================================
00350   void GEOMAlgo_FinderShapeOn2::ProcessEdges()
00351 {
00352   myErrorStatus=0;
00353   //
00354   Standard_Boolean bIsConformState, bIsToBreak;
00355   Standard_Integer i, aNb, iCnt, iErr;
00356   TopAbs_State aSt;
00357   TopTools_IndexedMapOfShape aM;
00358   TopExp_Explorer aExp;
00359   GEOMAlgo_ListIteratorOfListOfPnt aIt;
00360   //
00361   TopExp::MapShapes(myShape, TopAbs_EDGE, aM);
00362   aNb=aM.Extent();
00363   for (i=1; i<=aNb; ++i) {
00364     GEOMAlgo_ListOfPnt aLP;
00365     GEOMAlgo_StateCollector aSC;
00366     //
00367     const TopoDS_Edge& aE=TopoDS::Edge(aM(i));
00368     //
00369     aExp.Init(aE, TopAbs_VERTEX);
00370     for (; aExp.More(); aExp.Next()) {
00371       const TopoDS_Shape& aV=aExp.Current();
00372       //
00373       bIsConformState=myMSS.Contains(aV);
00374       if (!bIsConformState) {
00375         break;// vertex has non-conformed state
00376       }
00377       else {
00378         aSt=myMSS.FindFromKey(aV);
00379         aSC.AppendState(aSt);
00380       }
00381     }
00382     //
00383     if (!bIsConformState) {
00384       continue; // vertex has non-conformed state,skip edge
00385     }
00386     //
00387     if (BRep_Tool::Degenerated(aE)) {
00388       myMSS.Add(aE, aSt);
00389       continue;
00390     }
00391     //
00392     if (myState==GEOMAlgo_ST_ON) {
00393       Standard_Boolean bCanBeON;
00394       Standard_Real aT1, aT2;
00395       Handle(Geom_Curve) aC;
00396       //
00397       aC=BRep_Tool::Curve(aE, aT1, aT2);
00398       bCanBeON=myClsf->CanBeON(aC);
00399       if(!bCanBeON) {
00400         continue;
00401       }
00402     }
00403     //
00404     InnerPoints(aE, aLP);
00405     if (myErrorStatus) {
00406       return;
00407     }
00408     //
00409     bIsConformState=Standard_True;
00410     aIt.Initialize(aLP);
00411     for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
00412       if (myNbPntsMax) {
00413         if (iCnt > myNbPntsMax) {
00414           break;
00415         }
00416       }
00417       //
00418       const gp_Pnt& aP=aIt.Value();
00419       //
00420       myClsf->SetPnt(aP);
00421       myClsf->Perform();
00422       iErr=myClsf->ErrorStatus();
00423       if (iErr) {
00424         myErrorStatus=40; // point can not be classified
00425         return;
00426       }
00427       //
00428       aSt=myClsf->State();
00429       //
00430       bIsToBreak=aSC.AppendState(aSt);
00431       if (bIsToBreak) {
00432         break;
00433       }
00434     }
00435     //
00436     aSt=aSC.State();
00437     //
00438     bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
00439     if (myShapeType==TopAbs_EDGE) {
00440       if (bIsConformState) {
00441         myMSS.Add(aE, aSt);
00442       }
00443     }
00444     else if (bIsConformState || aSt==TopAbs_ON) {
00445       myMSS.Add(aE, aSt);
00446     }
00447   } //  for (i=1; i<=aNb; ++i) next edge
00448 }
00449 //=======================================================================
00450 //function : ProcessFaces
00451 //purpose  :
00452 //=======================================================================
00453   void GEOMAlgo_FinderShapeOn2::ProcessFaces()
00454 {
00455   myErrorStatus=0;
00456   //
00457   Standard_Boolean bIsConformState, bIsToBreak, bCanBeON;
00458   Standard_Integer i, aNbF, iCnt, iErr;
00459   TopAbs_State aSt;
00460   TopTools_IndexedMapOfShape aM;
00461   TopExp_Explorer aExp;
00462   GEOMAlgo_ListIteratorOfListOfPnt aIt;
00463   //
00464   TopExp::MapShapes(myShape, TopAbs_FACE, aM);
00465   aNbF=aM.Extent();
00466   for (i=1; i<=aNbF; ++i) {
00467     GEOMAlgo_StateCollector aSC;
00468     GEOMAlgo_ListOfPnt aLP;
00469     //
00470     const TopoDS_Face& aF=TopoDS::Face(aM(i));
00471     //
00472     if (myState==GEOMAlgo_ST_ON) {
00473       Handle(Geom_Surface) aS;
00474       //
00475       aS=BRep_Tool::Surface(aF);
00476       bCanBeON=myClsf->CanBeON(aS);
00477       if(!bCanBeON) {
00478         continue;
00479       }
00480     }
00481     //
00482     aExp.Init(aF, TopAbs_EDGE);
00483     for (; aExp.More(); aExp.Next()) {
00484       const TopoDS_Shape& aE=aExp.Current();
00485       bIsConformState=myMSS.Contains(aE);
00486       if (!bIsConformState) {
00487         break;// edge has non-conformed state
00488       }
00489       else {
00490         aSt=myMSS.FindFromKey(aE);
00491         aSC.AppendState(aSt);
00492       }
00493     }
00494     //
00495     if (!bIsConformState) {
00496       continue; // edge has non-conformed state,skip face
00497     }
00498     //
00499     InnerPoints(aF, aLP);
00500     if (myErrorStatus) {
00501       return;
00502     }
00503     //
00504     bIsConformState=Standard_True;
00505     aIt.Initialize(aLP);
00506     for (iCnt=0; aIt.More(); aIt.Next(), ++iCnt) {
00507       if (myNbPntsMax) {
00508         if (iCnt > myNbPntsMax) {
00509           break;
00510         }
00511       }
00512       //
00513       const gp_Pnt& aP=aIt.Value();
00514       //
00515       myClsf->SetPnt(aP);
00516       myClsf->Perform();
00517       iErr=myClsf->ErrorStatus();
00518       if (iErr) {
00519         myErrorStatus=40; // point can not be classified
00520         return;
00521       }
00522       //
00523       aSt=myClsf->State();
00524       //
00525       bIsToBreak=aSC.AppendState(aSt);
00526       if (bIsToBreak) {
00527         break;
00528       }
00529     }
00530     //
00531     aSt=aSC.State();
00532     //
00533     bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
00534     if (myShapeType==TopAbs_FACE) {
00535       if (bIsConformState) {
00536         myMSS.Add(aF, aSt);
00537       }
00538     }
00539     else if (bIsConformState || aSt==TopAbs_ON) {
00540       myMSS.Add(aF, aSt);
00541     }
00542   }//  for (i=1; i<=aNb; ++i) next face
00543 }
00544 //=======================================================================
00545 //function : ProcessSolids
00546 //purpose  :
00547 //=======================================================================
00548   void GEOMAlgo_FinderShapeOn2::ProcessSolids()
00549 {
00550   myErrorStatus=0;
00551   //
00552   Standard_Boolean bIsConformState;
00553   Standard_Integer i, aNbS, j, aNbF;
00554   TopTools_IndexedMapOfShape aM, aMF;
00555   TopAbs_State aSt;
00556   //
00557   TopExp::MapShapes(myShape, TopAbs_SOLID, aM);
00558   aNbS=aM.Extent();
00559   for (i=1; i<=aNbS; ++i) {
00560     GEOMAlgo_StateCollector aSC;
00561     //
00562     const TopoDS_Shape& aSd=aM(i);
00563     aMF.Clear();
00564     TopExp::MapShapes(aSd, TopAbs_FACE, aMF);
00565     aNbF=aMF.Extent();
00566     for (j=1; j<=aNbF; ++j) {
00567       const TopoDS_Shape& aF=aMF(j);
00568       bIsConformState=myMSS.Contains(aF);
00569       if (!bIsConformState) {
00570         break;// face has non-conformed state
00571       }
00572       else {
00573         aSt=myMSS.FindFromKey(aF);
00574         aSC.AppendState(aSt);
00575       }
00576     }
00577     //
00578     if (!bIsConformState) {
00579       continue; // face has non-conformed state,skip solid
00580     }
00581     //
00582     aSt=aSC.State();
00583     //
00584     bIsConformState=GEOMAlgo_SurfaceTools::IsConformState(aSt, myState);
00585     if (bIsConformState) {
00586       myMSS.Add(aSd, aSt);
00587     }
00588   }
00589 }
00590 //
00591 //=======================================================================
00592 //function : InnerPoints
00593 //purpose  :
00594 //=======================================================================
00595   void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Face& aF,
00596                                           GEOMAlgo_ListOfPnt& aLP)
00597 {
00598   myErrorStatus=0;
00599   //
00600   Standard_Integer j, j1, j2, k, n[4], aNbLinks, aNx, aNb, iCnt;//, aNbMax, *pIds;
00601   TopLoc_Location aLoc;
00602   Handle(Poly_Triangulation) aTRF;
00603   TColStd_MapOfInteger aMBN;
00604   GEOMAlgo_DataMapOfPassKeyInteger aMPKI;
00605   GEOMAlgo_DataMapIteratorOfDataMapOfPassKeyInteger aIt;
00606   gp_Pnt aP, aP1, aP2;
00607   //
00608   aLP.Clear();
00609   //
00610   aTRF=BRep_Tool::Triangulation(aF, aLoc);
00611   if (aTRF.IsNull()) {
00612     if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aF)) {
00613       myWarningStatus=20; // no triangulation found
00614       return;
00615     }
00616     aTRF=BRep_Tool::Triangulation(aF, aLoc);
00617   }
00618   //
00619   const gp_Trsf& aTrsf=aLoc.Transformation();
00620   const Poly_Array1OfTriangle& aTrs=aTRF->Triangles();
00621   const TColgp_Array1OfPnt& aNodes=aTRF->Nodes();
00622   //
00623   // map link/nbtriangles
00624   j1=aTrs.Lower();
00625   j2=aTrs.Upper();
00626   for (j=j1; j<=j2; ++j) {
00627     const Poly_Triangle& aTr=aTrs(j);
00628     aTr.Get(n[0], n[1], n[2]);
00629     n[3]=n[0];
00630     for (k=0; k<3; ++k) {
00631       GEOMAlgo_PassKey aPK;
00632       //
00633       aPK.SetIds(n[k], n[k+1]);
00634       if (aMPKI.IsBound(aPK)) {
00635         Standard_Integer& iCntX=aMPKI.ChangeFind(aPK);
00636         ++iCntX;
00637       }
00638       else {
00639         aMPKI.Bind(aPK, 1);
00640       }
00641     }
00642   }
00643   //
00644   // boundary nodes aMBN
00645   aNbLinks=aMPKI.Extent();
00646   aIt.Initialize(aMPKI);
00647   for (; aIt.More(); aIt.Next()) {
00648     iCnt=aIt.Value();
00649     if (iCnt==1) {
00650       const GEOMAlgo_PassKey& aPK=aIt.Key();
00651       //qf
00652       /*
00653       aNbMax=aPK.NbMax();
00654       pIds=(Standard_Integer*)aPK.Key();
00655       for (k=1; k<3; ++k) {
00656         aNx=*(pIds+aNbMax-k);
00657         aMBN.Add(aNx);
00658       }
00659       */
00660       aNx=(Standard_Integer)aPK.Id(1);
00661       aMBN.Add(aNx);
00662       aNx=(Standard_Integer)aPK.Id(2);
00663       aMBN.Add(aNx);
00664       //qt
00665     }
00666   }
00667   //
00668   // inner nodes=all_nodes - boundary_nodes
00669   j1=aNodes.Lower();
00670   j2=aNodes.Upper();
00671   for (j=j1; j<=j2; ++j) {
00672     if (!aMBN.Contains(j)) {
00673       aP=aNodes(j).Transformed(aTrsf);
00674       aLP.Append(aP);
00675     }
00676   }
00677   //
00678   aNb=aLP.Extent();
00679   //
00680   if (!aNb && myNbPntsMin) {
00681     // try to fill it yourself
00682     Standard_Boolean bIsDone;
00683     Standard_Integer aN1, aN2;
00684     Handle(Geom_Surface) aS;
00685     GeomAdaptor_Surface aGAS;
00686     GeomAbs_SurfaceType aType;
00687     //
00688     aS=BRep_Tool::Surface(aF);
00689     aGAS.Load(aS);
00690     aType=aGAS.GetType();
00691     if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder) {
00692       // inner links
00693       aNbLinks=aMPKI.Extent();
00694       aIt.Initialize(aMPKI);
00695       for (; aIt.More(); aIt.Next()) {
00696         iCnt=aIt.Value();
00697         if (iCnt>1) {
00698           // take the first having occured inner link
00699           // and discretize it
00700           const GEOMAlgo_PassKey& aPK=aIt.Key();
00701           //qf
00702           /*
00703           aNbMax=aPK.NbMax();
00704           pIds=(Standard_Integer*)aPK.Key();
00705           aN1=*(pIds+aNbMax-1);
00706           aN2=*(pIds+aNbMax-2);
00707           */
00708           //
00709           aN1=(Standard_Integer)aPK.Id(1);
00710           aN2=(Standard_Integer)aPK.Id(2);
00711           //qt
00712           aP1=aNodes(aN1).Transformed(aTrsf);
00713           aP2=aNodes(aN2).Transformed(aTrsf);
00714           //
00715           if (aType==GeomAbs_Cylinder) {
00716             Standard_Real aTolSM;
00717             gp_Cylinder aCyl;
00718             //
00719             aTolSM=1.523e-6;//~1.-cos(0.1 deg)
00720             aCyl=aGAS.Cylinder();
00721             if (!GEOMAlgo_SurfaceTools::IsCoaxial(aP1, aP2, aCyl, aTolSM)) {
00722               continue;
00723             }
00724           }
00725           //
00726           BRepLib_MakeEdge aBME(aP1, aP2);
00727           bIsDone=aBME.IsDone();
00728           if (!bIsDone) {
00729             myErrorStatus=30; //can not obtain the line fron the link
00730             return;
00731           }
00732           //
00733           const TopoDS_Shape& aSx=aBME.Shape();
00734           const TopoDS_Edge& aE=TopoDS::Edge(aSx);
00735           //
00736           InnerPoints(aE, myNbPntsMin, aLP);
00737           break;
00738         }// if (iCnt>1)
00739       }// for (; aIt.More(); aIt.Next())
00740     }// if (aType==GeomAbs_Plane || aType==GeomAbs_Cylinder)
00741   }// if (!aNb && myNbPntsMin) {
00742 }
00743 //=======================================================================
00744 //function : InnerPoints
00745 //purpose  :
00746 //=======================================================================
00747   void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
00748                                           GEOMAlgo_ListOfPnt& aLP)
00749 {
00750   myErrorStatus=0;
00751   //
00752   Standard_Integer j, aNbNodes, aIndex, aNb;
00753   Handle(Poly_PolygonOnTriangulation) aPTE;
00754   Handle(Poly_Triangulation) aTRE;
00755   TopLoc_Location aLoc;
00756   gp_Pnt aP;
00757   //
00758   aLP.Clear();
00759   BRep_Tool::PolygonOnTriangulation(aE, aPTE, aTRE, aLoc);
00760   if (aTRE.IsNull() || aPTE.IsNull()) {
00761     Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(aE, aLoc);
00762     if (aPE.IsNull()) {
00763       if (!GEOMAlgo_FinderShapeOn::BuildTriangulation(aE)) {
00764         myErrorStatus=20; // no triangulation found
00765         return;
00766       }
00767       aPE = BRep_Tool::Polygon3D(aE, aLoc);
00768     }
00769     const gp_Trsf& aTrsf=aLoc.Transformation();
00770     const TColgp_Array1OfPnt& aNodes=aPE->Nodes();
00771     //
00772     aNbNodes=aPE->NbNodes();
00773     Standard_Integer low = aNodes.Lower(), up = aNodes.Upper();
00774     for (j=low+1; j<up; ++j) {
00775       aP=aNodes(j).Transformed(aTrsf);
00776       aLP.Append(aP);
00777     }
00778   }
00779   else {
00780     const gp_Trsf& aTrsf=aLoc.Transformation();
00781     const TColgp_Array1OfPnt& aNodes=aTRE->Nodes();
00782     //
00783     aNbNodes=aPTE->NbNodes();
00784     const TColStd_Array1OfInteger& aInds=aPTE->Nodes();
00785     for (j=2; j<aNbNodes; ++j) {
00786       aIndex=aInds(j);
00787       aP=aNodes(aIndex).Transformed(aTrsf);
00788       aLP.Append(aP);
00789     }
00790   }
00791   //
00792   aNb=aLP.Extent();
00793   if (!aNb && myNbPntsMin) {
00794     // try to fill it yourself
00795     InnerPoints(aE, myNbPntsMin, aLP);
00796     aNb=aLP.Extent();
00797   }
00798 }
00799 //=======================================================================
00800 //function : InnerPoints
00801 //purpose  :
00802 //=======================================================================
00803   void GEOMAlgo_FinderShapeOn2::InnerPoints(const TopoDS_Edge& aE,
00804                                           const Standard_Integer aNbPntsMin,
00805                                           GEOMAlgo_ListOfPnt& aLP)
00806 {
00807   // try to fill it yourself
00808   Standard_Boolean bInf1, bInf2;
00809   Standard_Integer j, aNbT;
00810   Standard_Real dT, aT, aT1, aT2;
00811   gp_Pnt aP;
00812   Handle(Geom_Curve) aC3D;
00813   //
00814   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
00815   if (aC3D.IsNull()) {
00816     return;
00817   }
00818   //
00819   bInf1=Precision::IsNegativeInfinite(aT1);
00820   bInf2=Precision::IsPositiveInfinite(aT2);
00821   if (bInf1 || bInf2) {
00822     return;
00823   }
00824   //
00825   aNbT=myNbPntsMin+1;
00826   dT=(aT2-aT1)/aNbT;
00827   for (j=1; j<=aNbPntsMin; ++j) {
00828     aT=aT1+j*dT;
00829     aC3D->D0(aT, aP);
00830     aLP.Append(aP);
00831   }
00832 }
00833 
00834 //
00835 // myErrorStatus :
00836 //
00837 // 10 -myClsf=NULL
00838 // 11 -myShape=NULL
00839 // 12 -unallowed type of sub-shapes
00840 // 13 -unallowed state
00841 // 15 -unallowed surface type
00842 // 20- no triangulation found
00843 // 30- can not obtain the line from the link
00844 // 40- point can not be classified
00845 // 41- invalid data for classifier