Integration of OCCT 6.5.0 from SVN
[occt.git] / src / IntTools / IntTools_Tools.cxx
CommitLineData
7fd59977 1// File: IntTools_Tools.cxx
2// Created: Thu Nov 16 11:42:23 2000
3// Author: Peter KURNEV
4// <pkv@irinox>
5//
6
7#include <IntTools_Tools.ixx>
8
9#include <Precision.hxx>
10
11#include <TopExp_Explorer.hxx>
12#include <TopTools_IndexedDataMapOfShapeShape.hxx>
13
14#include <TopoDS.hxx>
15#include <TopoDS_Shape.hxx>
16#include <TopoDS_Vertex.hxx>
17#include <TopoDS_Edge.hxx>
18#include <TopoDS_Face.hxx>
19#include <TopoDS_Wire.hxx>
20#include <TopLoc_Location.hxx>
21
22#include <BRep_Builder.hxx>
23#include <BRep_Tool.hxx>
24#include <BRepAdaptor_Surface.hxx>
25#include <BRepAdaptor_Curve.hxx>
26#include <BRepAdaptor_Surface.hxx>
27
28#include <gp_Pnt.hxx>
29#include <gp_Pnt2d.hxx>
30#include <gp.hxx>
31#include <gp_Lin.hxx>
32#include <gp_Dir.hxx>
33#include <gp_Ax1.hxx>
34
35#include <Geom_Curve.hxx>
36#include <GeomAdaptor_Surface.hxx>
37#include <Geom_Surface.hxx>
38#include <GeomAPI_ProjectPointOnSurf.hxx>
39#include <GeomAPI_ProjectPointOnCurve.hxx>
40#include <GeomAdaptor_Curve.hxx>
41#include <GeomAbs_CurveType.hxx>
42#include <Geom_Line.hxx>
43#include <Geom2d_Curve.hxx>
44#include <Geom_BoundedCurve.hxx>
45#include <Geom_Geometry.hxx>
46#include <Geom_TrimmedCurve.hxx>
47#include <Geom2d_TrimmedCurve.hxx>
48
49#include <IntTools_FClass2d.hxx>
50#include <IntTools_Curve.hxx>
51#include <IntTools_SequenceOfCurves.hxx>
52
53static
54 void ParabolaTolerance(const Handle(Geom_Curve)& ,
55 const Standard_Real ,
56 const Standard_Real ,
57 const Standard_Real ,
58 Standard_Real& ,
59 Standard_Real& );
60
61//=======================================================================
62//function : HasInternalEdge
63//purpose :
64//=======================================================================
65 Standard_Boolean IntTools_Tools::HasInternalEdge(const TopoDS_Wire& aW)
66{
67 Standard_Boolean bFlag=Standard_True;
68
69 TopExp_Explorer anExp(aW, TopAbs_EDGE);
70 for (; anExp.More(); anExp.Next()) {
71 const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
72 TopAbs_Orientation anOr=aE.Orientation();
73 if (anOr==TopAbs_INTERNAL) {
74 return bFlag;
75 }
76 }
77 return !bFlag;
78}
79
80//=======================================================================
81//function : IsClosed
82//purpose :
83//=======================================================================
84 Standard_Boolean IntTools_Tools::IsClosed (const Handle(Geom_Curve)& aC3D)
85{
86
87 Standard_Real aF, aL, aDist;
88 gp_Pnt aP1, aP2;
89
90 Handle (Geom_BoundedCurve) aGBC=
91 Handle (Geom_BoundedCurve)::DownCast(aC3D);
92 if (aGBC.IsNull()) {
93 return Standard_False;
94 }
95
96 aF=aC3D->FirstParameter();
97 aL=aC3D-> LastParameter();
98
99 aC3D->D0(aF, aP1);
100 aC3D->D0(aL, aP2);
101
102 aDist=aP1.Distance(aP2);
103 //return (aDist < 1.e-12);
104 return (aDist < Precision::Confusion());
105}
106
107//=======================================================================
108//function : RejectLines
109//purpose :
110//=======================================================================
111 void IntTools_Tools::RejectLines(const IntTools_SequenceOfCurves& aSIn,
112 IntTools_SequenceOfCurves& aSOut)
113{
114 Standard_Integer i, j, aNb;
115 Standard_Boolean bFlag;
116 Handle (Geom_Curve) aC3D;
117
118 gp_Dir aD1, aD2;
119
120 aSOut.Clear();
121
122 aNb=aSIn.Length();
123 for (i=1; i<=aNb; i++) {
124 const IntTools_Curve& IC=aSIn(i);
125 aC3D=IC.Curve();
126 //
127 Handle (Geom_TrimmedCurve) aGTC=
128 Handle (Geom_TrimmedCurve)::DownCast(aC3D);
129
130 if (!aGTC.IsNull()) {
131 aC3D=aGTC->BasisCurve();
132 IntTools_Curve* pIC=(IntTools_Curve*) &IC;
133 pIC->SetCurve(aC3D);
134 }
135 //
136 Handle (Geom_Line) aGLine=
137 Handle (Geom_Line)::DownCast(aC3D);
138
139 if (aGLine.IsNull()) {
140 aSOut.Clear();
141 for (j=1; j<=aNb; j++) {
142 aSOut.Append(aSIn(j));
143 }
144 return;
145 }
146 //
147 gp_Lin aLin=aGLine->Lin();
148 aD2=aLin.Direction();
149 if (i==1) {
150 aSOut.Append(IC);
151 aD1=aD2;
152 continue;
153 }
154
155 bFlag=IntTools_Tools::IsDirsCoinside(aD1, aD2);
156 if (!bFlag) {
157 aSOut.Append(IC);
158 return;
159 }
160 }
161}
162
163//=======================================================================
164//function : IsDirsCoinside
165//purpose :
166//=======================================================================
167 Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1, const gp_Dir& D2)
168{
169 Standard_Boolean bFlag;
170 gp_Pnt P1(D1.X(), D1.Y(), D1.Z());
171 gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
172 Standard_Real dLim=0.0002, d;
173 d=P1.Distance (P2);
174 bFlag= (d<dLim || fabs (2.-d)<dLim);
175 return bFlag;
176}
177
178//=======================================================================
179//function : IsDirsCoinside
180//purpose :
181//=======================================================================
182 Standard_Boolean IntTools_Tools::IsDirsCoinside (const gp_Dir& D1,
183 const gp_Dir& D2,
184 const Standard_Real dLim)
185{
186 Standard_Boolean bFlag;
187 Standard_Real d;
188 //
189 gp_Pnt P1(D1.X(), D1.Y(), D1.Z());
190 gp_Pnt P2(D2.X(), D2.Y(), D2.Z());
191 d=P1.Distance (P2);
192 bFlag= (d<dLim || fabs (2.-d)<dLim);
193 return bFlag;
194}
195//=======================================================================
196//function : SplitCurve
197//purpose :
198//=======================================================================
199 Standard_Integer IntTools_Tools::SplitCurve(const IntTools_Curve& IC,
200 IntTools_SequenceOfCurves& aCvs)
201{
202 Handle (Geom_Curve) aC3D =IC.Curve();
203 if(aC3D.IsNull())
204 return 0;
205 //
206 Handle (Geom2d_Curve) aC2D1=IC.FirstCurve2d();
207 Handle (Geom2d_Curve) aC2D2=IC.SecondCurve2d();
208 Standard_Boolean bIsClosed;
209
210 bIsClosed=IntTools_Tools::IsClosed(aC3D);
211 if (!bIsClosed) {
212 return 0;
213 }
214
215 Standard_Real aF, aL, aMid;
216
217 //
218 aF=aC3D->FirstParameter();
219 aL=aC3D->LastParameter();
220 aMid=0.5*(aF+aL);
221 //modified by NIZNHY-PKV Thu Feb 5 08:26:58 2009 f
222 GeomAdaptor_Curve aGAC(aC3D);
223 GeomAbs_CurveType aCT=aGAC.GetType();
224 if (aCT==GeomAbs_BSplineCurve ||
225 aCT==GeomAbs_BezierCurve) {
226 //aMid=0.5*aMid;
227 aMid=IntTools_Tools::IntermediatePoint(aF, aL);
228 }
229 //modified by NIZNHY-PKV Thu Feb 5 08:27:00 2009 t
230 //
231 Handle(Geom_Curve) aC3DNewF, aC3DNewL;
232 aC3DNewF =new Geom_TrimmedCurve (aC3D, aF, aMid);
233 aC3DNewL =new Geom_TrimmedCurve (aC3D, aMid, aL);
234
235 //
236 Handle (Geom2d_Curve) aC2D1F, aC2D1L, aC2D2F, aC2D2L;
237 //
238 if(!aC2D1.IsNull()) {
239 aC2D1F=new Geom2d_TrimmedCurve (aC2D1, aF, aMid);
240 aC2D1L=new Geom2d_TrimmedCurve (aC2D1, aMid, aL);
241 }
242
243 if(!aC2D2.IsNull()) {
244 aC2D2F=new Geom2d_TrimmedCurve (aC2D2, aF, aMid);
245 aC2D2L=new Geom2d_TrimmedCurve (aC2D2, aMid, aL);
246 }
247 //
248
249 IntTools_Curve aIC1(aC3DNewF, aC2D1F, aC2D2F);
250 IntTools_Curve aIC2(aC3DNewL, aC2D1L, aC2D2L);
251 //
252 aCvs.Append(aIC1);
253 //
254 aCvs.Append(aIC2);
255 //
256 return 2;
257}
258
259//=======================================================================
260//function : IntermediatePoint
261//purpose :
262//=======================================================================
263 Standard_Real IntTools_Tools::IntermediatePoint (const Standard_Real aFirst,
264 const Standard_Real aLast)
265{
266 //define parameter division number as 10*e^(-PI) = 0.43213918
267 const Standard_Real PAR_T = 0.43213918;
268 Standard_Real aParm;
269 aParm=(1.-PAR_T)*aFirst + PAR_T*aLast;
270 return aParm;
271}
272
273//=======================================================================
274//function : IsVertex
275//purpose :
276//=======================================================================
277 Standard_Boolean IntTools_Tools::IsVertex (const gp_Pnt& aP,
278 const Standard_Real aTolPV,
279 const TopoDS_Vertex& aV)
280{
281 Standard_Real aTolV, aD, dTol;
282 gp_Pnt aPv;
283
284 aTolV=BRep_Tool::Tolerance(aV);
285 //
286 //modified by NIZNHY-PKV Thu Jan 18 17:44:46 2007f
287 //aTolV=aTolV+aTolPV;
288 dTol=Precision::Confusion();
289 aTolV=aTolV+aTolPV+dTol;
290 //modified by NIZNHY-PKV Thu Jan 18 17:44:49 2007t
291 //
292 aPv=BRep_Tool::Pnt(aV);
293 aD=aPv.Distance(aP);
294 return (aD<=aTolV);
295}
296
297
298//=======================================================================
299//function : IsVertex
300//purpose :
301//=======================================================================
302 Standard_Boolean IntTools_Tools::IsVertex (const IntTools_CommonPrt& aCmnPrt)
303{
304 Standard_Boolean anIsVertex;
305 Standard_Real aParam;
306
307 const TopoDS_Edge& aE1=aCmnPrt.Edge1();
308 const IntTools_Range& aR1=aCmnPrt.Range1();
309 aParam=0.5*(aR1.First()+aR1.Last());
310 anIsVertex=IntTools_Tools::IsVertex (aE1, aParam);
311
312 if (anIsVertex) {
313 return Standard_True;
314 }
315
316 const TopoDS_Edge& aE2=aCmnPrt.Edge2();
317 const IntTools_SequenceOfRanges& aRs2=aCmnPrt.Ranges2();
318 const IntTools_Range& aR2=aRs2(1);
319 aParam=0.5*(aR2.First()+aR2.Last());
320 anIsVertex=IntTools_Tools::IsVertex (aE2, aParam);
321 if (anIsVertex) {
322 return Standard_True;
323 }
324 return Standard_False;
325}
326
327//=======================================================================
328//function : IsVertex
329//purpose :
330//=======================================================================
331 Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
332 const TopoDS_Vertex& aV,
333 const Standard_Real t)
334{
335 Standard_Real aTolV, aTolV2, d2;
336 gp_Pnt aPv, aPt;
337
338 BRepAdaptor_Curve aBAC(aE);
339 aBAC.D0(t, aPt);
340
341 aTolV=BRep_Tool::Tolerance(aV);
342 aTolV2=aTolV*aTolV;
343 aPv=BRep_Tool::Pnt(aV);
344 d2=aPv.SquareDistance (aPt);
345 if (d2 < aTolV2) {
346 return Standard_True;
347 }
348 return Standard_False;
349}
350//=======================================================================
351//function : IsVertex
352//purpose :
353//=======================================================================
354 Standard_Boolean IntTools_Tools::IsVertex (const TopoDS_Edge& aE,
355 const Standard_Real t)
356{
357 Standard_Real aTolV, aTolV2, d2;
358 TopoDS_Vertex aV;
359 gp_Pnt aPv, aPt;
360
361 BRepAdaptor_Curve aBAC(aE);
362 aBAC.D0(t, aPt);
363
364 TopExp_Explorer anExp(aE, TopAbs_VERTEX);
365 for (; anExp.More(); anExp.Next()) {
366 aV=TopoDS::Vertex (anExp.Current());
367 aTolV=BRep_Tool::Tolerance(aV);
368 aTolV2=aTolV*aTolV;
369 aTolV2=1.e-12;
370 aPv=BRep_Tool::Pnt(aV);
371 d2=aPv.SquareDistance (aPt);
372 if (d2 < aTolV2) {
373 return Standard_True;
374 }
375 }
376 return Standard_False;
377}
378
379
380//=======================================================================
381//function : ComputeVV
382//purpose :
383//=======================================================================
384 Standard_Integer IntTools_Tools::ComputeVV(const TopoDS_Vertex& aV1,
385 const TopoDS_Vertex& aV2)
386{
387 Standard_Real aTolV1, aTolV2, aTolSum, d;
388 gp_Pnt aP1, aP2;
389
390 aTolV1=BRep_Tool::Tolerance(aV1);
391 aTolV2=BRep_Tool::Tolerance(aV2);
392 aTolSum=aTolV1+aTolV2;
393
394 aP1=BRep_Tool::Pnt(aV1);
395 aP2=BRep_Tool::Pnt(aV2);
396
397 d=aP1.Distance(aP2);
398 if (d<aTolSum) {
399 return 0;
400 }
401 return -1;
402}
403
404//=======================================================================
405//function : MakeFaceFromWireAndFace
406//purpose :
407//=======================================================================
408 void IntTools_Tools::MakeFaceFromWireAndFace(const TopoDS_Wire& aW,
409 const TopoDS_Face& aF,
410 TopoDS_Face& aFNew)
411{
412 TopoDS_Face aFF;
413 aFF=aF;
414 aFF.Orientation(TopAbs_FORWARD);
415 aFNew=TopoDS::Face (aFF.EmptyCopied());
416 BRep_Builder BB;
417 BB.Add(aFNew, aW);
418}
419
420//=======================================================================
421//function : ClassifyPointByFace
422//purpose :
423//=======================================================================
424 TopAbs_State IntTools_Tools::ClassifyPointByFace(const TopoDS_Face& aF,
425 const gp_Pnt2d& aP2d)
426{
427 Standard_Real aFaceTolerance;
428 TopAbs_State aState;
429
430 aFaceTolerance=BRep_Tool::Tolerance(aF);
431 IntTools_FClass2d aClass2d(aF, aFaceTolerance);
432 aState=aClass2d.Perform(aP2d);
433
434 return aState;
435}
436
437//=======================================================================
438//function : IsMiddlePointsEqual
439//purpose :
440//=======================================================================
441 Standard_Boolean IntTools_Tools::IsMiddlePointsEqual(const TopoDS_Edge& aE1,
442 const TopoDS_Edge& aE2)
443
444{
445 Standard_Real f1, l1, m1, f2, l2, m2, aTol1, aTol2, aSumTol;
446 gp_Pnt aP1, aP2;
447
448 aTol1=BRep_Tool::Tolerance(aE1);
449 Handle(Geom_Curve) C1=BRep_Tool::Curve(aE1, f1, l1);
450 m1=0.5*(f1+l1);
451 C1->D0(m1, aP1);
452
453 aTol2=BRep_Tool::Tolerance(aE2);
454 Handle(Geom_Curve) C2=BRep_Tool::Curve(aE2, f2, l2);
455 m2=0.5*(f2+l2);
456 C2->D0(m2, aP2);
457
458 aSumTol=aTol1+aTol2;
459
460 if (aP1.Distance(aP2) < aSumTol) {
461 return Standard_True;
462 }
463 return Standard_False;
464}
465
466//=======================================================================
467//function : CurveTolerance
468//purpose :
469//=======================================================================
470 Standard_Real IntTools_Tools::CurveTolerance(const Handle(Geom_Curve)& aC3D,
471 const Standard_Real aTolBase)
472{
473 Standard_Real aTolReached, aTf, aTl, aTolMin, aTolMax;
474
475 aTolReached=aTolBase;
476 //
477 if (aC3D.IsNull()) {
478 return aTolReached;
479 }
480 //
481 Handle(Geom_TrimmedCurve) aCT3D=Handle(Geom_TrimmedCurve)::DownCast(aC3D);
482 if (aCT3D.IsNull()) {
483 return aTolReached;
484 }
485 //
486 aTolMin=aTolBase;
487 aTolMax=aTolBase;
488 //
489 aTf=aCT3D->FirstParameter();
490 aTl=aCT3D->LastParameter();
491 //
492 GeomAdaptor_Curve aGAC(aCT3D);
493 GeomAbs_CurveType aCType=aGAC.GetType();
494 //
495 if (aCType==GeomAbs_Parabola) {
496 Handle(Geom_Curve) aC3DBase=aCT3D->BasisCurve();
497 ParabolaTolerance(aC3DBase, aTf, aTl, aTolBase, aTolMin, aTolMax);
498 aTolReached=aTolMax;
499 }
500 //
501 return aTolReached;
502}
503
504#include <Geom_Parabola.hxx>
505#include <gp_Parab.hxx>
506//=======================================================================
507//function : ParabolaTolerance
508//purpose :
509//=======================================================================
510void ParabolaTolerance(const Handle(Geom_Curve)& aC3D,
511 const Standard_Real aTf,
512 const Standard_Real aTl,
513 const Standard_Real aTol,
514 Standard_Real& aTolMin,
515 Standard_Real& aTolMax)
516{
517
518 aTolMin=aTol;
519 aTolMax=aTol;
520
521 Handle(Geom_Parabola) aGP=Handle(Geom_Parabola)::DownCast(aC3D);
522 if (aGP.IsNull()){
523 return;
524 }
525
526 Standard_Integer aNbPoints;
527 Standard_Real aFocal, aX1, aX2, aTol1, aTol2;
528 gp_Pnt aPf, aPl;
529 gp_Parab aParab=aGP->Parab();
530 gp_Ax1 aXAxis=aParab.XAxis();
531 Handle(Geom_Line) aGAxis=new Geom_Line(aXAxis);
532
533 aFocal=aGP->Focal();
534 if (aFocal==0.) {
535 return;
536 }
537 //
538 // aTol1
539 aTol1=aTol;
540 aX1=0.;
541 aGP->D0(aTf, aPf);
542 GeomAPI_ProjectPointOnCurve aProj1(aPf, aGAxis);
543 aNbPoints=aProj1.NbPoints();
544 if (aNbPoints) {
545 aX1=aProj1.LowerDistanceParameter();
546 }
547 if (aX1>=0.) {
548 aTol1=aTol*sqrt(0.5*aX1/aFocal);
549 }
550 if (aTol1==0.) {
551 aTol1=aTol;
552 }
553 //
554 // aTol2
555 aTol2=aTol;
556 aX2=0.;
557 aGP->D0(aTl, aPl);
558 GeomAPI_ProjectPointOnCurve aProj2(aPl, aGAxis);
559 aNbPoints=aProj2.NbPoints();
560 if (aNbPoints) {
561 aX2=aProj2.LowerDistanceParameter();
562 }
563
564 if (aX2>=0.) {
565 aTol2=aTol*sqrt(0.5*aX2/aFocal);
566 }
567 if (aTol2==0.) {
568 aTol2=aTol;
569 }
570 //
571 aTolMax=(aTol1>aTol2) ? aTol1 : aTol2;
572 aTolMin=(aTol1<aTol2) ? aTol1 : aTol2;
573}
574