Back to index

salome-geom  6.5.0
GEOMAlgo_WESCorrector.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:        NMTAlgo_WESCorrector.cxx
00024 // Author:      Peter KURNEV
00025 
00026 #include <GEOMAlgo_WESCorrector.hxx>
00027 
00028 #include <Geom_Surface.hxx>
00029 
00030 #include <TopLoc_Location.hxx>
00031 #include <TopoDS.hxx>
00032 
00033 #include <TopoDS_Shape.hxx>
00034 #include <TopoDS_Wire.hxx>
00035 #include <TopoDS_Face.hxx>
00036 #include <TopoDS_Edge.hxx>
00037 
00038 #include <BRep_Builder.hxx>
00039 #include <BRep_Tool.hxx>
00040 #include <BRepAdaptor_Surface.hxx>
00041 
00042 #include <TopTools_IndexedMapOfOrientedShape.hxx>
00043 #include <TopTools_ListIteratorOfListOfShape.hxx>
00044 
00045 #include <BOP_ConnexityBlock.hxx>
00046 #include <BOP_ListIteratorOfListOfConnexityBlock.hxx>
00047 
00048 #include <BOPTColStd_ListOfListOfShape.hxx>
00049 #include <BOPTColStd_ListIteratorOfListOfListOfShape.hxx>
00050 
00051 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00052 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
00053 #include <TopExp.hxx>
00054 #include <TopTools_IndexedMapOfShape.hxx>
00055 #include <TopTools_MapOfShape.hxx>
00056 #include <TopTools_MapIteratorOfMapOfShape.hxx>
00057 #include <TopoDS_Iterator.hxx>
00058 #include <GEOMAlgo_WireSplitter.hxx>
00059 #include <GEOMAlgo_WESScaler.hxx>
00060 
00061 static
00062   void MakeWire(const TopTools_ListOfShape& aLE,
00063                 TopoDS_Wire& newWire);
00064 
00065 
00066 static
00067   Standard_Boolean IsToScale(const TopoDS_Face& aF,
00068                              Standard_Real& aScale);
00069 
00070 //=======================================================================
00071 // function:
00072 // purpose:
00073 //=======================================================================
00074   GEOMAlgo_WESCorrector::GEOMAlgo_WESCorrector()
00075 :
00076   GEOMAlgo_Algo()
00077 {
00078 }
00079 //=======================================================================
00080 // function: ~
00081 // purpose:
00082 //=======================================================================
00083   GEOMAlgo_WESCorrector::~GEOMAlgo_WESCorrector()
00084 {
00085 }
00086 //=======================================================================
00087 // function: SetWES
00088 // purpose:
00089 //=======================================================================
00090   void GEOMAlgo_WESCorrector::SetWES (const GEOMAlgo_WireEdgeSet& aWES)
00091 {
00092   GEOMAlgo_WireEdgeSet* pWES=(GEOMAlgo_WireEdgeSet*) &aWES;
00093   myWES=pWES;
00094 }
00095 //=======================================================================
00096 // function: WES
00097 // purpose:
00098 //=======================================================================
00099   GEOMAlgo_WireEdgeSet& GEOMAlgo_WESCorrector::WES ()
00100 {
00101   return *myWES;
00102 }
00103 //=======================================================================
00104 // function: NewWES
00105 // purpose:
00106 //=======================================================================
00107   GEOMAlgo_WireEdgeSet& GEOMAlgo_WESCorrector::NewWES ()
00108 {
00109   return myNewWES;
00110 }
00111 //=======================================================================
00112 // function: Perform
00113 // purpose:
00114 //=======================================================================
00115   void GEOMAlgo_WESCorrector::Perform()
00116 {
00117   myErrorStatus=0;
00118   //
00119   DoConnexityBlocks();
00120   DoCorrections();
00121 }
00122 //=======================================================================
00123 // function: DoConnexityBlocks
00124 // purpose:
00125 //=======================================================================
00126   void GEOMAlgo_WESCorrector::DoConnexityBlocks()
00127 {
00128   Standard_Boolean bRegular, bClosed;
00129   Standard_Integer i, aNbV, j, aNbC, aNbVP, aNbVS;
00130   TopTools_ListIteratorOfListOfShape aIt;
00131   TopoDS_Iterator aItE;
00132   TopoDS_Shape aER;
00133   TopTools_IndexedMapOfShape aMER, aMEP, aMEC, aMVP;
00134   TopTools_IndexedMapOfShape aMVS, aMVAdd;
00135   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
00136   //
00137   // 1. aMVE;
00138   const TopTools_ListOfShape& aLSE=myWES->StartElements();
00139   aIt.Initialize(aLSE);
00140   for (; aIt.More(); aIt.Next()) {
00141     const TopoDS_Shape& aE=aIt.Value();
00142     if (!aMEP.Contains(aE)) {
00143       aMEP.Add(aE);
00144       TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
00145     }
00146     else {
00147       aMER.Add(aE);
00148     }
00149   }
00150   //
00151   // 2.
00152   aNbV=aMVE.Extent();
00153   for (i=1; i<=aNbV; ++i) {
00154     const TopoDS_Shape& aV=aMVE.FindKey(i);
00155     //
00156     aNbVS=aMVS.Extent();
00157     if (aNbVS==aNbV) {
00158       break;
00159     }
00160     //
00161     if (aMVS.Contains(aV)) {
00162       continue;
00163     }
00164     aMVS.Add(aV);    // aMVS - globally processed vertices
00165     //
00166     //------------------------------------- goal: aMEC
00167     aMEC.Clear();    // aMEC - edges of CB
00168     aMVP.Clear();    // aMVP - vertices to process right now
00169     aMVAdd.Clear();  // aMVAdd vertices to process on next step of while(1)
00170     //
00171     aMVP.Add(aV);
00172     //
00173     while(1) {
00174       aNbVP=aMVP.Extent();
00175       for (j=1; j<=aNbVP; ++j) {
00176         const TopoDS_Shape& aVP=aMVP(j);
00177         const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aVP);
00178         aIt.Initialize(aLE);
00179         for (; aIt.More(); aIt.Next()) {
00180           const TopoDS_Shape& aE=aIt.Value();
00181           if (aMEC.Contains(aE)) {
00182             continue;
00183           }
00184           aMEC.Add(aE);
00185           //
00186           aItE.Initialize(aE);
00187           for (; aItE.More(); aItE.Next()) {
00188             const TopoDS_Shape& aVE=aItE.Value();
00189             if (!aMVS.Contains(aVE)) {
00190               aMVS.Add(aVE);
00191               aMVAdd.Add(aVE);
00192             }
00193           }
00194         }
00195       }//for (j=1; j<=aNbVP; ++j)
00196       //
00197       aNbVP=aMVAdd.Extent();
00198       if (!aNbVP) {
00199         break; // from while(1)
00200       }
00201       //
00202       aMVP.Clear();
00203       for (j=1; j<=aNbVP; ++j) {
00204         const TopoDS_Shape& aVE=aMVAdd(j);
00205         aMVP.Add(aVE);
00206       }
00207       aMVAdd.Clear();
00208     }// while(1) {
00209     //-------------------------------------
00210     BOP_ConnexityBlock aCB;
00211     TopTools_ListOfShape aLEC;
00212     TopTools_IndexedDataMapOfShapeListOfShape aMVER;
00213     //
00214     bRegular=Standard_True;
00215     //
00216     aNbC=aMEC.Extent();
00217     for (j=1; j<=aNbC; ++j) {
00218       aER=aMEC(j);
00219       //
00220       if (aMER.Contains(aER)) {
00221         aER.Orientation(TopAbs_FORWARD);
00222         aLEC.Append(aER);
00223         aER.Orientation(TopAbs_REVERSED);
00224         aLEC.Append(aER);
00225         //
00226         bRegular=Standard_False;
00227       }
00228       else {
00229         aLEC.Append(aER);
00230       }
00231       //
00232       if (bRegular) {
00233         const  TopoDS_Edge& aEx=*((TopoDS_Edge*)&aER);
00234         if (!BRep_Tool::Degenerated(aEx)) {
00235           TopExp::MapShapesAndAncestors(aER, TopAbs_VERTEX, TopAbs_EDGE, aMVER);
00236         }
00237       }
00238     }//for (j=1; j<=aNbC; ++j) {
00239     //
00240     if (bRegular) {
00241       Standard_Integer k, aNbVR, aNbER;
00242       //
00243       aNbVR=aMVER.Extent();
00244       for (k=1; k<=aNbVR; ++k) {
00245         const TopTools_ListOfShape& aLER=aMVER(k);
00246         aNbER=aLER.Extent();
00247         if (aNbER==1) {
00248           const TopoDS_Edge& aEx=TopoDS::Edge(aER);
00249           bClosed=BRep_Tool::IsClosed(aEx, myWES->Face());
00250           if (!bClosed) {
00251             bRegular=!bRegular;
00252             break;
00253           }
00254         }
00255         if (aNbER>2) {
00256           bRegular=!bRegular;
00257           break;
00258         }
00259       }
00260     }
00261     //
00262     aCB.SetShapes(aLEC);
00263     aCB.SetRegularity(bRegular);
00264     myConnexityBlocks.Append(aCB);
00265     aMEC.Clear();
00266   }//for (i=1; i<=aNbV; ++i) {
00267 }
00268 
00269 //=======================================================================
00270 // function: DoCorrections
00271 // purpose:
00272 //=======================================================================
00273   void GEOMAlgo_WESCorrector::DoCorrections()
00274 {
00275   Standard_Boolean bIsRegular, bIsNothingToDo, bToScale;
00276   Standard_Integer iErr;
00277   Standard_Real aScale;
00278   TopoDS_Wire aW;
00279   BOP_ListIteratorOfListOfConnexityBlock aCBIt;
00280   GEOMAlgo_WESScaler aWSC;
00281   //
00282   const TopoDS_Face& aF=myWES->Face();
00283   //
00284   bToScale=IsToScale(aF, aScale);
00285   //
00286   myNewWES.SetFace(aF);
00287   aCBIt.Initialize(myConnexityBlocks);
00288   for (; aCBIt.More(); aCBIt.Next()) {
00289     const BOP_ConnexityBlock& aCB=aCBIt.Value();
00290     const TopTools_ListOfShape& aLE=aCB.Shapes();
00291     //
00292     bIsRegular=aCB.IsRegular();
00293     if (bIsRegular) {
00294       MakeWire(aLE, aW);
00295       myNewWES.AddShape (aW);
00296       continue;
00297     }
00298     //
00299     GEOMAlgo_WireSplitter aWS;
00300     //
00301     if(bToScale) {
00302       TopoDS_Shape aE;
00303       TopTools_ListIteratorOfListOfShape aIt;
00304       BOPTColStd_ListIteratorOfListOfListOfShape aItLLSS;
00305       //
00306       aWSC.SetScale(aScale);
00307       aWSC.SetFace(aF);
00308       aWSC.SetEdges(aLE);
00309       //
00310       aWSC.Perform();
00311       iErr=aWSC.ErrorStatus();
00312       if (iErr) {
00313         return;
00314       }
00315       //
00316       const TopoDS_Face& aFS=aWSC.FaceScaled();
00317       const TopTools_ListOfShape& aLES=aWSC.EdgesScaled();
00318       //
00319       aWS.SetFace(aFS);
00320       aWS.SetEdges(aLES);
00321       //
00322       aWS.Perform();
00323       iErr=aWS.ErrorStatus();
00324       if (iErr) {
00325         continue;
00326       }
00327       //
00328       bIsNothingToDo=aWS.IsNothingToDo();
00329       if (bIsNothingToDo) {
00330         MakeWire(aLE, aW);
00331         myNewWES.AddShape (aW);
00332         continue;
00333       }
00334       //
00335       const BOPTColStd_ListOfListOfShape& aLLSS=aWS.Shapes();
00336       aItLLSS.Initialize(aLLSS);
00337       for (; aItLLSS.More(); aItLLSS.Next()) {
00338         TopTools_ListOfShape aLS;
00339         //
00340         const TopTools_ListOfShape& aLSS=aItLLSS.Value();
00341         aIt.Initialize(aLSS);
00342         for (; aIt.More(); aIt.Next()) {
00343           const TopoDS_Shape& aES=aIt.Value();
00344           aE=aWSC.Origin(aES);
00345           aLS.Append(aE);
00346         }
00347         //
00348         MakeWire(aLS, aW);
00349         myNewWES.AddShape (aW);
00350       }
00351     }//if(bToScale)
00352     //
00353     else {
00354       aWS.SetFace(aF);
00355       aWS.SetEdges(aLE);
00356       //
00357       aWS.Perform();
00358       iErr=aWS.ErrorStatus();
00359       if (iErr) {
00360         continue;
00361       }
00362       bIsNothingToDo=aWS.IsNothingToDo();
00363       if (bIsNothingToDo) {
00364         MakeWire(aLE, aW);
00365         myNewWES.AddShape (aW);
00366         continue;
00367       }
00368       //
00369       const BOPTColStd_ListOfListOfShape& aSSS=aWS.Shapes();
00370       //
00371       BOPTColStd_ListIteratorOfListOfListOfShape aWireIt(aSSS);
00372       for (; aWireIt.More(); aWireIt.Next()) {
00373         const TopTools_ListOfShape& aLEx=aWireIt.Value();
00374         //
00375         MakeWire(aLEx, aW);
00376         myNewWES.AddShape (aW);
00377       }
00378     }// else
00379   }
00380 }
00381 
00382 //=======================================================================
00383 // function: MakeWire
00384 // purpose:
00385 //=======================================================================
00386   void MakeWire(const TopTools_ListOfShape& aLE,
00387                 TopoDS_Wire& newWire)
00388 {
00389   BRep_Builder aBB;
00390   aBB.MakeWire(newWire);
00391 
00392   TopTools_ListIteratorOfListOfShape anIt(aLE);
00393   for (; anIt.More(); anIt.Next()){
00394     const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
00395     aBB.Add(newWire, aE);
00396   }
00397 }
00398 
00399 //=======================================================================
00400 //function : IsToScale
00401 //purpose  :
00402 //=======================================================================
00403 Standard_Boolean IsToScale(const TopoDS_Face& aF,
00404                            Standard_Real& aScale)
00405 {
00406   Standard_Boolean bRet;
00407   Standard_Real aV1, aV2, dV, aTr;
00408   GeomAbs_SurfaceType aType;
00409   BRepAdaptor_Surface aBAS;
00410   //
00411   bRet=Standard_False;
00412   aScale=1.;
00413   //
00414   aBAS.Initialize(aF);
00415   aType=aBAS.GetType();
00416   if (aType==GeomAbs_Cylinder) {
00417     aTr=1.e5;
00418     aV1=aBAS.FirstVParameter();
00419     aV2=aBAS.LastVParameter();
00420     dV=aV2-aV1;
00421     //
00422     if (dV>aTr) {
00423       bRet=!bRet;
00424       aScale=1./aTr;
00425       return bRet;
00426     }
00427   }
00428   return bRet;
00429 }