Salome HOME
Update from BR_V5_DEV 13Feb2009
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_BuilderTools.cxx
1 //  Copyright (C) 2007-2008  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 // File:        GEOMAlgo_BuilderTools.cxx
23 // Created:     
24 // Author:      Peter KURNEV
25 //              <pkv@irinox>
26 //
27 #include <GEOMAlgo_BuilderTools.ixx>
28
29 #include <TColStd_Array1OfReal.hxx>
30
31 #include <gp_Pnt2d.hxx>
32 #include <gp_Vec.hxx>
33 #include <gp_Dir.hxx>
34 #include <gp_Pnt.hxx>
35
36 #include <TColgp_Array1OfPnt.hxx>
37
38 #include <Poly_Triangulation.hxx>
39 #include <Poly_Array1OfTriangle.hxx>
40 #include <Poly_Triangle.hxx>
41
42 #include <Geom2d_Curve.hxx>
43 #include <Geom2dInt_Geom2dCurveTool.hxx>
44
45 #include <TopLoc_Location.hxx>
46 #include <TopAbs_Orientation.hxx>
47
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Iterator.hxx>
50 #include <TopoDS_Wire.hxx>
51 #include <TopoDS.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopExp_Explorer.hxx>
54
55 #include <BRep_Tool.hxx>
56 #include <BRepBndLib.hxx>
57 #include <BRepMesh_FastDiscret.hxx>
58 #include <Bnd_Box.hxx>
59 #include <BRepAdaptor_Curve2d.hxx>
60
61 static 
62   Standard_Integer ComputeProps(const TopoDS_Face& aF,
63                                 Standard_Real& aA,
64                                 Standard_Real& aV);
65 static
66   void BuildTriangulation(const TopoDS_Face& aF);
67
68 //=======================================================================
69 //function : IsHole
70 //purpose  : 
71 //=======================================================================
72   Standard_Boolean GEOMAlgo_BuilderTools::IsHole(const TopoDS_Shape& aW,
73                                                  const TopoDS_Shape& aFace)
74 {
75   Standard_Boolean bIsHole;
76   Standard_Integer i, aNbS;
77   Standard_Real aT1, aT2, aS;
78   Standard_Real aU1, aU2, aU, dU;
79   Standard_Real aX1, aY1, aX0, aY0;
80   TopAbs_Orientation aOr;
81   
82   gp_Pnt2d aP2D0, aP2D1;
83   Handle(Geom2d_Curve) aC2D;
84   TopoDS_Face aF, aFF;
85   TopoDS_Iterator aItW;
86   //
87   bIsHole=Standard_False;
88   //
89   aF=TopoDS::Face(aFace);
90   aFF=aF;
91   aFF.Orientation(TopAbs_FORWARD);
92   //
93   aS=0.;
94   aItW.Initialize(aW);
95   for (; aItW.More(); aItW.Next()) { 
96     const TopoDS_Edge& aE=TopoDS::Edge(aItW.Value());
97     aOr=aE.Orientation();
98     if (!(aOr==TopAbs_FORWARD || 
99           aOr==TopAbs_REVERSED)) {
100       continue;
101     }
102     //
103     aC2D=BRep_Tool::CurveOnSurface(aE, aFF, aT1, aT2);
104     if (aC2D.IsNull()) {
105       break; //xx
106     }
107     //
108     BRepAdaptor_Curve2d aBAC2D(aE, aFF);
109     aNbS=Geom2dInt_Geom2dCurveTool::NbSamples(aBAC2D);
110     if (aNbS>2) {
111       aNbS*=4;
112     }
113     //
114     dU=(aT2-aT1)/(Standard_Real)(aNbS-1);
115     aU =aT1;
116     aU1=aT1;
117     aU2=aT2;
118     if (aOr==TopAbs_REVERSED) {
119       aU =aT2;
120       aU1=aT2;
121       aU2=aT1;
122       dU=-dU;
123     }
124     //
125     aC2D->D0(aU, aP2D0);
126     for(i=2; i<=aNbS; i++) {
127       aU=aU1+(i-1)*dU;
128       aC2D->D0(aU, aP2D1);
129       aP2D0.Coord(aX0, aY0);
130       aP2D1.Coord(aX1, aY1);
131       //
132       aS=aS+(aY0+aY1)*(aX1-aX0); 
133       //
134       aP2D0=aP2D1;
135     }
136   }//for (; aItW.More(); aItW.Next()) { 
137   bIsHole=(aS>0.);
138   return bIsHole;
139 }
140 //=======================================================================
141 //function : IsHole
142 //purpose  : 
143 //=======================================================================
144   Standard_Boolean GEOMAlgo_BuilderTools::IsHole(const TopoDS_Shape& aShell)
145 {
146   Standard_Boolean bIsHole;
147   Standard_Integer iRet;
148   Standard_Real aAi, aA, aV, aVi;
149   TopExp_Explorer aExp;
150   //
151   aA=0.;
152   aV=0.;
153   aExp.Init(aShell, TopAbs_FACE);
154   for (; aExp.More(); aExp.Next()) {
155     const TopoDS_Face& aF=TopoDS::Face(aExp.Current());
156     iRet=ComputeProps(aF, aAi, aVi);
157     if (!iRet) {
158       aA+=aAi;
159       aV+=aVi;
160     }
161   }
162   //
163   bIsHole=aV<0.;
164   return bIsHole;
165 }
166 //=======================================================================
167 //function : ComputeProps
168 //purpose  : 
169 //=======================================================================
170 Standard_Integer ComputeProps(const TopoDS_Face& aF,
171                               Standard_Real& aA,
172                               Standard_Real& aV)
173 {
174   Standard_Integer j, i, i1, i2, aNbNodes, aNbTrigs, n[3];
175   Standard_Real aAi, aVi;
176   gp_Pnt aP[3], aGC, aGC1;
177   TopLoc_Location aLoc;
178   TopAbs_Orientation aOr;
179   Handle(Poly_Triangulation) aTri;
180   //
181   aA=0.;
182   aV=0.;
183   //
184   aTri=BRep_Tool::Triangulation(aF, aLoc);
185   if(aTri.IsNull()) {
186     BuildTriangulation(aF);
187     aTri=BRep_Tool::Triangulation(aF, aLoc);
188     if(aTri.IsNull()) {
189       return 1;// a face is without triangulation
190     }
191   }
192   //
193   aNbNodes=aTri->NbNodes();
194   aNbTrigs=aTri->NbTriangles();
195   if (!aNbTrigs){
196     return 2;//no triangles
197   }
198   //
199   aOr=aF.Orientation();
200   //
201   const TColgp_Array1OfPnt& aNodes=aTri->Nodes();
202   const Poly_Array1OfTriangle& aTriangles=aTri->Triangles();
203   //
204   i1=aTriangles.Lower();
205   i2=aTriangles.Upper();
206   //
207   for (i=i1; i<=i2; ++i){
208     const Poly_Triangle& aTriangle=aTriangles.Value(i);
209     aTriangle.Get(n[0], n[1], n[2]);
210     aGC.SetCoord(0.,0.,0.);
211     for (j=0; j<3; ++j) {
212       aP[j]=aNodes.Value(n[j]);
213       aGC.ChangeCoord()+=aP[j].XYZ();
214     }
215     aGC.ChangeCoord()*=0.333333333333;
216     //
217     // Normal
218     gp_Vec aV01(aP[0], aP[1]);
219     gp_Vec aV12(aP[1], aP[2]);
220     gp_Vec aVN=aV01^aV12;
221     aAi=aVN.Magnitude();
222     aA=aA+aAi;
223     //
224     if (aAi>0.0000001) {
225       Standard_Real aSx, aZx;
226       gp_Dir aDN(aVN);
227       if (aOr==TopAbs_REVERSED) {
228         aDN.Reverse();
229       }
230       //
231       aSx=aAi*aDN.Z();
232       aZx=aGC.Z();
233       aVi=aZx*aSx;
234       aV=aV+aVi;
235     }
236   }
237   return 0;
238 }
239 //=======================================================================
240 //function : BuildTriangulation
241 //purpose  : 
242 //=======================================================================
243 void BuildTriangulation(const TopoDS_Face& aF)
244 {
245   Standard_Boolean bWithShare;
246   Standard_Real aDiscret, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
247   Standard_Real dX, dY, dZ, dMax, aCoeff, aAngle;
248   Bnd_Box aBox;
249   //
250   bWithShare=Standard_False;
251   aAngle=0.5;
252   //
253   BRepBndLib::Add(aF, aBox);
254   //
255   // aDiscret
256   aBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
257   dX=aXmax-aXmin;
258   dY=aYmax-aYmin;
259   dZ=aZmax-aZmin;
260   dMax=dX;
261   if (dY>dMax) {
262     dMax=dY;
263   }
264   if (dZ>dMax) {
265     dMax=dZ;
266   }
267   //
268   aCoeff=0.1;
269   aDiscret=aCoeff*dMax;
270   //
271   BRepMesh_FastDiscret aMesher(aDiscret,
272                                aAngle,
273                                aBox,
274                                bWithShare,
275                                Standard_True,
276                                Standard_False,
277                                Standard_True);
278   aMesher.Add(aF);
279 }