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