Back to index

salome-geom  6.5.0
GEOMAlgo_BuilderTools.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_BuilderTools.cxx
00024 // Author:      Peter KURNEV
00025 
00026 #include <GEOMAlgo_BuilderTools.hxx>
00027 
00028 #include <Basics_OCCTVersion.hxx>
00029 
00030 #include <TColStd_Array1OfReal.hxx>
00031 
00032 #include <gp_Pnt2d.hxx>
00033 #include <gp_Vec.hxx>
00034 #include <gp_Dir.hxx>
00035 #include <gp_Pnt.hxx>
00036 
00037 #include <TColgp_Array1OfPnt.hxx>
00038 
00039 #include <Poly_Triangulation.hxx>
00040 #include <Poly_Array1OfTriangle.hxx>
00041 #include <Poly_Triangle.hxx>
00042 
00043 #include <Geom2d_Curve.hxx>
00044 #include <Geom2dInt_Geom2dCurveTool.hxx>
00045 
00046 #include <TopLoc_Location.hxx>
00047 #include <TopAbs_Orientation.hxx>
00048 
00049 #include <TopoDS_Face.hxx>
00050 #include <TopoDS_Iterator.hxx>
00051 #include <TopoDS_Wire.hxx>
00052 #include <TopoDS.hxx>
00053 #include <TopoDS_Edge.hxx>
00054 #include <TopExp_Explorer.hxx>
00055 
00056 #if OCC_VERSION_LARGE > 0x06050100 // for OCC-6.5.2 and higher version
00057 #include <TopExp.hxx>
00058 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00059 #endif
00060 
00061 #include <BRep_Tool.hxx>
00062 #include <BRepBndLib.hxx>
00063 #include <BRepMesh_FastDiscret.hxx>
00064 #include <Bnd_Box.hxx>
00065 #include <BRepAdaptor_Curve2d.hxx>
00066 
00067 static
00068   Standard_Integer ComputeProps(const TopoDS_Face& aF,
00069                                 Standard_Real& aA,
00070                                 Standard_Real& aV);
00071 static
00072   void BuildTriangulation(const TopoDS_Face& aF);
00073 
00074 //=======================================================================
00075 //function : IsHole
00076 //purpose  :
00077 //=======================================================================
00078   Standard_Boolean GEOMAlgo_BuilderTools::IsHole(const TopoDS_Shape& aW,
00079                                                  const TopoDS_Shape& aFace)
00080 {
00081   Standard_Boolean bIsHole;
00082   Standard_Integer i, aNbS;
00083   Standard_Real aT1, aT2, aS;
00084   Standard_Real aU1, aU2, aU, dU;
00085   Standard_Real aX1, aY1, aX0, aY0;
00086   TopAbs_Orientation aOr;
00087 
00088   gp_Pnt2d aP2D0, aP2D1;
00089   Handle(Geom2d_Curve) aC2D;
00090   TopoDS_Face aF, aFF;
00091   TopoDS_Iterator aItW;
00092   //
00093   bIsHole=Standard_False;
00094   //
00095   aF=TopoDS::Face(aFace);
00096   aFF=aF;
00097   aFF.Orientation(TopAbs_FORWARD);
00098   //
00099   aS=0.;
00100   aItW.Initialize(aW);
00101   for (; aItW.More(); aItW.Next()) {
00102     const TopoDS_Edge& aE=TopoDS::Edge(aItW.Value());
00103     aOr=aE.Orientation();
00104     if (!(aOr==TopAbs_FORWARD ||
00105           aOr==TopAbs_REVERSED)) {
00106       continue;
00107     }
00108     //
00109     aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
00110     if (aC2D.IsNull()) {
00111       break; //xx
00112     }
00113     //
00114     BRepAdaptor_Curve2d aBAC2D(aE, aFF);
00115     aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
00116     if (aNbS>2) {
00117       aNbS*=4;
00118     }
00119     //
00120     dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
00121     aU =aT1;
00122     aU1=aT1;
00123     aU2=aT2;
00124     if (aOr==TopAbs_REVERSED) {
00125       aU =aT2;
00126       aU1=aT2;
00127       aU2=aT1;
00128       dU=-dU;
00129     }
00130     //
00131     aC2D->D0(aU, aP2D0);
00132     for(i=2; i<=aNbS; i++) {
00133       aU=aU1+(i-1)*dU;
00134       aC2D->D0(aU, aP2D1);
00135       aP2D0.Coord(aX0, aY0);
00136       aP2D1.Coord(aX1, aY1);
00137       //
00138       aS=aS+(aY0+aY1)*(aX1-aX0);
00139       //
00140       aP2D0=aP2D1;
00141     }
00142   }//for (; aItW.More(); aItW.Next()) {
00143   bIsHole=(aS>0.);
00144   return bIsHole;
00145 }
00146 //=======================================================================
00147 //function : IsHole
00148 //purpose  :
00149 //=======================================================================
00150   Standard_Boolean GEOMAlgo_BuilderTools::IsHole(const TopoDS_Shape& aShell)
00151 {
00152   Standard_Boolean bIsHole;
00153   Standard_Integer iRet;
00154   Standard_Real aAi, aA, aV, aVi;
00155   TopExp_Explorer aExp;
00156   //
00157   aA=0.;
00158   aV=0.;
00159   aExp.Init(aShell, TopAbs_FACE);
00160   for (; aExp.More(); aExp.Next()) {
00161     const TopoDS_Face& aF=TopoDS::Face(aExp.Current());
00162     iRet=ComputeProps(aF, aAi, aVi);
00163     if (!iRet) {
00164       aA+=aAi;
00165       aV+=aVi;
00166     }
00167   }
00168   //
00169   bIsHole=aV<0.;
00170   return bIsHole;
00171 }
00172 //=======================================================================
00173 //function : ComputeProps
00174 //purpose  :
00175 //=======================================================================
00176 Standard_Integer ComputeProps(const TopoDS_Face& aF,
00177                               Standard_Real& aA,
00178                               Standard_Real& aV)
00179 {
00180   Standard_Integer j, i, i1, i2, aNbNodes, aNbTrigs, n[3];
00181   Standard_Real aAi, aVi;
00182   gp_Pnt aP[3], aGC, aGC1;
00183   TopLoc_Location aLoc;
00184   TopAbs_Orientation aOr;
00185   Handle(Poly_Triangulation) aTri;
00186   //
00187   aA=0.;
00188   aV=0.;
00189   //
00190   aTri=BRep_Tool::Triangulation(aF, aLoc);
00191   if(aTri.IsNull()) {
00192     BuildTriangulation(aF);
00193     aTri=BRep_Tool::Triangulation(aF, aLoc);
00194     if(aTri.IsNull()) {
00195       return 1;// a face is without triangulation
00196     }
00197   }
00198   //
00199   aNbNodes=aTri->NbNodes();
00200   aNbTrigs=aTri->NbTriangles();
00201   if (!aNbTrigs){
00202     return 2;//no triangles
00203   }
00204   //
00205   aOr=aF.Orientation();
00206   //
00207   const TColgp_Array1OfPnt& aNodes=aTri->Nodes();
00208   const Poly_Array1OfTriangle& aTriangles=aTri->Triangles();
00209   //
00210   i1=aTriangles.Lower();
00211   i2=aTriangles.Upper();
00212   //
00213   for (i=i1; i<=i2; ++i){
00214     const Poly_Triangle& aTriangle=aTriangles.Value(i);
00215     aTriangle.Get(n[0], n[1], n[2]);
00216     aGC.SetCoord(0.,0.,0.);
00217     for (j=0; j<3; ++j) {
00218       aP[j]=aNodes.Value(n[j]);
00219       aGC.ChangeCoord()+=aP[j].XYZ();
00220     }
00221     aGC.ChangeCoord()*=0.333333333333;
00222     //
00223     // Normal
00224     gp_Vec aV01(aP[0], aP[1]);
00225     gp_Vec aV12(aP[1], aP[2]);
00226     gp_Vec aVN=aV01^aV12;
00227     aAi=aVN.Magnitude();
00228     aA=aA+aAi;
00229     //
00230     if (aAi>0.0000001) {
00231       Standard_Real aSx, aZx;
00232       gp_Dir aDN(aVN);
00233       if (aOr==TopAbs_REVERSED) {
00234         aDN.Reverse();
00235       }
00236       //
00237       aSx=aAi*aDN.Z();
00238       aZx=aGC.Z();
00239       aVi=aZx*aSx;
00240       aV=aV+aVi;
00241     }
00242   }
00243   return 0;
00244 }
00245 //=======================================================================
00246 //function : BuildTriangulation
00247 //purpose  :
00248 //=======================================================================
00249 void BuildTriangulation(const TopoDS_Face& aF)
00250 {
00251   Standard_Boolean bWithShare;
00252   Standard_Real aDiscret, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
00253   Standard_Real dX, dY, dZ, dMax, aCoeff, aAngle;
00254   Bnd_Box aBox;
00255   //
00256   bWithShare=Standard_False;
00257   aAngle=0.5;
00258   //
00259   BRepBndLib::Add(aF, aBox);
00260   //
00261   // aDiscret
00262   aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
00263   dX=aXmax-aXmin;
00264   dY=aYmax-aYmin;
00265   dZ=aZmax-aZmin;
00266   dMax=dX;
00267   if (dY>dMax) {
00268     dMax=dY;
00269   }
00270   if (dZ>dMax) {
00271     dMax=dZ;
00272   }
00273   //
00274   aCoeff=0.1;
00275   aDiscret=aCoeff*dMax;
00276   //
00277   BRepMesh_FastDiscret aMesher(aDiscret,
00278                                aAngle,
00279                                aBox,
00280                                bWithShare,
00281                                Standard_True,
00282                                Standard_False,
00283                                Standard_True);
00284 
00285 #if OCC_VERSION_LARGE > 0x06050100 // for OCC-6.5.2 and higher version
00286   TopTools_IndexedDataMapOfShapeListOfShape anAncestors;
00287   TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, anAncestors);
00288   aMesher.Add(aF, anAncestors);
00289 #else
00290   aMesher.Add(aF);
00291 #endif
00292 }