Back to index

salome-geom  6.5.0
BlockFix_CheckTool.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:      BlockFix_CheckTool.cxx
00024 //  Created:   17.12.04 11:15:25
00025 //  Author:    Sergey KUUL
00026 //
00027 #include <BlockFix_CheckTool.ixx>
00028 
00029 //#include <BlockFix_UnionEdges.hxx>
00030 //#include <BlockFix_UnionFaces.hxx>
00031 
00032 #include <BRep_Tool.hxx>
00033 
00034 #include <TopExp.hxx>
00035 #include <TopExp_Explorer.hxx>
00036 #include <TopoDS.hxx>
00037 #include <TopoDS_Edge.hxx>
00038 #include <TopoDS_Face.hxx>
00039 #include <TopoDS_Solid.hxx>
00040 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00041 #include <TopTools_MapOfShape.hxx>
00042 #include <TopTools_ListOfShape.hxx>
00043 #include <TopTools_ListIteratorOfListOfShape.hxx>
00044 
00045 
00046 //=======================================================================
00047 //function : BlockFix_CheckTool()
00048 //purpose  : Constructor
00049 //=======================================================================
00050 
00051 BlockFix_CheckTool::BlockFix_CheckTool( )
00052 {
00053   myHasCheck = Standard_False;
00054   myPossibleBlocks.Clear();
00055 }
00056 
00057 
00058 //=======================================================================
00059 //function : SetShape
00060 //purpose  :
00061 //=======================================================================
00062 
00063 void BlockFix_CheckTool::SetShape(const TopoDS_Shape& aShape)
00064 {
00065   myHasCheck = Standard_False;
00066   myShape = aShape;
00067   myPossibleBlocks.Clear();
00068 }
00069 
00070 
00071 //=======================================================================
00072 //function : Perform
00073 //purpose  :
00074 //=======================================================================
00075 
00076 void BlockFix_CheckTool::Perform()
00077 {
00078   myNbSolids=0;
00079   myNbBlocks=0;
00080   myNbDegen=0;
00081   myNbUF=0;
00082   myNbUE=0;
00083   myNbUFUE=0;
00084 
00085   TopExp_Explorer exps (myShape, TopAbs_SOLID);
00086   TopTools_MapOfShape mapS;
00087   for (; exps.More(); exps.Next()) {
00088     TopoDS_Solid aSolid = TopoDS::Solid(exps.Current());
00089     if (!mapS.Add(aSolid)) continue;
00090     myNbSolids++;
00091     Standard_Boolean IsBlock=Standard_True;
00092     Standard_Boolean MayBeUF=Standard_False;
00093     Standard_Boolean MayBeUE=Standard_False;
00094     Standard_Integer nf=0;
00095     TopExp_Explorer expf (aSolid, TopAbs_FACE);
00096     TopTools_MapOfShape mapF;
00097     for (; expf.More(); expf.Next()) {
00098       if (mapF.Add(expf.Current()))
00099         nf++;
00100     }
00101 
00102     if (nf < 6) {
00103       IsBlock = Standard_False;
00104     }
00105     else if (nf > 6) {
00106       IsBlock = Standard_False;
00107       // check faces unification
00108       TopTools_SequenceOfShape faces;
00109       mapF.Clear();
00110       for (expf.Init(aSolid, TopAbs_FACE); expf.More(); expf.Next()) {
00111         if (mapF.Add(expf.Current())) {
00112           TopoDS_Face aFace = TopoDS::Face(expf.Current());
00113           faces.Append(aFace);
00114         }
00115       }
00116       Standard_Boolean HasFacesForUnification = Standard_False;
00117       for (Standard_Integer i=1; i<faces.Length() && !HasFacesForUnification; i++) {
00118         TopoDS_Face F1 = TopoDS::Face(faces.Value(i));
00119         TopTools_MapOfShape Edges;
00120         for (TopExp_Explorer expe(F1,TopAbs_EDGE); expe.More(); expe.Next())
00121           Edges.Add(expe.Current().Oriented(TopAbs_FORWARD));
00122         TopLoc_Location L1;
00123         Handle(Geom_Surface) S1 = BRep_Tool::Surface(F1,L1);
00124         for(Standard_Integer j=i+1; j<=faces.Length() && !HasFacesForUnification; j++) {
00125           TopoDS_Face F2 = TopoDS::Face(faces.Value(j));
00126           TopLoc_Location L2;
00127           Handle(Geom_Surface) S2 = BRep_Tool::Surface(F2,L2);
00128           if( S1==S2 && L1==L2 ) {
00129             // faces have equal based surface
00130             // now check common edge
00131             for(TopExp_Explorer expe2(F2,TopAbs_EDGE); expe2.More(); expe2.Next()) {
00132               if(Edges.Contains(expe2.Current().Oriented(TopAbs_FORWARD))) {
00133                 HasFacesForUnification = Standard_True;
00134                 break;
00135               }
00136             }
00137           }
00138         }
00139       }
00140       if (HasFacesForUnification) {
00141         MayBeUF=Standard_True;
00142       }
00143     }
00144 
00145     Standard_Integer nbe=0;
00146     TopTools_MapOfShape DegenEdges;
00147     TopExp_Explorer expe (aSolid, TopAbs_EDGE);
00148     TopTools_MapOfShape mapE;
00149     for (; expe.More(); expe.Next()) {
00150       TopoDS_Edge E = TopoDS::Edge(expe.Current());
00151       if (!mapE.Add(E)) continue;
00152       if (BRep_Tool::Degenerated(E)) {
00153         DegenEdges.Add(E);
00154       }
00155       else {
00156         nbe++;
00157       }
00158     }
00159     if (nbe == 12 && DegenEdges.Extent() > 0) {
00160       IsBlock = Standard_False;
00161       myNbDegen++;
00162       myPossibleBlocks.Append(aSolid);
00163       continue;
00164     }
00165     if (nbe < 12)
00166       IsBlock = Standard_False;
00167     if (nbe > 12) {
00168       IsBlock = Standard_False;
00169       // check edges unification
00170       // creating map of edge faces
00171       TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
00172       TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
00173 
00174       mapF.Clear();
00175       for (expf.Init(aSolid, TopAbs_FACE); expf.More(); expf.Next()) {
00176         TopoDS_Face aFace = TopoDS::Face(expf.Current());
00177         if (!mapF.Add(aFace)) continue;
00178         TopTools_IndexedDataMapOfShapeListOfShape aMapFacesEdges;
00179 
00180         TopTools_MapOfShape mapEe;
00181         for (expe.Init(aFace, TopAbs_EDGE); expe.More(); expe.Next()) {
00182           TopoDS_Edge edge = TopoDS::Edge(expe.Current());
00183           if (!mapEe.Add(edge)) continue;
00184           if (!aMapEdgeFaces.Contains(edge)) continue;
00185           const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
00186           TopTools_ListIteratorOfListOfShape anIter (aList);
00187           for (; anIter.More(); anIter.Next()) {
00188             TopoDS_Face face = TopoDS::Face(anIter.Value());
00189             if (face.IsSame(aFace)) continue;
00190             if (aMapFacesEdges.Contains(face)) {
00191               aMapFacesEdges.ChangeFromKey(face).Append(edge);
00192             }
00193             else {
00194               TopTools_ListOfShape ListEdges;
00195               ListEdges.Append(edge);
00196               aMapFacesEdges.Add(face,ListEdges);
00197             }
00198           }
00199         }
00200         Standard_Integer i = 1;
00201         for (; i <= aMapFacesEdges.Extent(); i++) {
00202           const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i);
00203           if (ListEdges.Extent() > 1) break;
00204         }
00205         if (i <= aMapFacesEdges.Extent()) {
00206           MayBeUE = Standard_True;
00207           break;
00208         }
00209       }
00210     }
00211 
00212     if (IsBlock)
00213       myNbBlocks++;
00214     else {
00215       if (MayBeUF) {
00216         myPossibleBlocks.Append(aSolid);
00217         if (MayBeUE)
00218           myNbUFUE++;
00219         else
00220           myNbUF++;
00221       }
00222       else if (MayBeUE) {
00223         myNbUE++;
00224         myPossibleBlocks.Append(aSolid);
00225       }
00226     }
00227   }
00228 
00229   myHasCheck = Standard_True;
00230 }
00231 
00232 
00233 //=======================================================================
00234 //function : NbPossibleBlocks
00235 //purpose  :
00236 //=======================================================================
00237 
00238 Standard_Integer BlockFix_CheckTool::NbPossibleBlocks() const
00239 {
00240   return myPossibleBlocks.Length();
00241 }
00242 
00243 
00244 //=======================================================================
00245 //function : PossibleBlock
00246 //purpose  :
00247 //=======================================================================
00248 
00249 TopoDS_Shape BlockFix_CheckTool::PossibleBlock(const Standard_Integer num) const
00250 {
00251   TopoDS_Shape res;
00252   if( num>0 && num<=myPossibleBlocks.Length() )
00253     res = myPossibleBlocks.Value(num);
00254   return res;
00255 }
00256 
00257 
00258 //=======================================================================
00259 //function : DumpCheckResult
00260 //purpose  :
00261 //=======================================================================
00262 
00263 void BlockFix_CheckTool::DumpCheckResult(Standard_OStream& S) const
00264 {
00265   if(!myHasCheck)
00266     S<<"Check not performed!"<<endl;
00267   else {
00268     S<<"dump results of check:"<<endl;
00269     S<<"  total number of solids = "<<myNbSolids<<endl;
00270     S<<"  including: number of good blocks = "<<myNbBlocks<<endl;
00271     S<<"             number of possible blocks = "<<NbPossibleBlocks()<<endl;
00272     S<<"             including: need remove degenerative = "<<myNbDegen<<endl;
00273     S<<"                        need unionfaces = "<<myNbUF<<endl;
00274     S<<"                        need unionedges = "<<myNbUE<<endl;
00275     S<<"                        need both unionfaces and unionedges = "<<myNbUFUE<<endl;
00276     Standard_Integer nbtmp = myNbSolids - myNbBlocks - NbPossibleBlocks();
00277     S<<"             number of impossible blocks = "<<nbtmp<<endl;
00278   }
00279 }