Back to index

salome-geom  6.5.0
GEOMAlgo_Tools.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_Tools.cxx
00024 // Created:     Mon Dec  6 11:35:29 2004
00025 // Author:      Peter KURNEV
00026 
00027 #include <GEOMAlgo_Tools.hxx>
00028 
00029 #include <gp.hxx>
00030 #include <gp_Pnt.hxx>
00031 #include <gp_Pnt2d.hxx>
00032 #include <gp_Vec2d.hxx>
00033 #include <gp_Dir2d.hxx>
00034 
00035 #include <Geom2d_Curve.hxx>
00036 #include <Geom2d_TrimmedCurve.hxx>
00037 
00038 #include <Geom_Curve.hxx>
00039 #include <Geom_Surface.hxx>
00040 
00041 #include <GeomAdaptor_Surface.hxx>
00042 
00043 #include <GeomAPI_ProjectPointOnSurf.hxx>
00044 #include <GeomAPI_ProjectPointOnCurve.hxx>
00045 
00046 #include <TopAbs_ShapeEnum.hxx>
00047 
00048 #include <TopoDS.hxx>
00049 #include <TopoDS_Shape.hxx>
00050 #include <TopoDS_Edge.hxx>
00051 #include <TopoDS_Iterator.hxx>
00052 
00053 #include <TopTools_ListOfShape.hxx>
00054 #include <TopTools_ListIteratorOfListOfShape.hxx>
00055 #include <TopTools_IndexedMapOfShape.hxx>
00056 
00057 #include <BRep_Tool.hxx>
00058 #include <BRep_Builder.hxx>
00059 #include <BRepTools.hxx>
00060 
00061 #include <BOPTools_Tools2D.hxx>
00062 #include <IntTools_Context.hxx>
00063 
00064 #include <GEOMAlgo_PassKeyShape.hxx>
00065 #include <GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape.hxx>
00066 
00067 static
00068   void GetCount(const TopoDS_Shape& aS,
00069                 Standard_Integer& iCnt);
00070 
00071 //=======================================================================
00072 //function : IsCompositeShape
00073 //purpose  :
00074 //=======================================================================
00075 Standard_Boolean GEOMAlgo_Tools::IsCompositeShape(const TopoDS_Shape& aS)
00076 {
00077   Standard_Boolean bRet;
00078   Standard_Integer iCnt;
00079   TopoDS_Iterator aIt;
00080   //
00081   iCnt=0;
00082   GetCount(aS, iCnt);
00083   bRet=(iCnt>1);
00084   //
00085   return bRet;
00086 }
00087 
00088 //=======================================================================
00089 //function : GetCount
00090 //purpose  :
00091 //=======================================================================
00092 void GetCount(const TopoDS_Shape& aS,
00093               Standard_Integer& iCnt)
00094 {
00095   TopoDS_Iterator aIt;
00096   TopAbs_ShapeEnum aTS;
00097   //
00098   aTS=aS.ShapeType();
00099   //
00100   if (aTS==TopAbs_SHAPE) {
00101     return;
00102   }
00103   if (aTS!=TopAbs_COMPOUND) {
00104     ++iCnt;
00105     return;
00106   }
00107   //
00108   aIt.Initialize(aS);
00109   for (; aIt.More(); aIt.Next()) {
00110     const TopoDS_Shape& aSx=aIt.Value();
00111     GetCount(aSx, iCnt);
00112   }
00113 }
00114 
00115 //=======================================================================
00116 //function : RefineSDShapes
00117 //purpose  :
00118 //=======================================================================
00119   Standard_Integer GEOMAlgo_Tools::RefineSDShapes(GEOMAlgo_IndexedDataMapOfPassKeyShapeListOfShape& aMPKLE,
00120                                                   const Standard_Real aTol,
00121                                                   const Handle(IntTools_Context)& aCtx)
00122 {
00123   Standard_Integer i, aNbE, iErr, j, aNbEE, aNbToAdd;
00124   TopTools_IndexedDataMapOfShapeListOfShape aMEE, aMSDE, aMEToAdd;
00125   //
00126   iErr=1;
00127   //
00128   aNbE=aMPKLE.Extent();
00129   for (i=1; i<=aNbE; ++i) {
00130     TopTools_ListOfShape& aLSDE=aMPKLE.ChangeFromIndex(i);
00131     //
00132     aMEE.Clear();
00133     iErr=GEOMAlgo_Tools::FindSDShapes(aLSDE, aTol, aMEE, aCtx);
00134     if (iErr) {
00135       return iErr;
00136     }
00137     //
00138     aNbEE=aMEE.Extent();
00139     if (aNbEE==1) {
00140       continue;  // nothing to do
00141     }
00142     //
00143     for (j=1; j<=aNbEE; ++j) {
00144       TopTools_ListOfShape& aLEE=aMEE.ChangeFromIndex(j);
00145       //
00146       if (j==1) {
00147         aLSDE.Clear();
00148         aLSDE.Append(aLEE);
00149       }
00150       else {
00151         const TopoDS_Shape& aE1=aLEE.First();
00152         aMEToAdd.Add(aE1, aLEE);
00153       }
00154     }
00155   }
00156   //
00157   aNbToAdd=aMEToAdd.Extent();
00158   if (!aNbToAdd) {
00159     return aNbToAdd;
00160   }
00161   //
00162   for (i=1; i<=aNbToAdd; ++i) {
00163     GEOMAlgo_PassKeyShape aPKE1;
00164     //
00165     const TopoDS_Shape& aE1=aMEToAdd.FindKey(i);
00166     const TopTools_ListOfShape& aLE=aMEToAdd(i);
00167     //
00168     //qf
00169     //aPKE1.SetIds(aE1);
00170     aPKE1.SetShapes(aE1);
00171     //qt
00172     aMPKLE.Add(aPKE1, aLE);
00173   }
00174   //
00175   return 0;
00176 }
00177 //=======================================================================
00178 //function : FindSDShapes
00179 //purpose  :
00180 //=======================================================================
00181 Standard_Integer GEOMAlgo_Tools::FindSDShapes(const TopTools_ListOfShape& aLE,
00182                                               const Standard_Real aTol,
00183                                               TopTools_IndexedDataMapOfShapeListOfShape& aMEE,
00184                                               const Handle(IntTools_Context)& aCtx)
00185 {
00186   Standard_Integer aNbE, aNbEProcessed, aNbESD, iErr;
00187   TopTools_ListOfShape aLESD;
00188   TopTools_ListIteratorOfListOfShape aIt, aIt1;
00189   TopTools_IndexedMapOfShape aMProcessed;
00190   TopAbs_ShapeEnum aType;
00191   //
00192   aNbE=aLE.Extent();
00193   if (!aNbE) {
00194     return 3; // Err
00195   }
00196   //modified by NIZNHY-PKV Thu Dec 30 10:56:52 2004 f
00197   if (aNbE==1) {
00198     return 0; // Nothing to do
00199   }
00200   //modified by NIZNHY-PKV Thu Dec 30 10:56:56 2004 t
00201   //
00202   while(1) {
00203     aNbEProcessed=aMProcessed.Extent();
00204     if (aNbEProcessed==aNbE) {
00205       break;
00206     }
00207     //
00208     aIt.Initialize(aLE);
00209     for (; aIt.More(); aIt.Next()) {
00210       const TopoDS_Shape& aS=aIt.Value();
00211       //
00212       if (aMProcessed.Contains(aS)) {
00213         continue;
00214       }
00215       //
00216       //modified by NIZNHY-PKV Thu Dec 30 10:57:01 2004 f
00217       aType=aS.ShapeType();
00218       if (aType==TopAbs_EDGE) {
00219         const TopoDS_Edge& aE=TopoDS::Edge(aS);
00220         if (BRep_Tool::Degenerated(aE)) {
00221           aMProcessed.Add(aE);
00222           continue;
00223         }
00224       }
00225       //modified by NIZNHY-PKV Thu Dec 30 10:57:03 2004 t
00226       //
00227       aLESD.Clear();
00228       iErr=GEOMAlgo_Tools::FindSDShapes(aS, aLE, aTol, aLESD, aCtx);
00229       if (iErr) {
00230         return 2; // Err
00231       }
00232       //
00233       aNbESD=aLESD.Extent();
00234       if (!aNbESD) {
00235         return 1; // Err
00236       }
00237       //
00238       aMEE.Add(aS, aLESD);
00239       //
00240       aIt1.Initialize(aLESD);
00241       for (; aIt1.More(); aIt1.Next()) {
00242         const TopoDS_Shape& aE1=aIt1.Value();
00243         aMProcessed.Add(aE1);
00244       }
00245     }
00246   }
00247   return 0;
00248 }
00249 //=======================================================================
00250 //function : FindSDShapes
00251 //purpose  :
00252 //=======================================================================
00253 Standard_Integer GEOMAlgo_Tools::FindSDShapes(const TopoDS_Shape& aE1,
00254                                               const TopTools_ListOfShape& aLE,
00255                                               const Standard_Real aTol,
00256                                               TopTools_ListOfShape& aLESD,
00257                                               const Handle(IntTools_Context)& aCtx)
00258 {
00259   Standard_Boolean bIsDone;
00260   Standard_Real aTol2, aD2;
00261   gp_Pnt aP1, aP2;
00262   TopTools_ListIteratorOfListOfShape aIt;
00263   //
00264   aTol2=aTol*aTol;
00265   GEOMAlgo_Tools::PointOnShape(aE1, aP1);
00266   //
00267   aIt.Initialize(aLE);
00268   for (; aIt.More(); aIt.Next()) {
00269     const TopoDS_Shape& aE2=aIt.Value();
00270     if (aE2.IsSame(aE1)) {
00271        aLESD.Append(aE2);
00272     }
00273     else {
00274       bIsDone=GEOMAlgo_Tools::ProjectPointOnShape(aP1, aE2, aP2, aCtx);
00275       if (!bIsDone) {
00276         //return 1;
00277         continue; // jfa BUG 20361
00278       }
00279       aD2=aP1.SquareDistance(aP2);
00280       if(aD2<aTol2) {
00281         aLESD.Append(aE2);
00282       }
00283     }
00284   }
00285   return 0;
00286 }
00287 
00288 //=======================================================================
00289 //function : ProjectPointOnShape
00290 //purpose  :
00291 //=======================================================================
00292 Standard_Boolean GEOMAlgo_Tools::ProjectPointOnShape(const gp_Pnt& aP1,
00293                                                      const TopoDS_Shape& aS,
00294                                                      gp_Pnt& aP2,
00295                                                      const Handle(IntTools_Context)& aCtx)
00296 {
00297   Standard_Boolean bIsDone = Standard_False;
00298   Standard_Real aT2;
00299   TopAbs_ShapeEnum aType;
00300   //
00301   aType = aS.ShapeType();
00302   switch (aType)
00303     {
00304     case TopAbs_EDGE:
00305       {
00306         const TopoDS_Edge& aE2 = TopoDS::Edge(aS);
00307         //
00308         if (BRep_Tool::Degenerated(aE2)) { // jfa
00309           return Standard_True;
00310         }
00311         else {
00312           Standard_Real f, l;
00313           Handle(Geom_Curve) aC3D = BRep_Tool::Curve (aE2, f, l);
00314           if (aC3D.IsNull()) {
00315             return Standard_True;
00316           }
00317           bIsDone = aCtx->ProjectPointOnEdge(aP1, aE2, aT2);
00318         }
00319         if (!bIsDone) {
00320           return bIsDone;
00321         }
00322         //
00323         GEOMAlgo_Tools::PointOnEdge(aE2, aT2, aP2);
00324       }
00325       break;
00326       //
00327     case TopAbs_FACE:
00328       {
00329         const TopoDS_Face& aF2 = TopoDS::Face(aS);
00330         GeomAPI_ProjectPointOnSurf& aProj = aCtx->ProjPS(aF2);
00331         //
00332         aProj.Perform(aP1);
00333         bIsDone = aProj.IsDone();
00334         if (!bIsDone) {
00335           return bIsDone;
00336         }
00337         //
00338         aP2 = aProj.NearestPoint();
00339       }
00340       break;
00341       //
00342     default:
00343       break; // Err
00344     }
00345   return bIsDone;
00346 }
00347 //=======================================================================
00348 //function : PointOnShape
00349 //purpose  :
00350 //=======================================================================
00351 void GEOMAlgo_Tools::PointOnShape(const TopoDS_Shape& aS,
00352                                   gp_Pnt& aP3D)
00353 {
00354   TopAbs_ShapeEnum aType;
00355   //
00356   aP3D.SetCoord(99.,99.,99.);
00357   aType=aS.ShapeType();
00358   switch(aType) {
00359     case TopAbs_EDGE: {
00360       const TopoDS_Edge& aE=TopoDS::Edge(aS);
00361       GEOMAlgo_Tools::PointOnEdge(aE, aP3D);
00362       }
00363       break;
00364       //
00365     case TopAbs_FACE: {
00366       const TopoDS_Face& aF=TopoDS::Face(aS);
00367       GEOMAlgo_Tools::PointOnFace(aF, aP3D);
00368       }
00369       break;
00370       //
00371     default:
00372       break; // Err
00373   }
00374 }
00375 //=======================================================================
00376 //function : PointOnFace
00377 //purpose  :
00378 //=======================================================================
00379 void GEOMAlgo_Tools::PointOnFace(const TopoDS_Face& aF,
00380                                  gp_Pnt& aP3D)
00381 {
00382   Standard_Real aU, aV, aUMin, aUMax, aVMin, aVMax;
00383   //
00384   BRepTools::UVBounds(aF, aUMin, aUMax, aVMin, aVMax);
00385   //
00386   aU=BOPTools_Tools2D::IntermediatePoint(aUMin, aUMax);
00387   aV=BOPTools_Tools2D::IntermediatePoint(aVMin, aVMax);
00388   //
00389   GEOMAlgo_Tools::PointOnFace(aF, aU, aV, aP3D);
00390 }
00391 //=======================================================================
00392 //function : PointOnFace
00393 //purpose  :
00394 //=======================================================================
00395 void GEOMAlgo_Tools::PointOnFace(const TopoDS_Face& aF,
00396                                  const Standard_Real aU,
00397                                  const Standard_Real aV,
00398                                  gp_Pnt& aP3D)
00399 {
00400   Handle(Geom_Surface) aS;
00401   //
00402   aS=BRep_Tool::Surface(aF);
00403   aS->D0(aU, aV, aP3D);
00404 }
00405 //=======================================================================
00406 //function : PointOnEdge
00407 //purpose  :
00408 //=======================================================================
00409 void GEOMAlgo_Tools::PointOnEdge(const TopoDS_Edge& aE,
00410                                  gp_Pnt& aP3D)
00411 {
00412   Standard_Real aTx, aT1, aT2;
00413   //
00414   BRep_Tool::Curve(aE, aT1, aT2);
00415   aTx=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
00416   GEOMAlgo_Tools::PointOnEdge(aE, aTx, aP3D);
00417 }
00418 //=======================================================================
00419 //function : PointOnEdge
00420 //purpose  :
00421 //=======================================================================
00422 void GEOMAlgo_Tools::PointOnEdge(const TopoDS_Edge& aE,
00423                                  const Standard_Real aT,
00424                                  gp_Pnt& aP3D)
00425 {
00426   Standard_Real aT1, aT2;
00427   Handle(Geom_Curve) aC3D;
00428   //
00429   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
00430   aC3D->D0(aT, aP3D);
00431 }
00432 //=======================================================================
00433 //function : RefinePCurveForEdgeOnFace
00434 //purpose  :
00435 //=======================================================================
00436 void GEOMAlgo_Tools::RefinePCurveForEdgeOnFace(const TopoDS_Edge& aE,
00437                                                const TopoDS_Face& aF,
00438                                                const Standard_Real aUMin,
00439                                                const Standard_Real aUMax)
00440 {
00441   Standard_Real aT1, aT2, aTx, aUx, aTol;
00442   gp_Pnt2d aP2D;
00443   Handle(Geom_Surface) aS;
00444   Handle(Geom2d_Curve) aC2D;
00445   BRep_Builder aBB;
00446   //
00447   aC2D=BRep_Tool::CurveOnSurface(aE, aF, aT1, aT2);
00448   if (!aC2D.IsNull()) {
00449     if (BRep_Tool::IsClosed(aE, aF)) {
00450       return;
00451     }
00452     aTx=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
00453     aC2D->D0(aTx, aP2D);
00454     aUx=aP2D.X();
00455     if (aUx < aUMin || aUx > aUMax) {
00456       // need to rebuild
00457       Handle(Geom2d_Curve) aC2Dx;
00458       //
00459       aTol=BRep_Tool::Tolerance(aE);
00460       aBB.UpdateEdge(aE, aC2Dx, aF, aTol);
00461     }
00462   }
00463 }
00464 //=======================================================================
00465 //function : IsUPeriodic
00466 //purpose  :
00467 //=======================================================================
00468 Standard_Boolean GEOMAlgo_Tools::IsUPeriodic(const  Handle(Geom_Surface) &aS)
00469 {
00470   Standard_Boolean bRet;
00471   GeomAbs_SurfaceType aType;
00472   GeomAdaptor_Surface aGAS;
00473   //
00474   aGAS.Load(aS);
00475   aType=aGAS.GetType();
00476   bRet=(aType==GeomAbs_Cylinder||
00477         aType==GeomAbs_Cone ||
00478         aType==GeomAbs_Sphere);
00479   //
00480   return bRet;
00481 }
00482 
00483 //modified by NIZNHY-PKV Fri Feb 03 11:16:35 2012f
00484 //=======================================================================
00485 //function : BuildPCurveForEdgeOnFace
00486 //purpose  :
00487 //=======================================================================
00488 Standard_Integer
00489   GEOMAlgo_Tools::BuildPCurveForEdgeOnFace(const TopoDS_Edge& aEold,
00490                                            const TopoDS_Edge& aEnew,
00491                                            const TopoDS_Face& aF,
00492                                            const Handle(IntTools_Context)& aCtx)
00493 {
00494   Standard_Boolean bIsClosed, bUClosed, bHasOld;
00495   Standard_Integer iRet, aNbPoints;
00496   Standard_Real aTS, aTS1, aTS2, aT, aT1, aT2, aScPr, aTol;
00497   Standard_Real aU, aV, aUS1, aVS1, aUS2, aVS2;
00498   gp_Pnt aP;
00499   gp_Pnt2d aP2DS1, aP2DS2, aP2D;
00500   gp_Vec2d aV2DS1, aV2DS2;
00501   Handle(Geom2d_Curve) aC2D, aC2DS1, aC2DS2;
00502   Handle(Geom_Surface) aS;
00503   TopoDS_Edge aES;
00504   //
00505   iRet=0;
00506   //
00507   bHasOld=BOPTools_Tools2D::HasCurveOnSurface(aEnew, aF, aC2D, aT1, aT2, aTol);
00508   if (bHasOld) {
00509     return iRet;
00510   }
00511   //
00512   BOPTools_Tools2D::BuildPCurveForEdgeOnFace(aEnew, aF);
00513   aC2D=BRep_Tool::CurveOnSurface(aEnew, aF, aT1, aT2);
00514   if (aC2D.IsNull()){
00515     iRet=1;
00516     return iRet;
00517   }
00518   //
00519   bIsClosed=BRep_Tool::IsClosed(aEold, aF);
00520   if (!bIsClosed) {
00521     return iRet;
00522   }
00523   //
00524   aTol=1.e-7;
00525   //
00526   // 1. bUClosed - direction of closeness
00527   //
00528   aES=aEold;
00529   aES.Orientation(TopAbs_FORWARD);
00530   aC2DS1=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
00531   //
00532   aES.Orientation(TopAbs_REVERSED);
00533   aC2DS2=BRep_Tool::CurveOnSurface(aES, aF, aTS1, aTS2);
00534   //
00535   aTS=BOPTools_Tools2D::IntermediatePoint(aTS1, aTS2);
00536   //
00537   aC2DS1->D1(aTS, aP2DS1, aV2DS1);
00538   aC2DS2->D1(aTS, aP2DS2, aV2DS2);
00539   //
00540   gp_Vec2d aV2DS12(aP2DS1, aP2DS2);
00541   gp_Dir2d aD2DS12(aV2DS12);
00542   const gp_Dir2d& aD2DX=gp::DX2d();
00543   //
00544   aScPr=aD2DS12*aD2DX;
00545   bUClosed=Standard_True;
00546   if (fabs(aScPr) < aTol) {
00547     bUClosed=!bUClosed;
00548   }
00549   //
00550   // 2. aP2D - point on curve aC2D, that corresponds to aP2DS1
00551   aP2DS1.Coord(aUS1, aVS1);
00552   aP2DS2.Coord(aUS2, aVS2);
00553   //
00554   aS=BRep_Tool::Surface(aF);
00555   aS->D0(aUS1, aVS1, aP);
00556   //
00557   GeomAPI_ProjectPointOnCurve& aProjPC=aCtx->ProjPC(aEnew);
00558   //
00559   aProjPC.Perform(aP);
00560   aNbPoints=aProjPC.NbPoints();
00561   if (!aNbPoints) {
00562     iRet=2;
00563     return iRet;
00564   }
00565   //
00566   aT=aProjPC.LowerDistanceParameter();
00567 
00568   //
00569   // 3. Build the second 2D curve
00570   Standard_Boolean bRevOrder;
00571   gp_Vec2d aV2DT, aV2D;
00572   Handle(Geom2d_Curve) aC2Dnew;
00573   Handle(Geom2d_TrimmedCurve) aC2DTnew;
00574   BRep_Builder aBB;
00575   //
00576   aC2D->D1(aT, aP2D, aV2D);
00577   aP2D.Coord(aU, aV);
00578   //
00579   aC2Dnew=Handle(Geom2d_Curve)::DownCast(aC2D->Copy());
00580   aC2DTnew = new Geom2d_TrimmedCurve(aC2Dnew, aT1, aT2);
00581   //
00582   aV2DT=aV2DS12;
00583   if (!bUClosed) {    // V Closed
00584     if (fabs(aV-aVS2)<aTol) {
00585       aV2DT.Reverse();
00586     }
00587   }
00588   else {   // U Closed
00589     if (fabs(aU-aUS2)<aTol) {
00590       aV2DT.Reverse();
00591     }
00592   }
00593   //
00594   aC2DTnew->Translate(aV2DT);
00595   //
00596   // 4 Order the 2D curves
00597   bRevOrder=Standard_False;
00598   aScPr=aV2D*aV2DS1;
00599   if(aScPr<0.) {
00600     bRevOrder=!bRevOrder;
00601   }
00602   //
00603   // 5. Update the edge
00604   aTol=BRep_Tool::Tolerance(aEnew);
00605   if (!bRevOrder) {
00606     aBB.UpdateEdge(aEnew, aC2D, aC2DTnew, aF, aTol);
00607   }
00608   else {
00609     aBB.UpdateEdge(aEnew, aC2DTnew, aC2D , aF, aTol);
00610   }
00611   //
00612   return iRet;
00613 }