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