Back to index

salome-geom  6.5.0
GEOMAlgo_GlueDetector.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_GlueDetector.cxx
00024 // Author:      Peter KURNEV
00025 
00026 #include <GEOMAlgo_GlueDetector.hxx>
00027 
00028 #include <Bnd_Box.hxx>
00029 #include <NCollection_UBTreeFiller.hxx>
00030 
00031 #include <TColStd_ListOfInteger.hxx>
00032 #include <TColStd_ListIteratorOfListOfInteger.hxx>
00033 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
00034 
00035 #include <TopoDS_Shape.hxx>
00036 #include <TopoDS_Face.hxx>
00037 #include <TopoDS_Edge.hxx>
00038 #include <TopoDS_Compound.hxx>
00039 #include <TopoDS_Vertex.hxx>
00040 #include <TopoDS_Iterator.hxx>
00041 #include <TopoDS_Compound.hxx>
00042 
00043 #include <TopTools_IndexedMapOfShape.hxx>
00044 #include <TopTools_ListOfShape.hxx>
00045 #include <TopTools_ListIteratorOfListOfShape.hxx>
00046 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
00047 #include <TopTools_MapOfShape.hxx>
00048 #include <TopTools_MapIteratorOfMapOfShape.hxx>
00049 
00050 #include <TopExp.hxx>
00051 #include <BRep_Tool.hxx>
00052 #include <BRep_Builder.hxx>
00053 #include <BRepBndLib.hxx>
00054 
00055 #include <NMTDS_BndSphereTree.hxx>
00056 #include <NMTDS_BndSphere.hxx>
00057 #include <NMTDS_IndexedDataMapOfShapeBndSphere.hxx>
00058 
00059 #include <GEOMAlgo_IndexedDataMapOfIntegerShape.hxx>
00060 #include <GEOMAlgo_PassKeyShape.hxx>
00061 #include <GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx>
00062 #include <GEOMAlgo_Tools.hxx>
00063 //
00064 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00065 #include <TopExp.hxx>
00066 #include <TopExp_Explorer.hxx>
00067 #include <TopTools_MapOfShape.hxx>
00068 
00069 //modified by NIZNHY-PKV Tue Mar 13 10:25:47 2012f
00070 static
00071   Standard_Integer CheckAncesstors
00072   (const TopoDS_Shape& aVSD,
00073    const TopTools_MapOfShape& aMVSD,
00074    const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
00075    const TopTools_IndexedDataMapOfShapeListOfShape& aMEV,
00076    TopTools_IndexedDataMapOfShapeListOfShape& aMEVZ);
00077 //modified by NIZNHY-PKV Tue Mar 13 10:25:50 2012t
00078 
00079 //=======================================================================
00080 //function :
00081 //purpose  :
00082 //=======================================================================
00083 GEOMAlgo_GlueDetector::GEOMAlgo_GlueDetector()
00084 :
00085   GEOMAlgo_GluerAlgo(),
00086   GEOMAlgo_Algo()
00087 {}
00088 //=======================================================================
00089 //function : ~
00090 //purpose  :
00091 //=======================================================================
00092 GEOMAlgo_GlueDetector::~GEOMAlgo_GlueDetector()
00093 {}
00094 //modified by NIZNHY-PKV Tue Mar 13 12:26:50 2012f
00095 //=======================================================================
00096 //function : StickedShapes
00097 //purpose  :
00098 //=======================================================================
00099 const TopTools_IndexedDataMapOfShapeListOfShape&
00100   GEOMAlgo_GlueDetector::StickedShapes()
00101 {
00102   return myStickedShapes;
00103 }
00104 //modified by NIZNHY-PKV Tue Mar 13 12:26:54 2012t
00105 //=======================================================================
00106 //function : Perform
00107 //purpose  :
00108 //=======================================================================
00109 void GEOMAlgo_GlueDetector::Perform()
00110 {
00111   myErrorStatus=0;
00112   myWarningStatus=0;
00113   myStickedShapes.Clear();
00114   //
00115   CheckData();
00116   if (myErrorStatus) {
00117     return;
00118   }
00119   //
00120   // Initialize the context
00121   GEOMAlgo_GluerAlgo::Perform();
00122   //
00123   DetectVertices();
00124   if (myErrorStatus) {
00125     return;
00126   }
00127   //
00128   //modified by NIZNHY-PKV Wed Mar 14 08:00:09 2012f
00129   CheckDetected();
00130   if (myErrorStatus) {
00131     return;
00132   }
00133   //modified by NIZNHY-PKV Wed Mar 14 08:00:12 2012t
00134   //
00135   DetectEdges();
00136   if (myErrorStatus) {
00137     return;
00138   }
00139   //
00140   DetectFaces();
00141   if (myErrorStatus) {
00142     return;
00143   }
00144 }
00145 //=======================================================================
00146 //function : DetectVertices
00147 //purpose  :
00148 //=======================================================================
00149 void GEOMAlgo_GlueDetector::DetectVertices()
00150 {
00151   Standard_Integer j, i, aNbV, aNbVSD;
00152   Standard_Real aTolV;
00153   gp_Pnt aPV;
00154   TColStd_ListIteratorOfListOfInteger aIt;
00155   TopoDS_Shape aVF;
00156   TopTools_IndexedMapOfShape aMV;
00157   TopTools_MapOfShape aMVProcessed;
00158   TopTools_ListIteratorOfListOfShape aItS;
00159   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
00160   TopTools_DataMapOfShapeListOfShape aMVV;
00161   GEOMAlgo_IndexedDataMapOfIntegerShape aMIS;
00162   NMTDS_IndexedDataMapOfShapeBndSphere aMSB;
00163   NMTDS_BndSphereTreeSelector aSelector;
00164   NMTDS_BndSphereTree aBBTree;
00165   NCollection_UBTreeFiller <Standard_Integer, NMTDS_BndSphere> aTreeFiller(aBBTree);
00166   //
00167   myErrorStatus=0;
00168   //
00169   TopExp::MapShapes(myArgument, TopAbs_VERTEX, aMV);
00170   aNbV=aMV.Extent();
00171   if (!aNbV) {
00172     myErrorStatus=2; // no vertices in source shape
00173     return;
00174   }
00175   //
00176   for (i=1; i<=aNbV; ++i) {
00177     NMTDS_BndSphere aBox;
00178     //
00179     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aMV(i));
00180     aPV=BRep_Tool::Pnt(aV);
00181     aTolV=BRep_Tool::Tolerance(aV);
00182     //
00183     aBox.SetGap(myTolerance);
00184     aBox.SetCenter(aPV);
00185     aBox.SetRadius(aTolV);
00186     //
00187     aTreeFiller.Add(i, aBox);
00188     //
00189     aMIS.Add(i, aV);
00190     aMSB.Add(aV, aBox);
00191   }
00192   //
00193   aTreeFiller.Fill();
00194   //
00195   //---------------------------------------------------
00196   // Chains
00197   for (i=1; i<=aNbV; ++i) {
00198     const TopoDS_Shape& aV=aMV(i);
00199     //
00200     if (aMVProcessed.Contains(aV)) {
00201       continue;
00202     }
00203     //
00204     Standard_Integer aNbIP, aIP, aNbIP1, aIP1;
00205     TopTools_ListOfShape aLVSD;
00206     TColStd_MapOfInteger aMIP, aMIP1, aMIPC;
00207     TColStd_MapIteratorOfMapOfInteger aIt1;
00208     //
00209     aMIP.Add(i);
00210     while(1) {
00211       aNbIP=aMIP.Extent();
00212       aIt1.Initialize(aMIP);
00213       for(; aIt1.More(); aIt1.Next()) {
00214         aIP=aIt1.Key();
00215         if (aMIPC.Contains(aIP)) {
00216           continue;
00217         }
00218         //
00219         const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
00220         const NMTDS_BndSphere& aBoxVP=aMSB.FindFromKey(aVP);
00221         //
00222         aSelector.Clear();
00223         aSelector.SetBox(aBoxVP);
00224         //
00225         aNbVSD=aBBTree.Select(aSelector);
00226         if (!aNbVSD) {
00227           continue;  // it shoild not be so [at least IP itself]
00228         }
00229         //
00230         const TColStd_ListOfInteger& aLI=aSelector.Indices();
00231         aIt.Initialize(aLI);
00232         for (; aIt.More(); aIt.Next()) {
00233           aIP1=aIt.Value();
00234           if (aMIP.Contains(aIP1)) {
00235             continue;
00236           }
00237           aMIP1.Add(aIP1);
00238         } //for (; aIt.More(); aIt.Next()) {
00239       }//for(; aIt1.More(); aIt1.Next()) {
00240       //
00241       aNbIP1=aMIP1.Extent();
00242       if (!aNbIP1) {
00243         break;
00244       }
00245       //
00246       aIt1.Initialize(aMIP);
00247       for(; aIt1.More(); aIt1.Next()) {
00248         aIP=aIt1.Key();
00249         aMIPC.Add(aIP);
00250       }
00251       //
00252       aMIP.Clear();
00253       aIt1.Initialize(aMIP1);
00254       for(; aIt1.More(); aIt1.Next()) {
00255         aIP=aIt1.Key();
00256         aMIP.Add(aIP);
00257       }
00258       aMIP1.Clear();
00259     }// while(1)
00260     //
00261     // Fill myImages
00262     aNbIP=aMIPC.Extent();
00263     //
00264     if (!aNbIP) {// no SD vertices is found
00265       aMVProcessed.Add(aV);
00266       continue;
00267     }
00268     //else { // SD vertices founded [ aMIPC ]
00269     aIt1.Initialize(aMIPC);
00270     for(j=0; aIt1.More(); aIt1.Next(), ++j) {
00271       aIP=aIt1.Key();
00272       const TopoDS_Shape& aVP=aMIS.FindFromKey(aIP);
00273       if (!j) {
00274         aVF=aVP;
00275       }
00276       aLVSD.Append(aVP);
00277       aMVProcessed.Add(aVP);
00278     }
00279     //}
00280     myImages.Bind(aVF, aLVSD);
00281   }// for (i=1; i<=aNbV; ++i) {
00282   //------------------------------
00283   // Origins
00284   aItIm.Initialize(myImages);
00285   for (; aItIm.More(); aItIm.Next()) {
00286     const TopoDS_Shape& aV=aItIm.Key();
00287     const TopTools_ListOfShape& aLVSD=aItIm.Value();
00288     aItS.Initialize(aLVSD);
00289     for (; aItS.More(); aItS.Next()) {
00290       const TopoDS_Shape& aVSD=aItS.Value();
00291       if (!myOrigins.IsBound(aVSD)) {
00292         myOrigins.Bind(aVSD, aV);
00293       }
00294     }
00295   }
00296 }
00297 //=======================================================================
00298 //function : DetectFaces
00299 //purpose  :
00300 //=======================================================================
00301 void GEOMAlgo_GlueDetector::DetectFaces()
00302 {
00303   DetectShapes(TopAbs_FACE);
00304 }
00305 //=======================================================================
00306 //function : DetectEdges
00307 //purpose  :
00308 //=======================================================================
00309 void GEOMAlgo_GlueDetector::DetectEdges()
00310 {
00311   DetectShapes(TopAbs_EDGE);
00312 }
00313 //=======================================================================
00314 //function : DetectShapes
00315 //purpose  :
00316 //=======================================================================
00317 void GEOMAlgo_GlueDetector::DetectShapes(const TopAbs_ShapeEnum aType)
00318 {
00319   Standard_Boolean bDegenerated;
00320   Standard_Integer i, aNbF, aNbSDF, iErr;
00321   TopTools_IndexedMapOfShape aMF;
00322   TopTools_ListIteratorOfListOfShape aItLS;
00323   GEOMAlgo_PassKeyShape aPKF;
00324   GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape aMPKLF;
00325   //
00326   myErrorStatus=0;
00327   //
00328   TopExp::MapShapes(myArgument, aType, aMF);
00329   //
00330   aNbF=aMF.Extent();
00331   for (i=1; i<=aNbF; ++i) {
00332     const TopoDS_Shape& aS=aMF(i);
00333     //
00334     if (aType==TopAbs_FACE) {
00335       const TopoDS_Face& aF=*((TopoDS_Face*)&aS);
00336       FacePassKey(aF, aPKF);
00337     }
00338     else if (aType==TopAbs_EDGE) {
00339       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aS);
00340       EdgePassKey(aE, aPKF);
00341     }
00342     //
00343     if (myErrorStatus) {
00344       return;
00345     }
00346     //
00347     if (aMPKLF.Contains(aPKF)) {
00348       TopTools_ListOfShape& aLSDF=aMPKLF.ChangeFromKey(aPKF);
00349       aLSDF.Append(aS);
00350     }
00351     else {
00352       TopTools_ListOfShape aLSDF;
00353       //
00354       aLSDF.Append(aS);
00355       aMPKLF.Add(aPKF, aLSDF);
00356     }
00357   }
00358   // check geometric coincidence
00359   if (myCheckGeometry) {
00360     iErr=GEOMAlgo_Tools::RefineSDShapes(aMPKLF, myTolerance, myContext);
00361     if (iErr) {
00362       myErrorStatus=200;
00363       return;
00364     }
00365   }
00366   //
00367   // Images/Origins
00368   aNbF=aMPKLF.Extent();
00369   for (i=1; i<=aNbF; ++i) {
00370     const TopTools_ListOfShape& aLSDF=aMPKLF(i);
00371     aNbSDF=aLSDF.Extent();
00372     if (!aNbSDF) {
00373       myErrorStatus=4; // it must not be
00374     }
00375     //
00376     if (aNbSDF==1) {
00377       continue;
00378     }
00379     //
00380     const TopoDS_Shape& aS1=aLSDF.First();
00381     //
00382     if (aType==TopAbs_EDGE) {
00383       const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aS1);
00384       bDegenerated=BRep_Tool::Degenerated(aE1);
00385       if (bDegenerated) {
00386         continue;
00387       }
00388     }
00389     //
00390     myImages.Bind(aS1, aLSDF);
00391     //
00392     // origins
00393     aItLS.Initialize(aLSDF);
00394     for (; aItLS.More(); aItLS.Next()) {
00395       const TopoDS_Shape& aFSD=aItLS.Value();
00396       if (!myOrigins.IsBound(aFSD)) {
00397         myOrigins.Bind(aFSD, aS1);
00398       }
00399     }
00400   }// for (i=1; i<=aNbF; ++i)
00401 }
00402 //=======================================================================
00403 //function : FacePassKey
00404 //purpose  :
00405 //=======================================================================
00406 void GEOMAlgo_GlueDetector::FacePassKey(const TopoDS_Face& aF,
00407                                         GEOMAlgo_PassKeyShape& aPK)
00408 {
00409   Standard_Integer i, aNbE;
00410   TopoDS_Shape aER;
00411   TopTools_ListOfShape aLE;
00412   TopTools_IndexedMapOfShape aME;
00413   //
00414   TopExp::MapShapes(aF, TopAbs_EDGE, aME);
00415   //
00416   aNbE=aME.Extent();
00417   for (i=1; i<=aNbE; ++i) {
00418     const TopoDS_Shape& aE=aME(i);
00419     //
00420     const TopoDS_Edge& aEE=*((TopoDS_Edge*)&aE);
00421     if (BRep_Tool::Degenerated(aEE)) {
00422       continue;
00423     }
00424     //
00425     if (myOrigins.IsBound(aE)) {
00426       aER=myOrigins.Find(aE);
00427     }
00428     else {
00429       aER=aE;
00430     }
00431     aLE.Append(aER);
00432   }
00433   aPK.SetShapes(aLE);
00434 }
00435 //=======================================================================
00436 //function : EdgePassKey
00437 //purpose  :
00438 //=======================================================================
00439 void GEOMAlgo_GlueDetector::EdgePassKey(const TopoDS_Edge& aE,
00440                                         GEOMAlgo_PassKeyShape& aPK)
00441 {
00442   TopAbs_Orientation aOr;
00443   TopoDS_Shape aVR;
00444   TopoDS_Iterator aIt;
00445   TopTools_ListOfShape aLV;
00446   //
00447   aIt.Initialize(aE);
00448   for (; aIt.More(); aIt.Next()) {
00449     const TopoDS_Shape& aV=aIt.Value();
00450     aOr=aV.Orientation();
00451     if (aOr==TopAbs_FORWARD || aOr==TopAbs_REVERSED) {
00452       if (myOrigins.IsBound(aV)) {
00453         aVR=myOrigins.Find(aV);
00454       }
00455       else {
00456         aVR=aV;
00457       }
00458       aLV.Append(aVR);
00459     }
00460   }
00461   //
00462   aPK.SetShapes(aLV);
00463 }
00464 //modified by NIZNHY-PKV Tue Mar 13 09:54:18 2012f
00465 //=======================================================================
00466 //function : CheckDetected
00467 //purpose  :
00468 //=======================================================================
00469 void GEOMAlgo_GlueDetector::CheckDetected()
00470 {
00471   TopoDS_Iterator aItA;
00472   TopExp_Explorer aExp;
00473   TopTools_ListOfShape aLV;
00474   TopTools_MapOfShape aMFence;
00475   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItIm;
00476   TopTools_IndexedDataMapOfShapeListOfShape aMVE, aMEV;
00477   //
00478   // 1. aMVE, aMEV
00479   TopExp::MapShapesAndAncestors(myArgument, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
00480   //
00481   aExp.Init(myArgument, TopAbs_EDGE);
00482   for (; aExp.More(); aExp.Next()) {
00483     const TopoDS_Shape& aE=aExp.Current();
00484     //
00485     aLV.Clear();
00486     aMFence.Clear();
00487     aItA.Initialize(aE);
00488     for (; aItA.More(); aItA.Next()) {
00489       const TopoDS_Shape& aV=aItA.Value();
00490       if (aMFence.Add(aV)) {
00491         aLV.Append(aV);
00492       }
00493     }
00494     //
00495     aMEV.Add(aE, aLV);
00496   }
00497   // 2. Checking
00498   aItIm.Initialize(myImages);
00499   for (; aItIm.More(); aItIm.Next()) {
00500     //const TopoDS_Shape& aV=aItIm.Key();
00501     const TopTools_ListOfShape& aLVSD=aItIm.Value();
00502     CheckDetected(aLVSD, aMVE, aMEV);
00503   }
00504 }
00505 //=======================================================================
00506 //function : CheckDetected
00507 //purpose  :
00508 //=======================================================================
00509 void GEOMAlgo_GlueDetector::CheckDetected
00510   (const TopTools_ListOfShape& aLVSD,
00511    const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
00512    const TopTools_IndexedDataMapOfShapeListOfShape& aMEV)
00513 {
00514   Standard_Integer i, aNbVSD, aNbA, iRet;
00515   TopAbs_ShapeEnum aTypeS, aTypeA[2];
00516   TopExp_Explorer aExp, aExpA;
00517   TopTools_MapOfShape aMFence, aMVSD;
00518   TopTools_ListOfShape aLV;
00519   TopTools_ListIteratorOfListOfShape aItLS;
00520   //
00521   myErrorStatus=0;
00522   //
00523   aNbVSD=aLVSD.Extent();
00524   if (aNbVSD < 2) {
00525     return ;
00526   }
00527   //
00528   aItLS.Initialize(aLVSD);
00529   for (; aItLS.More(); aItLS.Next()) {
00530     const TopoDS_Shape& aVSD=aItLS.Value();
00531     aMVSD.Add(aVSD);
00532   }
00533   //
00534   aItLS.Initialize(aLVSD);
00535   for (; aItLS.More(); aItLS.Next()) {
00536     const TopoDS_Shape& aVSD=aItLS.Value();
00537     //
00538     iRet=CheckAncesstors(aVSD, aMVSD, aMVE, aMEV, myStickedShapes);
00539     if (iRet) {
00540       // Sticked shapes detected
00541       myWarningStatus=2;
00542     }
00543   }
00544 }
00545 //=======================================================================
00546 //function : CheckAncesstors
00547 //purpose  :
00548 //=======================================================================
00549 Standard_Integer CheckAncesstors
00550   (const TopoDS_Shape& aVSD,
00551    const TopTools_MapOfShape& aMVSD,
00552    const TopTools_IndexedDataMapOfShapeListOfShape& aMVE,
00553    const TopTools_IndexedDataMapOfShapeListOfShape& aMEV,
00554    TopTools_IndexedDataMapOfShapeListOfShape& aMEVZ)
00555 {
00556   Standard_Address pLE, pLV, pLVZ;
00557   Standard_Integer iRet, aNbVX;
00558   TopTools_ListIteratorOfListOfShape aItLE, aItLV;
00559   TopTools_MapOfShape aMFence;
00560   TopTools_ListOfShape aLVX;
00561   //
00562   iRet=0;
00563   //
00564   pLE=aMVE.FindFromKey1(aVSD);
00565   if (!pLE) {
00566     return iRet;
00567   }
00568   //
00569   const TopTools_ListOfShape& aLE=*((TopTools_ListOfShape*)pLE);
00570   aItLE.Initialize(aLE);
00571   for (; aItLE.More(); aItLE.Next()) {
00572     const TopoDS_Shape& aE=aItLE.Value();
00573     //
00574     pLV=aMEV.FindFromKey1(aE);
00575     if (!pLV) {
00576       continue; // it should be not so
00577     }
00578     //
00579     aLVX.Clear();
00580     const TopTools_ListOfShape& aLV=*((TopTools_ListOfShape*)pLV);
00581     aItLV.Initialize(aLV);
00582     for (; aItLV.More(); aItLV.Next()) {
00583       const TopoDS_Shape& aV=aItLV.Value();
00584       if (!aV.IsSame(aVSD)) {
00585         if (aMVSD.Contains(aV)) {
00586           if (aMFence.Add(aV)) {
00587             aLVX.Append(aV);
00588           }
00589         }
00590       }
00591     }
00592     //
00593     aNbVX=aLVX.Extent();
00594     if (!aNbVX) {
00595       continue;
00596     }
00597     //
00598     iRet=1;
00599     //
00600     pLVZ=aMEVZ.FindFromKey1(aE);
00601     if (!pLVZ) {
00602       aMEVZ.Add(aE, aLVX);
00603     }
00604     else {
00605       TopTools_ListOfShape& aLVZ=*((TopTools_ListOfShape*)pLVZ);
00606       aLVZ.Append(aLVX);
00607     }
00608   }
00609   //
00610   return iRet;
00611 }
00612 //modified by NIZNHY-PKV Tue Mar 13 09:54:59 2012t