Salome HOME
Win32 compliation.
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_GetInPlace_1.cxx
1 // Copyright (C) 2007-2011  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_GetInPlace_1.cxx
23 // Author:   Peter KURNEV
24
25 #include <GEOMAlgo_GetInPlace.hxx>
26
27 #include <Basics_OCCTVersion.hxx>
28
29 #include <math.h>
30
31 #include <gp_Pnt.hxx>
32 #include <gp_Vec.hxx>
33 #include <gp_Pnt2d.hxx>
34 #include <gp_Dir2d.hxx>
35
36 #include <Geom_Surface.hxx>
37 #include <Geom2d_Curve.hxx>
38 #include <Geom2d_Line.hxx>
39 #include <Geom2d_TrimmedCurve.hxx>
40 #include <Geom2dAdaptor_Curve.hxx>
41 #include <Geom2dHatch_Hatcher.hxx>
42 #include <Geom2dHatch_Intersector.hxx>
43 #include <GeomAPI_ProjectPointOnCurve.hxx>
44
45 #include <HatchGen_Domain.hxx>
46
47 #include <TopAbs_State.hxx>
48 #include <TopAbs_ShapeEnum.hxx>
49 #include <TopAbs_Orientation.hxx>
50
51 #include <TopoDS_Vertex.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Solid.hxx>
54 #include <TopoDS_Face.hxx>
55
56 #include <TopExp_Explorer.hxx>
57
58 #include <BRep_Tool.hxx>
59 #include <BRepTools.hxx>
60 #include <BRepClass3d_SolidClassifier.hxx>
61
62 #include <IntTools_Tools.hxx>
63
64 #include <BOPTools_Tools3D.hxx>
65 #include <BOPTools_Tools2D.hxx>
66
67
68 static
69   Standard_Integer PntInEdge(const TopoDS_Edge& aF,
70                              gp_Pnt& aP);
71 static
72   Standard_Integer PntInEdge(const TopoDS_Edge& aF,
73                              gp_Pnt& aP,
74                              Standard_Real& aT);
75 static
76   Standard_Integer PntInFace(const TopoDS_Face& aF,
77                              gp_Pnt& aP);
78 static
79   Standard_Integer PntInFace(const TopoDS_Face& aF,
80                              gp_Pnt& aP,
81                              gp_Pnt2d& theP2D);
82 static
83   Standard_Integer PntInSolid(const TopoDS_Solid& aZ,
84                               const Standard_Real aTol,
85                               gp_Pnt& aP);
86
87 //=======================================================================
88 //function : CheckCoincidence
89 //purpose  :
90 //=======================================================================
91 Standard_Boolean GEOMAlgo_GetInPlace::CheckCoincidence(const TopoDS_Shape& aS1,
92                                                        const TopoDS_Shape& aS2)
93 {
94   Standard_Boolean bOk;
95   Standard_Integer iErr;
96   Standard_Real aTol2;
97   TopAbs_ShapeEnum aType1, aType2;
98   TopAbs_State aState;
99   gp_Pnt aP1, aP2;
100   //
101   myErrorStatus=0;
102   //
103   iErr=0;
104   bOk=Standard_False;
105   aTol2=myTolerance*myTolerance;
106   aType1=aS1.ShapeType();
107   aType2=aS2.ShapeType();
108   //
109   // 1. A point on shape #2 -> aP2
110   if (myMapShapePnt.IsBound(aS2)) {
111     aP2=myMapShapePnt.Find(aS2);
112   }
113   else {//else 1
114     if (aType2==TopAbs_VERTEX) {
115       const TopoDS_Vertex& aV2=*((TopoDS_Vertex*)&aS2);
116       aP2=BRep_Tool::Pnt(aV2);
117     }
118     //
119     else if (aType2==TopAbs_EDGE) {
120       const TopoDS_Edge& aE2=*((TopoDS_Edge*)&aS2);
121       iErr=PntInEdge(aE2, aP2);
122     }
123     //
124     else if (aType2==TopAbs_FACE) {
125       const TopoDS_Face& aF2=*((TopoDS_Face*)&aS2);
126       iErr=PntInFace(aF2, aP2);
127     }
128     //
129     else if (aType2==TopAbs_SOLID) {
130       const TopoDS_Solid& aZ2=*((TopoDS_Solid*)&aS2);
131       iErr=PntInSolid(aZ2, myTolerance, aP2);
132     }
133     //
134     else {
135       iErr=1;
136     }
137     //
138     if (iErr) {
139       myErrorStatus=50;
140       return bOk;
141     }
142     //
143     myMapShapePnt.Bind(aS2, aP2);
144   } //else 1
145   //
146   // 2. Project the point aP2 on shape #1 and check
147   if (aType1==TopAbs_EDGE) {
148     Standard_Integer aNbPoints;
149     Standard_Real aDmin, aT, aT1, aT2, dT;
150     //
151     const TopoDS_Edge& aE1=*((TopoDS_Edge*)&aS1);
152     //
153 #if OCC_VERSION_LARGE > 0x06050200
154     GeomAPI_ProjectPointOnCurve& aPPC=myContext->ProjPC(aE1);
155 #else
156     GeomAPI_ProjectPointOnCurve& aPPC=myContext.ProjPC(aE1);
157 #endif
158     aPPC.Perform(aP2);
159     aNbPoints=aPPC.NbPoints();
160     if (aNbPoints) {
161       aDmin=aPPC.LowerDistance();
162       aT=aPPC.LowerDistanceParameter();
163       if (aDmin < myTolerance) {
164         dT=1.e-12;
165         BRep_Tool::Curve(aE1, aT1, aT2);
166         if(aT > (aT1-dT) && aT < (aT2+dT)) {
167           bOk=Standard_True;
168         }
169       }
170     }
171     //else {
172     // iErr=2;
173     //}
174   }//if (aType1==TopAbs_EDGE) {
175   //
176   else if (aType1==TopAbs_FACE) {
177     const TopoDS_Face& aF1=*((TopoDS_Face*)&aS1);
178     //
179 #if OCC_VERSION_LARGE > 0x06050200
180     bOk=myContext->IsValidPointForFace(aP2, aF1, myTolerance);
181 #else
182     bOk=myContext.IsValidPointForFace(aP2, aF1, myTolerance);
183 #endif
184   }
185   //
186   else if (aType1==TopAbs_SOLID) {
187     const TopoDS_Solid& aZ1=*((TopoDS_Solid*)&aS1);
188     //
189 #if OCC_VERSION_LARGE > 0x06050200
190     BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aZ1);
191 #else
192     BRepClass3d_SolidClassifier& aSC=myContext.SolidClassifier(aZ1);
193 #endif
194     aSC.Perform(aP2, myTolerance);
195     aState=aSC.State();
196     bOk=(aState==TopAbs_IN);
197   }
198   //
199   if (iErr) {
200     myErrorStatus=50;
201   }
202   //
203   return bOk;
204 }
205 //=======================================================================
206 //
207 //=======================================================================
208 //function : PntInEdge
209 //purpose  :
210 //=======================================================================
211 Standard_Integer PntInEdge(const TopoDS_Edge& aE,
212                            gp_Pnt& aP)
213 {
214   Standard_Integer iErr;
215   Standard_Real aT;
216   //
217   iErr=PntInEdge(aE, aP, aT);
218   //
219   return iErr;
220 }
221 //=======================================================================
222 //function : PntInEdge
223 //purpose  :
224 //=======================================================================
225 Standard_Integer PntInEdge(const TopoDS_Edge& aE,
226                            gp_Pnt& aP,
227                            Standard_Real& aT)
228 {
229   Standard_Integer iErr;
230   Standard_Real aT1, aT2;
231   Handle(Geom_Curve) aC3D;
232   //
233   iErr=0;
234   //
235   aC3D=BRep_Tool::Curve(aE, aT1, aT2);
236   aT=IntTools_Tools::IntermediatePoint(aT1, aT2);
237   aC3D->D0(aT, aP);
238   //
239   return iErr;
240 }
241 //=======================================================================
242 //function : PntInSolid
243 //purpose  :
244 //=======================================================================
245 Standard_Integer PntInSolid(const TopoDS_Solid& aZ,
246                             const Standard_Real aTol,
247                             gp_Pnt& aP)
248 {
249   Standard_Integer iErr;
250   Standard_Real aUx, aVx, aCoef;
251   gp_Pnt aPx;
252   gp_Pnt2d aP2Dx;
253   gp_Vec aDNx;
254
255   TopoDS_Face aF;
256   TopExp_Explorer aExp;
257   //
258   iErr=0;
259   aCoef=10.;
260   //
261   aExp.Init (aZ, TopAbs_FACE);
262   for (; aExp.More() ; aExp.Next()) {
263     aF=*((TopoDS_Face*)&aExp.Current());
264     break;
265   }
266   //
267   iErr=PntInFace(aF, aPx, aP2Dx);
268   if (iErr) {
269     return iErr;
270   }
271   //
272   aP2Dx.Coord(aUx, aVx);
273   BOPTools_Tools2D::FaceNormal(aF, aUx, aVx, aDNx);
274   aDNx.Reverse();
275   //
276   aP.SetXYZ(aPx.XYZ()+aCoef*aTol*aDNx.XYZ());
277   //
278   return iErr;
279 }
280 //=======================================================================
281 //function : PntInFace
282 //purpose  :
283 //=======================================================================
284 Standard_Integer PntInFace(const TopoDS_Face& aF,
285                            gp_Pnt& aP)
286 {
287   Standard_Integer iErr;
288   //
289   gp_Pnt2d aP2Dx;
290   //
291   iErr=PntInFace(aF, aP, aP2Dx);
292   //
293   return iErr;
294 }
295 //=======================================================================
296 //function : PntInFace
297 //purpose  :
298 //=======================================================================
299 Standard_Integer PntInFace(const TopoDS_Face& aF,
300                            gp_Pnt& theP,
301                            gp_Pnt2d& theP2D)
302 {
303   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
304   Standard_Integer iErr, aIx, aNbDomains, i;
305   Standard_Real aUMin, aUMax, aVMin, aVMax;
306   Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT;
307   Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
308   gp_Dir2d aD2D (0., 1.);
309   gp_Pnt2d aP2D;
310   gp_Pnt aPx;
311   Handle(Geom2d_Curve) aC2D;
312   Handle(Geom2d_TrimmedCurve) aCT2D;
313   Handle(Geom2d_Line) aL2D;
314   Handle(Geom_Surface) aS;
315   TopAbs_Orientation aOrE;
316   TopoDS_Face aFF;
317   TopExp_Explorer aExp;
318   //
319   aTolHatch2D=1.e-8;
320   aTolHatch3D=1.e-8;
321   aTotArcIntr=1.e-10;
322   aTolTangfIntr=1.e-10;
323   //
324   Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr);
325   Geom2dHatch_Hatcher aHatcher(aIntr,
326                                aTolHatch2D, aTolHatch3D,
327                                Standard_True, Standard_False);
328   //
329   iErr=0;
330   aEpsT=1.e-12;
331   //
332   aFF=aF;
333   aFF.Orientation (TopAbs_FORWARD);
334   //
335   aS=BRep_Tool::Surface(aFF);
336   BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
337   //
338   // 1
339   aExp.Init (aFF, TopAbs_EDGE);
340   for (; aExp.More() ; aExp.Next()) {
341     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
342     aOrE=aE.Orientation();
343     //
344     aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
345     if (aC2D.IsNull() ) {
346       iErr=1;
347       return iErr;
348     }
349     if (fabs(aU1-aU2) < aEpsT) {
350       iErr=2;
351       return iErr;
352     }
353     //
354     aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
355     aHatcher.AddElement(aCT2D, aOrE);
356   }// for (; aExp.More() ; aExp.Next()) {
357   //
358   // 2
359   aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
360   aP2D.SetCoord(aUx, 0.);
361   aL2D=new Geom2d_Line (aP2D, aD2D);
362   Geom2dAdaptor_Curve aHCur(aL2D);
363   //
364   aIx=aHatcher.AddHatching(aHCur) ;
365   //
366   // 3.
367   aHatcher.Trim();
368   bIsDone=aHatcher.TrimDone(aIx);
369   if (!bIsDone) {
370     iErr=3;
371     return iErr;
372   }
373   //
374   aHatcher.ComputeDomains(aIx);
375   bIsDone=aHatcher.IsDone(aIx);
376   if (!bIsDone) {
377     iErr=4;
378     return iErr;
379   }
380   //
381   // 4.
382   aNbDomains=aHatcher.NbDomains(aIx);
383   for (i=1; i<=aNbDomains; ++i) {
384     const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
385     bHasFirstPoint=aDomain.HasFirstPoint();
386     if (!bHasFirstPoint) {
387       iErr=5;
388       return iErr;
389     }
390     //
391     aV1=aDomain.FirstPoint().Parameter();
392     //
393     bHasSecondPoint=aDomain.HasSecondPoint();
394     if (!bHasSecondPoint) {
395       iErr=6;
396       return iErr;
397     }
398     //
399     aV2=aDomain.SecondPoint().Parameter();
400     //
401     aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
402     //
403     break;
404   }
405   //
406   aS->D0(aUx, aVx, aPx);
407   //
408   theP2D.SetCoord(aUx, aVx);
409   theP=aPx;
410   //
411   return iErr;
412 }