Salome HOME
Merge from V5_1_main 14/05/2010
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_BuilderTools.cxx
1 //  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File:        GEOMAlgo_BuilderTools.cxx
24 // Created:     
25 // Author:      Peter KURNEV
26 //              <pkv@irinox>
27 //
28 #include <GEOMAlgo_BuilderTools.ixx>
29
30 #include <TColStd_Array1OfReal.hxx>
31
32 #include <gp_Pnt2d.hxx>
33 #include <gp_Vec.hxx>
34 #include <gp_Dir.hxx>
35 #include <gp_Pnt.hxx>
36
37 #include <TColgp_Array1OfPnt.hxx>
38
39 #include <Poly_Triangulation.hxx>
40 #include <Poly_Array1OfTriangle.hxx>
41 #include <Poly_Triangle.hxx>
42
43 #include <Geom2d_Curve.hxx>
44 #include <Geom2dInt_Geom2dCurveTool.hxx>
45
46 #include <TopLoc_Location.hxx>
47 #include <TopAbs_Orientation.hxx>
48
49 #include <TopoDS_Face.hxx>
50 #include <TopoDS_Iterator.hxx>
51 #include <TopoDS_Wire.hxx>
52 #include <TopoDS.hxx>
53 #include <TopoDS_Edge.hxx>
54 #include <TopExp_Explorer.hxx>
55
56 #include <BRep_Tool.hxx>
57 #include <BRepBndLib.hxx>
58 #include <BRepMesh_FastDiscret.hxx>
59 #include <Bnd_Box.hxx>
60 #include <BRepAdaptor_Curve2d.hxx>
61
62 static 
63   Standard_Integer ComputeProps(const TopoDS_Face& aF,
64                                 Standard_Real& aA,
65                                 Standard_Real& aV);
66 static
67   void BuildTriangulation(const TopoDS_Face& aF);
68
69 //=======================================================================
70 //function : IsHole
71 //purpose  : 
72 //=======================================================================
73   Standard_Boolean GEOMAlgo_BuilderTools::IsHole(const TopoDS_Shape& aW,
74                                                  const TopoDS_Shape& aFace)
75 {
76   Standard_Boolean bIsHole;
77   Standard_Integer i, aNbS;
78   Standard_Real aT1, aT2, aS;
79   Standard_Real aU1, aU2, aU, dU;
80   Standard_Real aX1, aY1, aX0, aY0;
81   TopAbs_Orientation aOr;
82   
83   gp_Pnt2d aP2D0, aP2D1;
84   Handle(Geom2d_Curve) aC2D;
85   TopoDS_Face aF, aFF;
86   TopoDS_Iterator aItW;
87   //
88   bIsHole=Standard_False;
89   //
90   aF=TopoDS::Face(aFace);
91   aFF=aF;
92   aFF.Orientation(TopAbs_FORWARD);
93   //
94   aS=0.;
95   aItW.Initialize(aW);
96   for (; aItW.More(); aItW.Next()) { 
97     const TopoDS_Edge& aE=TopoDS::Edge(aItW.Value());
98     aOr=aE.Orientation();
99     if (!(aOr==TopAbs_FORWARD || 
100           aOr==TopAbs_REVERSED)) {
101       continue;
102     }
103     //
104     aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
105     if (aC2D.IsNull()) {
106       break; //xx
107     }
108     //
109     BRepAdaptor_Curve2d aBAC2D(aE, aFF);
110     aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
111     if (aNbS>2) {
112       aNbS*=4;
113     }
114     //
115     dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
116     aU =aT1;
117     aU1=aT1;
118     aU2=aT2;
119     if (aOr==TopAbs_REVERSED) {
120       aU =aT2;
121       aU1=aT2;
122       aU2=aT1;
123       dU=-dU;
124     }
125     //
126     aC2D->D0(aU, aP2D0);
127     for(i=2; i<=aNbS; i++) {
128       aU=aU1+(i-1)*dU;
129       aC2D->D0(aU, aP2D1);
130       aP2D0.Coord(aX0, aY0);
131       aP2D1.Coord(aX1, aY1);
132       //
133       aS=aS+(aY0+aY1)*(aX1-aX0); 
134       //
135       aP2D0=aP2D1;
136     }
137   }//for (; aItW.More(); aItW.Next()) { 
138   bIsHole=(aS>0.);
139   return bIsHole;
140 }
141 //=======================================================================
142 //function : IsHole
143 //purpose  : 
144 //=======================================================================
145   Standard_Boolean GEOMAlgo_BuilderTools::IsHole(const TopoDS_Shape& aShell)
146 {
147   Standard_Boolean bIsHole;
148   Standard_Integer iRet;
149   Standard_Real aAi, aA, aV, aVi;
150   TopExp_Explorer aExp;
151   //
152   aA=0.;
153   aV=0.;
154   aExp.Init(aShell, TopAbs_FACE);
155   for (; aExp.More(); aExp.Next()) {
156     const TopoDS_Face& aF=TopoDS::Face(aExp.Current());
157     iRet=ComputeProps(aF, aAi, aVi);
158     if (!iRet) {
159       aA+=aAi;
160       aV+=aVi;
161     }
162   }
163   //
164   bIsHole=aV<0.;
165   return bIsHole;
166 }
167 //=======================================================================
168 //function : ComputeProps
169 //purpose  : 
170 //=======================================================================
171 Standard_Integer ComputeProps(const TopoDS_Face& aF,
172                               Standard_Real& aA,
173                               Standard_Real& aV)
174 {
175   Standard_Integer j, i, i1, i2, aNbNodes, aNbTrigs, n[3];
176   Standard_Real aAi, aVi;
177   gp_Pnt aP[3], aGC, aGC1;
178   TopLoc_Location aLoc;
179   TopAbs_Orientation aOr;
180   Handle(Poly_Triangulation) aTri;
181   //
182   aA=0.;
183   aV=0.;
184   //
185   aTri=BRep_Tool::Triangulation(aF, aLoc);
186   if(aTri.IsNull()) {
187     BuildTriangulation(aF);
188     aTri=BRep_Tool::Triangulation(aF, aLoc);
189     if(aTri.IsNull()) {
190       return 1;// a face is without triangulation
191     }
192   }
193   //
194   aNbNodes=aTri->NbNodes();
195   aNbTrigs=aTri->NbTriangles();
196   if (!aNbTrigs){
197     return 2;//no triangles
198   }
199   //
200   aOr=aF.Orientation();
201   //
202   const TColgp_Array1OfPnt& aNodes=aTri->Nodes();
203   const Poly_Array1OfTriangle& aTriangles=aTri->Triangles();
204   //
205   i1=aTriangles.Lower();
206   i2=aTriangles.Upper();
207   //
208   for (i=i1; i<=i2; ++i){
209     const Poly_Triangle& aTriangle=aTriangles.Value(i);
210     aTriangle.Get(n[0], n[1], n[2]);
211     aGC.SetCoord(0.,0.,0.);
212     for (j=0; j<3; ++j) {
213       aP[j]=aNodes.Value(n[j]);
214       aGC.ChangeCoord()+=aP[j].XYZ();
215     }
216     aGC.ChangeCoord()*=0.333333333333;
217     //
218     // Normal
219     gp_Vec aV01(aP[0], aP[1]);
220     gp_Vec aV12(aP[1], aP[2]);
221     gp_Vec aVN=aV01^aV12;
222     aAi=aVN.Magnitude();
223     aA=aA+aAi;
224     //
225     if (aAi>0.0000001) {
226       Standard_Real aSx, aZx;
227       gp_Dir aDN(aVN);
228       if (aOr==TopAbs_REVERSED) {
229         aDN.Reverse();
230       }
231       //
232       aSx=aAi*aDN.Z();
233       aZx=aGC.Z();
234       aVi=aZx*aSx;
235       aV=aV+aVi;
236     }
237   }
238   return 0;
239 }
240 //=======================================================================
241 //function : BuildTriangulation
242 //purpose  : 
243 //=======================================================================
244 void BuildTriangulation(const TopoDS_Face& aF)
245 {
246   Standard_Boolean bWithShare;
247   Standard_Real aDiscret, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
248   Standard_Real dX, dY, dZ, dMax, aCoeff, aAngle;
249   Bnd_Box aBox;
250   //
251   bWithShare=Standard_False;
252   aAngle=0.5;
253   //
254   BRepBndLib::Add(aF, aBox);
255   //
256   // aDiscret
257   aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
258   dX=aXmax-aXmin;
259   dY=aYmax-aYmin;
260   dZ=aZmax-aZmin;
261   dMax=dX;
262   if (dY>dMax) {
263     dMax=dY;
264   }
265   if (dZ>dMax) {
266     dMax=dZ;
267   }
268   //
269   aCoeff=0.1;
270   aDiscret=aCoeff*dMax;
271   //
272   BRepMesh_FastDiscret aMesher(aDiscret,
273                                aAngle,
274                                aBox,
275                                bWithShare,
276                                Standard_True,
277                                Standard_False,
278                                Standard_True);
279   aMesher.Add(aF);
280 }