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