Back to index

salome-geom  6.5.0
GEOMAlgo_Tools_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 // File:      GEOMAlgo_Tools_1.cxx
00020 // Created:   Thu May  6 10:46:21 2010
00021 // Author:    Peter KURNEV
00022 //            <pkv@irinox>
00023 
00024 #include <GEOMAlgo_Tools.hxx>
00025 //
00026 #include <NCollection_DataMap.hxx>
00027 
00028 #include <gp_Pnt2d.hxx>
00029 #include <gp_Pnt.hxx>
00030 
00031 #include <Geom2dAdaptor_Curve.hxx>
00032 #include <Geom2dInt_GInter.hxx>
00033 #include <Geom2d_Curve.hxx>
00034 #include <Geom_Curve.hxx>
00035 #include <Geom_Surface.hxx>
00036 #include <GeomAdaptor_Surface.hxx>
00037 
00038 #include <IntRes2d_Domain.hxx>
00039 #include <IntRes2d_IntersectionPoint.hxx>
00040 #include <IntRes2d_Transition.hxx>
00041 
00042 #include <TopoDS_Iterator.hxx>
00043 #include <TopoDS_Face.hxx>
00044 #include <TopoDS_Wire.hxx>
00045 #include <TopoDS_Edge.hxx>
00046 #include <TopoDS_Vertex.hxx>
00047 #include <TopExp_Explorer.hxx>
00048 
00049 #include <BRep_Tool.hxx>
00050 #include <BRep_Builder.hxx>
00051 
00052 #include <TopTools_MapOfShape.hxx>
00053 #include <TopTools_ShapeMapHasher.hxx>
00054 #include <TopTools_ListOfShape.hxx>
00055 #include <TopTools_DataMapOfShapeListOfShape.hxx>
00056 #include <TopTools_ListOfShape.hxx>
00057 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
00058 #include <BRepTools.hxx>
00059 
00060 static
00061   inline Standard_Boolean IsEqual(const TopoDS_Shape& aS1,
00062                               const TopoDS_Shape& aS2) {
00063   return TopTools_ShapeMapHasher::IsEqual(aS1, aS2);
00064 }
00065 //
00066 static
00067   Standard_Boolean CorrectWire(const TopoDS_Wire& aW,
00068                             const TopoDS_Face& aF);
00069 
00070 //=======================================================================
00071 //function : CorrectWires
00072 //purpose  :
00073 //=======================================================================
00074   Standard_Boolean GEOMAlgo_Tools::CorrectWires(const TopoDS_Shape& aShape)
00075 {
00076   Standard_Boolean bRet;
00077   TopoDS_Iterator aItF;
00078   TopExp_Explorer aExp;
00079   TopTools_MapOfShape aMF;
00080   GeomAdaptor_Surface aGAS;
00081   GeomAbs_SurfaceType aTS;
00082   TopLoc_Location aLoc;
00083   //
00084   bRet=Standard_False;
00085   //
00086   aExp.Init(aShape, TopAbs_FACE);
00087   for (; aExp.More(); aExp.Next()) {
00088     const TopoDS_Face& aF=*((TopoDS_Face*)&aExp.Current());
00089     if (aMF.Add(aF)) {
00090       const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF, aLoc);
00091       aGAS.Load(aS);
00092       aTS=aGAS.GetType();
00093       if (aTS==GeomAbs_Cylinder || aTS==GeomAbs_Plane) {
00094        aItF.Initialize(aF);
00095        for (; aItF.More(); aItF.Next()) {
00096          const TopoDS_Wire& aW=*((TopoDS_Wire*)&aItF.Value());
00097          if (CorrectWire(aW, aF)) {
00098           bRet=Standard_True;
00099          }
00100        }
00101       }
00102     }
00103   }
00104   return bRet;
00105 }
00106 //=======================================================================
00107 //class: GEOMAlgo_InfoEdge
00108 //purpose  :
00109 //=======================================================================
00110 class GEOMAlgo_InfoEdge {
00111  public:
00112   //
00113   GEOMAlgo_InfoEdge() {
00114     myErrorStatus=0;
00115     myTolInt=1.0e-10;
00116   };
00117   //
00118   ~GEOMAlgo_InfoEdge(){
00119   };
00120   //
00121   void Init(const TopoDS_Edge& aE,
00122            const TopoDS_Face& aF);
00123   //
00124   void SetTolInt(const Standard_Real aTolInt) {
00125     myTolInt=aTolInt;
00126   };
00127   //
00128   const Standard_Real TolInt() const {
00129     return myTolInt;
00130   }
00131   //
00132   const Geom2dAdaptor_Curve& Adaptor() const {
00133     return myGAC2D;
00134   }
00135   //
00136   const IntRes2d_Domain& Domain()const {
00137     return myDomain;
00138   }
00139   //
00140   const Handle(Geom2d_Curve)& CurveOnSurface()const {
00141     return myC2D;
00142   }
00143   //
00144   const Handle(Geom_Curve)& Curve()const {
00145     return myC3D;
00146   }
00147   //
00148   Standard_Integer ErrorStatus()const {
00149     return myErrorStatus;
00150   }
00151   //
00152  protected:
00153   Standard_Integer myErrorStatus;
00154   Standard_Real myTolInt;
00155   Geom2dAdaptor_Curve myGAC2D;
00156   IntRes2d_Domain myDomain;
00157   Handle(Geom2d_Curve) myC2D;
00158   Handle(Geom_Curve) myC3D;
00159 };
00160 //
00161 typedef NCollection_DataMap<TopoDS_Shape, GEOMAlgo_InfoEdge> GEOMAlgo_DataMapOfShapeInfoEdge;
00162 typedef GEOMAlgo_DataMapOfShapeInfoEdge::Iterator GEOMAlgo_DataMapIteratorOfDataMapOfShapeInfoEdge;
00163 
00164 //=======================================================================
00165 //function : Init
00166 //purpose  :
00167 //=======================================================================
00168   void GEOMAlgo_InfoEdge::Init(const TopoDS_Edge& aE,
00169                             const TopoDS_Face& aF)
00170 {
00171   Standard_Real aT1, aT2, aT1x, aT2x;
00172   gp_Pnt2d aP2D1, aP2D2;
00173   //
00174   myErrorStatus=0;
00175   //
00176   myC3D=BRep_Tool::Curve(aE, aT1, aT2);
00177   myC2D=BRep_Tool::CurveOnSurface(aE ,aF, aT1, aT2);
00178   if (!myC2D.IsNull() && aT2>aT1) {
00179     myGAC2D.Load(myC2D);
00180     if(!myGAC2D.IsPeriodic()) {
00181       aT1x=myGAC2D.FirstParameter();
00182       aT2x=myGAC2D.LastParameter();
00183       if(aT1x > aT1) {
00184        aT1=aT1x;
00185       }
00186       if(aT2x < aT2) {
00187        aT2=aT2x;
00188       }
00189     }
00190     //
00191     BRep_Tool::UVPoints(aE, aF, aP2D1, aP2D2);
00192     myDomain.SetValues(aP2D1, aT1, myTolInt, aP2D2, aT2, myTolInt);
00193   }
00194   else {
00195     myErrorStatus=10;
00196     return;
00197   }
00198 }
00199 //=======================================================================
00200 //function : CorrectWire
00201 //purpose  :
00202 //=======================================================================
00203 Standard_Boolean CorrectWire(const TopoDS_Wire& aW,
00204                           const TopoDS_Face& aF)
00205 {
00206   Standard_Boolean bRet;
00207   Standard_Real aTolInt;
00208   Standard_Integer iErr, aNbV, aNbE;
00209   TopoDS_Iterator aItW, aItE;
00210   Geom2dInt_GInter aInter;
00211   GEOMAlgo_DataMapOfShapeInfoEdge aDMEIE;
00212   TopTools_DataMapOfShapeListOfShape aDMVLE;
00213   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMVLE;
00214   //
00215   bRet=Standard_False;
00216   aTolInt=1.0e-10;
00217   //
00218   aItW.Initialize(aW);
00219   for (; aItW.More(); aItW.Next()) {
00220     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aItW.Value());
00221 
00222     aItE.Initialize(aE);
00223     for (aNbV=0; aItE.More(); aItE.Next(), ++aNbV) {
00224     }
00225     if (aNbV<2) {
00226       return bRet; //
00227     }
00228     //
00229     if (!aDMEIE.IsBound(aE)) {
00230       GEOMAlgo_InfoEdge aInfoEdge;
00231       //
00232       aInfoEdge.Init (aE, aF);
00233       iErr=aInfoEdge.ErrorStatus();
00234       if (iErr) {
00235        return bRet; //
00236       }
00237       //
00238       aDMEIE.Bind(aE, aInfoEdge);
00239     }
00240     //
00241     aItE.Initialize(aE);
00242     for (; aItE.More(); aItE.Next()) {
00243       const TopoDS_Shape& aV=aItE.Value();
00244       if (aDMVLE.IsBound(aV)) {
00245        TopTools_ListOfShape& aLE=aDMVLE.ChangeFind(aV);
00246        aLE.Append(aE);
00247       }
00248       else {
00249        TopTools_ListOfShape aLE;
00250        aLE.Append(aE);
00251        aDMVLE.Bind(aV, aLE);
00252       }
00253     }
00254   }
00255   //
00256   // 2
00257   Standard_Real aTolV, aD1, aD2, aDmax, aCoeff;
00258   gp_Pnt aPV;
00259   Handle(Geom_Surface) aS;
00260   BRep_Builder aBB;
00261   //
00262   aCoeff=1.1;
00263   aS=BRep_Tool::Surface(aF);
00264   //
00265   aItDMVLE.Initialize(aDMVLE);
00266   for(; aItDMVLE.More(); aItDMVLE.Next()) {
00267     const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aItDMVLE.Key());
00268     const TopTools_ListOfShape& aLE=aItDMVLE.Value();
00269     aNbE=aLE.Extent();
00270     if (aNbE!=2) {
00271       continue;
00272     }
00273     //
00274     aPV=BRep_Tool::Pnt(aV);
00275     aTolV=BRep_Tool::Tolerance(aV);
00276     //
00277     const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aLE.First());
00278     const GEOMAlgo_InfoEdge& aIE1=aDMEIE.Find(aE1);
00279     const Geom2dAdaptor_Curve& aGAC1=aIE1.Adaptor();
00280     const IntRes2d_Domain& aDomain1=aIE1.Domain();
00281     //
00282     const TopoDS_Edge& aE2=*((TopoDS_Edge*)&aLE.Last());
00283     const GEOMAlgo_InfoEdge& aIE2=aDMEIE.Find(aE2);
00284     const Geom2dAdaptor_Curve& aGAC2=aIE2.Adaptor();
00285     const IntRes2d_Domain& aDomain2=aIE2.Domain();
00286     //
00287     aInter.Perform(aGAC1, aDomain1,aGAC2, aDomain2, aTolInt, aTolInt);
00288     if(!aInter.IsDone()) {
00289       continue;
00290     }
00291     //
00292     Standard_Integer i, aNbP;
00293     Standard_Real aIP_ParamOnFirst, aIP_ParamOnSecond;
00294     gp_Pnt aP3D1, aP3D2;
00295     gp_Pnt2d aP2D1, aP2D2;
00296     IntRes2d_Transition aTr1, aTr2;
00297     //
00298     aNbP=aInter.NbPoints();
00299     for (i=1; i<=aNbP; ++i) {
00300       const IntRes2d_IntersectionPoint& aIP = aInter.Point(i);
00301       aIP_ParamOnFirst  = aIP.ParamOnFirst();
00302       aIP_ParamOnSecond = aIP.ParamOnSecond();
00303       aTr1 =aIP.TransitionOfFirst();
00304       aTr2 =aIP.TransitionOfSecond();
00305       if(aTr1.PositionOnCurve()==IntRes2d_Middle ||
00306         aTr2.PositionOnCurve()==IntRes2d_Middle) {
00307        //
00308        const Handle(Geom_Curve)& aC3D1=aIE1.Curve();
00309        if (!aC3D1.IsNull()) {
00310          aP3D1=aC3D1->Value(aIP_ParamOnFirst);
00311        }
00312        else {
00313          aP2D1=aGAC1.Value(aIP_ParamOnFirst);
00314          aS->D0(aP2D1.X(), aP2D1.Y(), aP3D1);
00315        }
00316        //
00317        const Handle(Geom_Curve)& aC3D2=aIE2.Curve();
00318        if (!aC3D2.IsNull()) {
00319          aP3D2=aC3D2->Value(aIP_ParamOnSecond);
00320        }
00321        else {
00322          aP2D2=aGAC2.Value(aIP_ParamOnSecond);
00323          aS->D0(aP2D2.X(), aP2D2.Y(), aP3D2);
00324        }
00325        //
00326        aD1=aPV.Distance(aP3D1);
00327        aD2=aPV.Distance(aP3D2);
00328        aDmax=(aD1>aD2)? aD1 : aD2;
00329        if (aDmax>aCoeff*aTolV) {
00330          if (aDmax<10.*aTolV){
00331            aBB.UpdateVertex(aV, aDmax);
00332            bRet=Standard_True;
00333          }
00334        }
00335       }//
00336     }//for (i=1; i<=aNbP; ++i) {
00337   }//for(; aItDMVLE.More(); aItDMVLE.Next()) {
00338   return bRet;
00339 }
00340 
00341