Salome HOME
25b9d0ecdfc587e19975b832e0be27da27750a1b
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_GetInPlace_1.cxx
1 // Copyright (C) 2007-2023  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   TopoDS_Face aF;
243   TopExp_Explorer aExp;
244   //
245   iErr=0;
246   aCoef=10.;
247   //
248   aExp.Init (aZ, TopAbs_FACE);
249   if (aExp.More()) {
250     aF=*((TopoDS_Face*)&aExp.Current());
251   }
252   //
253   iErr=PntInFace(aF, aPx, aP2Dx);
254   if (iErr) {
255     return iErr;
256   }
257   //
258   aP2Dx.Coord(aUx, aVx);
259   GEOMAlgo_AlgoTools::FaceNormal(aF, aUx, aVx, aDNx);
260   aDNx.Reverse();
261   //
262   aP.SetXYZ(aPx.XYZ()+aCoef*aTol*aDNx.XYZ());
263   //
264   return iErr;
265 }
266 //=======================================================================
267 //function : PntInFace
268 //purpose  :
269 //=======================================================================
270 Standard_Integer PntInFace(const TopoDS_Face& aF,
271                            gp_Pnt& aP)
272 {
273   Standard_Integer iErr;
274   //
275   gp_Pnt2d aP2Dx;
276   //
277   iErr=PntInFace(aF, aP, aP2Dx);
278   //
279   return iErr;
280 }
281 //=======================================================================
282 //function : PntInFace
283 //purpose  :
284 //=======================================================================
285 Standard_Integer PntInFace(const TopoDS_Face& aF,
286                            gp_Pnt& theP,
287                            gp_Pnt2d& theP2D)
288 {
289   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
290   Standard_Integer iErr, aIx, aNbDomains, i;
291   Standard_Real aUMin, aUMax, aVMin, aVMax;
292   Standard_Real aVx, aUx, aV1, aV2, aU1, aU2, aEpsT;
293   Standard_Real aTotArcIntr, aTolTangfIntr, aTolHatch2D, aTolHatch3D;
294   gp_Dir2d aD2D (0., 1.);
295   gp_Pnt2d aP2D;
296   gp_Pnt aPx;
297   Handle(Geom2d_Curve) aC2D;
298   Handle(Geom2d_TrimmedCurve) aCT2D;
299   Handle(Geom2d_Line) aL2D;
300   Handle(Geom_Surface) aS;
301   TopAbs_Orientation aOrE;
302   TopoDS_Face aFF;
303   TopExp_Explorer aExp;
304   //
305   aTolHatch2D=1.e-8;
306   aTolHatch3D=1.e-8;
307   aTotArcIntr=1.e-10;
308   aTolTangfIntr=1.e-10;
309   //
310   Geom2dHatch_Intersector aIntr(aTotArcIntr, aTolTangfIntr);
311   Geom2dHatch_Hatcher aHatcher(aIntr,
312                                aTolHatch2D, aTolHatch3D,
313                                Standard_True, Standard_False);
314   //
315   iErr=0;
316   aEpsT=1.e-12;
317   //
318   aFF=aF;
319   aFF.Orientation (TopAbs_FORWARD);
320   //
321   aS=BRep_Tool::Surface(aFF);
322   BRepTools::UVBounds(aFF, aUMin, aUMax, aVMin, aVMax);
323   //
324   // 1
325   aExp.Init (aFF, TopAbs_EDGE);
326   for (; aExp.More() ; aExp.Next()) {
327     const TopoDS_Edge& aE=*((TopoDS_Edge*)&aExp.Current());
328     aOrE=aE.Orientation();
329     //
330     aC2D=BRep_Tool::CurveOnSurface (aE, aFF, aU1, aU2);
331     if (aC2D.IsNull() ) {
332       iErr=1;
333       return iErr;
334     }
335     if (fabs(aU1-aU2) < aEpsT) {
336       iErr=2;
337       return iErr;
338     }
339     //
340     aCT2D=new Geom2d_TrimmedCurve(aC2D, aU1, aU2);
341     aHatcher.AddElement(aCT2D, aOrE);
342   }// for (; aExp.More() ; aExp.Next()) {
343   //
344   // 2
345   aUx=IntTools_Tools::IntermediatePoint(aUMin, aUMax);
346   aP2D.SetCoord(aUx, 0.);
347   aL2D=new Geom2d_Line (aP2D, aD2D);
348   Geom2dAdaptor_Curve aHCur(aL2D);
349   //
350   aIx=aHatcher.AddHatching(aHCur) ;
351   //
352   // 3.
353   aHatcher.Trim();
354   bIsDone=aHatcher.TrimDone(aIx);
355   if (!bIsDone) {
356     iErr=3;
357     return iErr;
358   }
359   //
360   aHatcher.ComputeDomains(aIx);
361   bIsDone=aHatcher.IsDone(aIx);
362   if (!bIsDone) {
363     iErr=4;
364     return iErr;
365   }
366   //
367   // 4.
368   aNbDomains=aHatcher.NbDomains(aIx);
369   if (!aNbDomains) {
370     iErr=5;
371     return iErr;
372   }
373   //
374   i=1;
375   const HatchGen_Domain& aDomain=aHatcher.Domain (aIx, i) ;
376   bHasFirstPoint=aDomain.HasFirstPoint();
377   if (!bHasFirstPoint) {
378     iErr=5;
379     return iErr;
380   }
381   //
382   aV1=aDomain.FirstPoint().Parameter();
383   //
384   bHasSecondPoint=aDomain.HasSecondPoint();
385   if (!bHasSecondPoint) {
386     iErr=6;
387     return iErr;
388   }
389   //
390   aV2=aDomain.SecondPoint().Parameter();
391   //
392   aVx=IntTools_Tools::IntermediatePoint(aV1, aV2);
393   //
394   aS->D0(aUx, aVx, aPx);
395   //
396   theP2D.SetCoord(aUx, aVx);
397   theP=aPx;
398   //
399   return iErr;
400 }
401