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