Back to index

salome-geom  6.5.0
GEOMAlgo_GetInPlace_1.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_GetInPlace_1.cxx
00024 // Author:    Peter KURNEV
00025 
00026 #include <GEOMAlgo_GetInPlace.hxx>
00027 
00028 #include <math.h>
00029 
00030 #include <gp_Pnt.hxx>
00031 #include <gp_Vec.hxx>
00032 #include <gp_Pnt2d.hxx>
00033 #include <gp_Dir2d.hxx>
00034 
00035 #include <Geom_Surface.hxx>
00036 #include <Geom2d_Curve.hxx>
00037 #include <Geom2d_Line.hxx>
00038 #include <Geom2d_TrimmedCurve.hxx>
00039 #include <Geom2dAdaptor_Curve.hxx>
00040 #include <Geom2dHatch_Hatcher.hxx>
00041 #include <Geom2dHatch_Intersector.hxx>
00042 #include <HatchGen_Domain.hxx>
00043 #include <GeomAPI_ProjectPointOnCurve.hxx>
00044 
00045 #include <TopAbs_State.hxx>
00046 #include <TopAbs_ShapeEnum.hxx>
00047 #include <TopAbs_Orientation.hxx>
00048 
00049 #include <TopoDS_Vertex.hxx>
00050 #include <TopoDS_Edge.hxx>
00051 #include <TopoDS_Solid.hxx>
00052 #include <TopoDS_Face.hxx>
00053 
00054 #include <BRep_Tool.hxx>
00055 #include <TopExp_Explorer.hxx>
00056 
00057 #include <BRepTools.hxx>
00058 #include <BRepClass3d_SolidClassifier.hxx>
00059 
00060 #include <IntTools_Tools.hxx>
00061 
00062 #include <BOPTools_Tools3D.hxx>
00063 #include <BOPTools_Tools2D.hxx>
00064 
00065 
00066 
00067 static
00068   Standard_Integer PntInEdge(const TopoDS_Edge& aF,
00069                           gp_Pnt& aP);
00070 static
00071   Standard_Integer PntInEdge(const TopoDS_Edge& aF,
00072                           gp_Pnt& aP,
00073                           Standard_Real& aT);
00074 static
00075   Standard_Integer PntInFace(const TopoDS_Face& aF,
00076                           gp_Pnt& aP);
00077 static
00078   Standard_Integer PntInFace(const TopoDS_Face& aF,
00079                           gp_Pnt& aP,
00080                           gp_Pnt2d& theP2D);
00081 static
00082   Standard_Integer PntInSolid(const TopoDS_Solid& aZ,
00083                            const Standard_Real aTol,
00084                            gp_Pnt& aP);
00085 
00086 
00087 //=======================================================================
00088 //function : CheckCoincidence
00089 //purpose  :
00090 //=======================================================================
00091 Standard_Boolean GEOMAlgo_GetInPlace::CheckCoincidence(const TopoDS_Shape& aS1,
00092                                                  const TopoDS_Shape& aS2)
00093 {
00094   Standard_Boolean bOk;
00095   Standard_Integer iErr;
00096   Standard_Real aTol2;
00097   TopAbs_ShapeEnum aType1, aType2;
00098   TopAbs_State aState;
00099   gp_Pnt aP1, aP2;
00100   //
00101   myErrorStatus=0;
00102   //
00103   iErr=0;
00104   bOk=Standard_False;
00105   aTol2=myTolerance*myTolerance;
00106   aType1=aS1.ShapeType();
00107   aType2=aS2.ShapeType();
00108   //
00109   // 1. A point on shape #2 -> aP2
00110   if (myMapShapePnt.IsBound(aS2)) {
00111     aP2=myMapShapePnt.Find(aS2);
00112   }
00113   else {//else 1
00114     if (aType2==TopAbs_VERTEX) {
00115       const TopoDS_Vertex& aV2=*((TopoDS_Vertex*)&aS2);
00116       aP2=BRep_Tool::Pnt(aV2);
00117     }
00118     //
00119     else if (aType2==TopAbs_EDGE) {
00120       const TopoDS_Edge& aE2=*((TopoDS_Edge*)&aS2);
00121       iErr=PntInEdge(aE2, aP2);
00122     }
00123     //
00124     else if (aType2==TopAbs_FACE) {
00125       const TopoDS_Face& aF2=*((TopoDS_Face*)&aS2);
00126       iErr=PntInFace(aF2, aP2);
00127     }
00128     //
00129     else if (aType2==TopAbs_SOLID) {
00130       const TopoDS_Solid& aZ2=*((TopoDS_Solid*)&aS2);
00131       iErr=PntInSolid(aZ2, myTolerance, aP2);
00132     }
00133     //
00134     else {
00135       iErr=1;
00136     }
00137     //
00138     if (iErr) {
00139       myErrorStatus=50;
00140       return bOk;
00141     }
00142     //
00143     myMapShapePnt.Bind(aS2, aP2);
00144   } //else 1
00145   //
00146   // 2. Project the point aP2 on shape #1 and check
00147   if (aType1==TopAbs_EDGE) {
00148     Standard_Integer aNbPoints;
00149     Standard_Real aDmin, aT, aT1, aT2, dT;
00150     //
00151     const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aS1);
00152     //
00153     GeomAPI_ProjectPointOnCurve& aPPC=myContext->ProjPC(aE1);
00154     aPPC.Perform(aP2);
00155     aNbPoints=aPPC.NbPoints();
00156     if (aNbPoints) {
00157       aDmin=aPPC.LowerDistance();
00158       aT=aPPC.LowerDistanceParameter();
00159       if (aDmin < myTolerance) {
00160        dT=1.e-12;
00161        BRep_Tool::Curve(aE1, aT1, aT2);
00162         if(aT > (aT1-dT) && aT < (aT2+dT)) {
00163          bOk=Standard_True;
00164        }
00165       }
00166     }
00167     //else {
00168     // iErr=2;
00169     //}
00170   }//if (aType1==TopAbs_EDGE) {
00171   //
00172   else if (aType1==TopAbs_FACE) {
00173     const TopoDS_Face& aF1=*((TopoDS_Face*)&aS1);
00174     //
00175     bOk=myContext->IsValidPointForFace(aP2, aF1, myTolerance);
00176   }
00177   //
00178   else if (aType1==TopAbs_SOLID) {
00179     const TopoDS_Solid& aZ1=*((TopoDS_Solid*)&aS1);
00180     //
00181     BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aZ1);
00182     aSC.Perform(aP2, myTolerance);
00183     aState=aSC.State();
00184     bOk=(aState==TopAbs_IN);
00185   }
00186   //
00187   if (iErr) {
00188     myErrorStatus=50;
00189   }
00190   //
00191   return bOk;
00192 }
00193 //=======================================================================
00194 //
00195 //=======================================================================
00196 //function : PntInEdge
00197 //purpose  :
00198 //=======================================================================
00199 Standard_Integer PntInEdge(const TopoDS_Edge& aE,
00200                         gp_Pnt& aP)
00201 
00202 {
00203   Standard_Integer iErr;
00204   Standard_Real aT;
00205   //
00206   iErr=PntInEdge(aE, aP, aT);
00207   //
00208   return iErr;
00209 }
00210 //=======================================================================
00211 //function : PntInEdge
00212 //purpose  :
00213 //=======================================================================
00214 Standard_Integer PntInEdge(const TopoDS_Edge& aE,
00215                         gp_Pnt& aP,
00216                         Standard_Real& aT)
00217 {
00218   Standard_Integer iErr;
00219   Standard_Real aT1, aT2;
00220   Handle(Geom_Curve) aC3D;
00221   //
00222   iErr=0;
00223   //
00224   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
00225   aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
00226   aC3D->D0(aT, aP);
00227   //
00228   return iErr;
00229 }
00230 //=======================================================================
00231 //function : PntInSolid
00232 //purpose  :
00233 //=======================================================================
00234 Standard_Integer PntInSolid(const TopoDS_Solid& aZ,
00235                          const Standard_Real aTol,
00236                          gp_Pnt& aP)
00237 {
00238   Standard_Integer iErr;
00239   Standard_Real aUx, aVx, aCoef;
00240   gp_Pnt aPx;
00241   gp_Pnt2d aP2Dx;
00242   gp_Vec aDNx;
00243 
00244   TopoDS_Face aF;
00245   TopExp_Explorer aExp;
00246   //
00247   iErr=0;
00248   aCoef=10.;
00249   //
00250   aExp.Init (aZ, TopAbs_FACE);
00251   for (; aExp.More() ; aExp.Next()) {
00252     aF=*((TopoDS_Face*)&aExp.Current());
00253     break;
00254   }
00255   //
00256   iErr=PntInFace(aF, aPx, aP2Dx);
00257   if (iErr) {
00258     return iErr;
00259   }
00260   //
00261   aP2Dx.Coord(aUx, aVx);
00262   BOPTools_Tools2D::FaceNormal(aF, aUx, aVx, aDNx);
00263   aDNx.Reverse();
00264   //
00265   aP.SetXYZ(aPx.XYZ()+aCoef*aTol*aDNx.XYZ());
00266   //
00267   return iErr;
00268 }
00269 //=======================================================================
00270 //function : PntInFace
00271 //purpose  :
00272 //=======================================================================
00273 Standard_Integer PntInFace(const TopoDS_Face& aF,
00274                         gp_Pnt& aP)
00275 {
00276   Standard_Integer iErr;
00277   //
00278   gp_Pnt2d aP2Dx;
00279   //
00280   iErr=PntInFace(aF, aP, aP2Dx);
00281   //
00282   return iErr;
00283 }
00284 //=======================================================================
00285 //function : PntInFace
00286 //purpose  :
00287 //=======================================================================
00288 Standard_Integer PntInFace(const TopoDS_Face& aF,
00289                         gp_Pnt& theP,
00290                         gp_Pnt2d& theP2D)
00291 {
00292   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
00293   Standard_Integer iErr, aIx, aNbDomains, i;
00294   Standard_Real aUMin, aUMax, aVMin, aVMax;
00295   Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT;
00296   Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
00297   gp_Dir2d aD2D (0., 1.);
00298   gp_Pnt2d aP2D;
00299   gp_Pnt aPx;
00300   Handle(Geom2d_Curve) aC2D;
00301   Handle(Geom2d_TrimmedCurve) aCT2D;
00302   Handle(Geom2d_Line) aL2D;
00303   Handle(Geom_Surface) aS;
00304   TopAbs_Orientation aOrE;
00305   TopoDS_Face aFF;
00306   TopExp_Explorer aExp;
00307   //
00308   aTolHatch2D=1.e-8;
00309   aTolHatch3D=1.e-8;
00310   aTotArcIntr=1.e-10;
00311   aTolTangfIntr=1.e-10;
00312   //
00313   Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr);
00314   Geom2dHatch_Hatcher aHatcher(aIntr,
00315                             aTolHatch2D, aTolHatch3D,
00316                             Standard_True, Standard_False);
00317   //
00318   iErr=0;
00319   aEpsT=1.e-12;
00320   //
00321   aFF=aF;
00322   aFF.Orientation (TopAbs_FORWARD);
00323   //
00324   aS=BRep_Tool::Surface(aFF);
00325   BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
00326   //
00327   // 1
00328   aExp.Init (aFF, TopAbs_EDGE);
00329   for (; aExp.More() ; aExp.Next()) {
00330     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
00331     aOrE=aE.Orientation();
00332     //
00333     aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
00334     if (aC2D.IsNull() ) {
00335       iErr=1;
00336       return iErr;
00337     }
00338     if (fabs(aU1-aU2) < aEpsT) {
00339       iErr=2;
00340       return iErr;
00341     }
00342     //
00343     aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
00344     aHatcher.AddElement(aCT2D, aOrE);
00345   }// for (; aExp.More() ; aExp.Next()) {
00346   //
00347   // 2
00348   aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
00349   aP2D.SetCoord(aUx, 0.);
00350   aL2D=new Geom2d_Line (aP2D, aD2D);
00351   Geom2dAdaptor_Curve aHCur(aL2D);
00352   //
00353   aIx=aHatcher.AddHatching(aHCur) ;
00354   //
00355   // 3.
00356   aHatcher.Trim();
00357   bIsDone=aHatcher.TrimDone(aIx);
00358   if (!bIsDone) {
00359     iErr=3;
00360     return iErr;
00361   }
00362   //
00363   aHatcher.ComputeDomains(aIx);
00364   bIsDone=aHatcher.IsDone(aIx);
00365   if (!bIsDone) {
00366     iErr=4;
00367     return iErr;
00368   }
00369   //
00370   // 4.
00371   aNbDomains=aHatcher.NbDomains(aIx);
00372   for (i=1; i<=aNbDomains; ++i) {
00373     const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
00374     bHasFirstPoint=aDomain.HasFirstPoint();
00375     if (!bHasFirstPoint) {
00376       iErr=5;
00377       return iErr;
00378     }
00379     //
00380     aV1=aDomain.FirstPoint().Parameter();
00381     //
00382     bHasSecondPoint=aDomain.HasSecondPoint();
00383     if (!bHasSecondPoint) {
00384       iErr=6;
00385       return iErr;
00386     }
00387     //
00388     aV2=aDomain.SecondPoint().Parameter();
00389     //
00390     aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
00391     //
00392     break;
00393   }
00394   //
00395   aS->D0(aUx, aVx, aPx);
00396   //
00397   theP2D.SetCoord(aUx, aVx);
00398   theP=aPx;
00399   //
00400   return iErr;
00401 }
00402