1 // Created on: 1992-12-21
2 // Created by: Didier PIFFAULT
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
24 #include <TColStd_ListOfInteger.hxx>
25 #include <TColStd_ListIteratorOfListOfInteger.hxx>
26 #include <Bnd_Box.hxx>
27 #include <Intf_Tool.hxx>
28 #include <Bnd_BoundSortBox.hxx>
29 #include <Intf_Array1OfLin.hxx>
30 #include <Intf_SectionPoint.hxx>
31 #include <Intf_SeqOfSectionPoint.hxx>
32 #include <Intf_TangentZone.hxx>
33 #include <Intf_SeqOfTangentZone.hxx>
36 #include <Extrema_ExtElC.hxx>
37 #include <Extrema_POnCurv.hxx>
39 static const int Pourcent3[4] = {0, 1, 2, 0};
41 static Standard_Boolean IsInSegment(const gp_Vec& P1P2,
43 const Standard_Real NP1P2,
45 const Standard_Real Tolerance) {
46 Param = P1P2.Dot(P1P);
48 if(Param > (NP1P2+Tolerance))
49 return(Standard_False);
50 if(Param < (-Tolerance))
51 return(Standard_False);
53 if(Param<0.0) Param=0.0;
54 if(Param>1.0) Param=1.0;
55 return(Standard_True);
59 //=======================================================================
60 //function : Intf_InterferencePolygonPolyhedron
61 //purpose : Empty constructor
62 //=======================================================================
64 Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron()
65 : Intf_Interference (Standard_False),
66 BeginOfClosedPolygon (Standard_False),
70 //=======================================================================
71 //function : Intf_InterferencePolygonPolyhedron
72 //purpose : Construct and compute an interference beetween a Polygon3d
74 //=======================================================================
76 Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron
77 (const Polygon3d& thePolyg, const Polyhedron& thePolyh)
78 : Intf_Interference (Standard_False),
79 BeginOfClosedPolygon (Standard_False),
82 Tolerance=ToolPolygon3d::DeflectionOverEstimation(thePolyg)+
83 ToolPolyh::DeflectionOverEstimation(thePolyh);
85 Tolerance=Epsilon(1000.);
87 if (!ToolPolygon3d::Bounding(thePolyg).IsOut(ToolPolyh::Bounding(thePolyh))) {
88 Interference(thePolyg, thePolyh);
93 Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron
94 (const Polygon3d& thePolyg, const Polyhedron& thePolyh,
95 Bnd_BoundSortBox &PolyhGrid)
96 : Intf_Interference (Standard_False),
97 BeginOfClosedPolygon (Standard_False),
100 Tolerance=ToolPolygon3d::DeflectionOverEstimation(thePolyg)+
101 ToolPolyh::DeflectionOverEstimation(thePolyh);
103 Tolerance=Epsilon(1000.);
105 if (!ToolPolygon3d::Bounding(thePolyg).IsOut(ToolPolyh::Bounding(thePolyh))) {
106 Interference(thePolyg, thePolyh,PolyhGrid);
110 //=======================================================================
111 //function : Intf_InterferencePolygonPolyhedron
112 //purpose : Construct and compute an interference beetween a Straight
113 // Line and a Polyhedron.
114 //=======================================================================
116 Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron
117 (const gp_Lin& theLin, const Polyhedron& thePolyh)
118 : Intf_Interference (Standard_False),
119 BeginOfClosedPolygon (Standard_False),
122 Tolerance=ToolPolyh::DeflectionOverEstimation(thePolyh);
124 Tolerance=Epsilon(1000.);
126 BeginOfClosedPolygon=Standard_False;
128 Bnd_BoundSortBox PolyhGrid;
129 PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh),
130 ToolPolyh::ComponentsBounding(thePolyh));
131 Standard_Integer indTri;
137 btoo.LinBox(theLin, ToolPolyh::Bounding(thePolyh), bofLin);
139 TColStd_ListIteratorOfListOfInteger iCl(PolyhGrid.Compare(bofLin));
144 theLin.Location().Translated(gp_Vec(theLin.Direction())),
145 Standard_True, indTri, thePolyh);
151 //=======================================================================
152 //function : Intf_InterferencePolygonPolyhedron
153 //purpose : Construct and compute an interference beetween the Straights
154 // Lines in <Obje> and the Polyhedron <thePolyh>.
155 //=======================================================================
157 Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron
158 (const Intf_Array1OfLin& theLins, const Polyhedron& thePolyh)
159 : Intf_Interference (Standard_False),
160 BeginOfClosedPolygon (Standard_False),
163 Tolerance=ToolPolyh::DeflectionOverEstimation(thePolyh);
165 Tolerance=Epsilon(1000.);
169 BeginOfClosedPolygon=Standard_False;
171 Bnd_BoundSortBox PolyhGrid;
172 PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh),
173 ToolPolyh::ComponentsBounding(thePolyh));
175 Standard_Integer indTri;
177 for (iLin=1; iLin<=theLins.Length(); iLin++) {
180 bToo.LinBox(theLins(iLin), ToolPolyh::Bounding(thePolyh), bofLin);
182 TColStd_ListIteratorOfListOfInteger ilC(PolyhGrid.Compare(bofLin));
187 (theLins(iLin).Location(),
188 theLins(iLin).Location().Translated(gp_Vec(theLins(iLin).Direction())),
189 Standard_True, indTri, thePolyh);
196 //=======================================================================
199 //=======================================================================
201 void Intf_InterferencePolygonPolyhedron::Perform
202 (const Polygon3d& thePolyg, const Polyhedron& thePolyh)
204 SelfInterference(Standard_False);
205 Tolerance=ToolPolygon3d::DeflectionOverEstimation(thePolyg)+
206 ToolPolyh::DeflectionOverEstimation(thePolyh);
208 Tolerance=Epsilon(1000.);
210 if (!ToolPolygon3d::Bounding(thePolyg).IsOut
211 (ToolPolyh::Bounding(thePolyh))) {
212 Interference(thePolyg, thePolyh);
217 //=======================================================================
220 //=======================================================================
222 void Intf_InterferencePolygonPolyhedron::Perform
223 (const gp_Lin& theLin, const Polyhedron& thePolyh)
225 SelfInterference(Standard_False);
226 Tolerance=ToolPolyh::DeflectionOverEstimation(thePolyh);
228 Tolerance=Epsilon(1000.);
230 BeginOfClosedPolygon=Standard_False;
232 Bnd_BoundSortBox PolyhGrid;
233 PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh),
234 ToolPolyh::ComponentsBounding(thePolyh));
236 Standard_Integer indTri;
242 btoo.LinBox(theLin, ToolPolyh::Bounding(thePolyh), bofLin);
244 TColStd_ListIteratorOfListOfInteger lCi(PolyhGrid.Compare(bofLin));
249 theLin.Location().Translated(gp_Vec(theLin.Direction())),
250 Standard_True, indTri, thePolyh);
256 //=======================================================================
258 //purpose : Compute an interference beetween the Straights
259 // Lines in <Obje> and the Polyhedron <thePolyh>.
260 //=======================================================================
262 void Intf_InterferencePolygonPolyhedron::Perform
263 (const Intf_Array1OfLin& theLins, const Polyhedron& thePolyh)
265 SelfInterference(Standard_False);
266 Tolerance=ToolPolyh::DeflectionOverEstimation(thePolyh);
268 Tolerance=Epsilon(1000.);
272 BeginOfClosedPolygon=Standard_False;
274 Bnd_BoundSortBox PolyhGrid;
275 PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh),
276 ToolPolyh::ComponentsBounding(thePolyh));
278 Standard_Integer indTri;
280 for (iLin=1; iLin<=theLins.Length(); iLin++) {
282 Btoo.LinBox(theLins(iLin), ToolPolyh::Bounding(thePolyh), bofLin);
284 TColStd_ListIteratorOfListOfInteger tlC(PolyhGrid.Compare(bofLin));
289 (theLins(iLin).Location(),
290 theLins(iLin).Location().Translated(gp_Vec(theLins(iLin).Direction())),
291 Standard_True, indTri, thePolyh);
298 //=======================================================================
299 //function : Interference
300 //purpose : Compare the boundings beetween the segment of <Obje>
301 // and the facets of <thePolyh>.
302 //=======================================================================
304 void Intf_InterferencePolygonPolyhedron::Interference
305 (const Polygon3d& thePolyg, const Polyhedron& thePolyh)
310 Bnd_BoundSortBox PolyhGrid;
311 PolyhGrid.Initialize(ToolPolyh::Bounding(thePolyh),
312 ToolPolyh::ComponentsBounding(thePolyh));
314 Standard_Integer indTri;
315 BeginOfClosedPolygon=ToolPolygon3d::Closed(thePolyg);
317 Standard_Real defPh = ToolPolyh::DeflectionOverEstimation(thePolyh);
319 for (iLin=1; iLin<=ToolPolygon3d::NbSegments(thePolyg); iLin++) {
322 bofSeg.Add(ToolPolygon3d::BeginOfSeg(thePolyg, iLin));
323 bofSeg.Add(ToolPolygon3d::EndOfSeg(thePolyg, iLin));
324 bofSeg.Enlarge(ToolPolygon3d::DeflectionOverEstimation(thePolyg));
326 TColStd_ListOfInteger maliste;
327 maliste = PolyhGrid.Compare(bofSeg);
328 TColStd_ListIteratorOfListOfInteger clt(maliste);
329 for (; clt.More(); clt.Next()) {
331 gp_Pnt p1 = ToolPolygon3d::BeginOfSeg(thePolyg, iLin);
332 gp_Pnt p2 = ToolPolygon3d::EndOfSeg(thePolyg, iLin);
333 Standard_Integer pTri0, pTri1, pTri2;
334 ToolPolyh::Triangle(thePolyh, indTri, pTri0, pTri1, pTri2);
335 gp_Pnt Pa=ToolPolyh::Point(thePolyh, pTri0);
336 gp_Pnt Pb=ToolPolyh::Point(thePolyh, pTri1);
337 gp_Pnt Pc=ToolPolyh::Point(thePolyh, pTri2);
340 gp_Vec Normale = PaPb.Crossed(PaPc);
341 Standard_Real Norm_Normale=Normale.Magnitude();
342 if(Norm_Normale<1e-14)
344 Normale.Multiply(defPh/Norm_Normale);
345 gp_Pnt p1m = p1.Translated(-Normale);
346 gp_Pnt p1p = p1.Translated( Normale);
347 gp_Pnt p2m = p2.Translated(-Normale);
348 gp_Pnt p2p = p2.Translated( Normale);
351 Standard_False, indTri, thePolyh);
354 Standard_False, indTri, thePolyh);
355 // Intersect(ToolPolygon3d::BeginOfSeg(thePolyg, iLin),
356 // ToolPolygon3d::EndOfSeg(thePolyg, iLin),
357 // Standard_False, indTri, thePolyh);
359 BeginOfClosedPolygon=Standard_False;
382 //=======================================================================
383 //function : Intf_InterferencePolygonPolyhedron
384 //purpose : Construct and compute an interference beetween a Straight
385 // Line and a Polyhedron.
386 //=======================================================================
388 Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron
389 (const gp_Lin& theLin, const Polyhedron& thePolyh,
390 Bnd_BoundSortBox &PolyhGrid)
391 : Intf_Interference(Standard_False)
393 Tolerance=ToolPolyh::DeflectionOverEstimation(thePolyh);
395 Tolerance=Epsilon(1000.);
397 BeginOfClosedPolygon=Standard_False;
399 Standard_Integer indTri;
405 btoo.LinBox(theLin, ToolPolyh::Bounding(thePolyh), bofLin);
407 TColStd_ListIteratorOfListOfInteger iCl(PolyhGrid.Compare(bofLin));
412 theLin.Location().Translated(gp_Vec(theLin.Direction())),
413 Standard_True, indTri, thePolyh);
419 //=======================================================================
420 //function : Intf_InterferencePolygonPolyhedron
421 //purpose : Construct and compute an interference beetween the Straights
422 // Lines in <Obje> and the Polyhedron <thePolyh>.
423 //=======================================================================
425 Intf_InterferencePolygonPolyhedron::Intf_InterferencePolygonPolyhedron
426 (const Intf_Array1OfLin& theLins, const Polyhedron& thePolyh,
427 Bnd_BoundSortBox &PolyhGrid)
428 : Intf_Interference(Standard_False)
430 Tolerance=ToolPolyh::DeflectionOverEstimation(thePolyh);
432 Tolerance=Epsilon(1000.);
436 BeginOfClosedPolygon=Standard_False;
438 Standard_Integer indTri;
440 for (iLin=1; iLin<=theLins.Length(); iLin++) {
443 bToo.LinBox(theLins(iLin), ToolPolyh::Bounding(thePolyh), bofLin);
445 TColStd_ListIteratorOfListOfInteger ilC(PolyhGrid.Compare(bofLin));
450 (theLins(iLin).Location(),
451 theLins(iLin).Location().Translated(gp_Vec(theLins(iLin).Direction())),
452 Standard_True, indTri, thePolyh);
459 //=======================================================================
462 //=======================================================================
464 void Intf_InterferencePolygonPolyhedron::Perform
465 (const Polygon3d& thePolyg, const Polyhedron& thePolyh,
466 Bnd_BoundSortBox &PolyhGrid)
468 SelfInterference(Standard_False);
469 Tolerance=ToolPolygon3d::DeflectionOverEstimation(thePolyg)+
470 ToolPolyh::DeflectionOverEstimation(thePolyh);
472 Tolerance=Epsilon(1000.);
474 if (!ToolPolygon3d::Bounding(thePolyg).IsOut
475 (ToolPolyh::Bounding(thePolyh))) {
476 Interference(thePolyg, thePolyh,PolyhGrid);
481 //=======================================================================
484 //=======================================================================
486 void Intf_InterferencePolygonPolyhedron::Perform
487 (const gp_Lin& theLin, const Polyhedron& thePolyh,
488 Bnd_BoundSortBox &PolyhGrid)
490 SelfInterference(Standard_False);
491 Tolerance=ToolPolyh::DeflectionOverEstimation(thePolyh);
493 Tolerance=Epsilon(1000.);
495 BeginOfClosedPolygon=Standard_False;
497 Standard_Integer indTri;
503 btoo.LinBox(theLin, ToolPolyh::Bounding(thePolyh), bofLin);
505 TColStd_ListIteratorOfListOfInteger lCi(PolyhGrid.Compare(bofLin));
510 theLin.Location().Translated(gp_Vec(theLin.Direction())),
511 Standard_True, indTri, thePolyh);
517 //=======================================================================
519 //purpose : Compute an interference beetween the Straights
520 // Lines in <Obje> and the Polyhedron <thePolyh>.
521 //=======================================================================
523 void Intf_InterferencePolygonPolyhedron::Perform
524 (const Intf_Array1OfLin& theLins, const Polyhedron& thePolyh,
525 Bnd_BoundSortBox &PolyhGrid)
527 SelfInterference(Standard_False);
528 Tolerance=ToolPolyh::DeflectionOverEstimation(thePolyh);
530 Tolerance=Epsilon(1000.);
534 BeginOfClosedPolygon=Standard_False;
536 Standard_Integer indTri;
538 for (iLin=1; iLin<=theLins.Length(); iLin++) {
540 Btoo.LinBox(theLins(iLin), ToolPolyh::Bounding(thePolyh), bofLin);
542 TColStd_ListIteratorOfListOfInteger tlC(PolyhGrid.Compare(bofLin));
547 (theLins(iLin).Location(),
548 theLins(iLin).Location().Translated(gp_Vec(theLins(iLin).Direction())),
549 Standard_True, indTri, thePolyh);
557 //=======================================================================
558 //function : Interference
559 //purpose : Compare the boundings beetween the segment of <Obje>
560 // and the facets of <thePolyh>.
561 //=======================================================================
563 void Intf_InterferencePolygonPolyhedron::Interference
564 (const Polygon3d& thePolyg, const Polyhedron& thePolyh,
565 Bnd_BoundSortBox &PolyhGrid)
569 Standard_Integer indTri;
570 BeginOfClosedPolygon=ToolPolygon3d::Closed(thePolyg);
572 for (iLin=1; iLin<=ToolPolygon3d::NbSegments(thePolyg); iLin++) {
575 bofSeg.Add(ToolPolygon3d::BeginOfSeg(thePolyg, iLin));
576 bofSeg.Add(ToolPolygon3d::EndOfSeg(thePolyg, iLin));
577 bofSeg.Enlarge(ToolPolygon3d::DeflectionOverEstimation(thePolyg));
579 // Modified by MKK - Thu Oct 25 12:40:11 2007
580 Standard_Real defPh = ToolPolyh::DeflectionOverEstimation(thePolyh);
581 TColStd_ListOfInteger maliste;
582 maliste = PolyhGrid.Compare(bofSeg);
583 TColStd_ListIteratorOfListOfInteger clt(maliste);
584 // Modified by MKK - Thu Oct 25 12:40:11 2007 Begin
587 if ( !maliste.IsEmpty() ) {
588 p1 = ToolPolygon3d::BeginOfSeg(thePolyg, iLin);
589 p2 = ToolPolygon3d::EndOfSeg(thePolyg, iLin);
593 // Modified by MKK - Thu Oct 25 12:40:11 2007 End
596 // Modified by MKK - Thu Oct 25 12:40:11 2007 Begin
598 Standard_Integer pTri[3];
599 ToolPolyh::Triangle(thePolyh, indTri, pTri[0], pTri[1], pTri[2]);
600 gp_XYZ triNor; // Vecteur normal.
601 Standard_Real triDp = 0.; // Distance polaire.
603 Intf::PlaneEquation(ToolPolyh::Point(thePolyh, pTri[0]),
604 ToolPolyh::Point(thePolyh, pTri[1]),
605 ToolPolyh::Point(thePolyh, pTri[2]),
608 // enlarge boundary segment
610 gp_XYZ dif = p1.XYZ() - p2.XYZ();
611 Standard_Real dist = dif.Modulus();
612 if ( dist > gp::Resolution() ) {
614 Standard_Real aCos = dif * triNor;
616 if ( aCos > gp::Resolution() ) {
617 Standard_Real shift = defPh / aCos;
618 Beg0.SetXYZ( p1.XYZ() + dif * shift );
622 else if ( iLin == ToolPolygon3d::NbSegments(thePolyg) ) {
623 gp_XYZ dif = p2.XYZ() - p1.XYZ();
624 Standard_Real dist = dif.Modulus();
625 if ( dist > gp::Resolution() ) {
627 Standard_Real aCos = dif * triNor;
629 if ( aCos > gp::Resolution() ) {
630 Standard_Real shift = defPh / aCos;
631 End0.SetXYZ( p2.XYZ() + dif * shift );
635 Standard_Real dBegTri=(triNor*Beg0.XYZ())-triDp; // Distance <p1> plane
636 Standard_Real dEndTri=(triNor*End0.XYZ())-triDp; // Distance <p2> plane
638 Intersect(Beg0, End0, Standard_False, indTri, thePolyh, triNor, triDp, dBegTri, dEndTri);
640 // Modified by MKK - Thu Oct 25 12:40:11 2007 End
643 BeginOfClosedPolygon=Standard_False;
648 //=======================================================================
649 //function : Intersect
650 //purpose : Compute the intersection beetween the segment or the line
651 // and the triangle <TTri>.
652 //=======================================================================
654 void Intf_InterferencePolygonPolyhedron::Intersect
655 (const gp_Pnt& BegO, const gp_Pnt& EndO, const Standard_Boolean Infinite,
656 const Standard_Integer TTri, const Polyhedron& thePolyh)
658 Standard_Integer pTri0,pTri1,pTri2;
659 ToolPolyh::Triangle(thePolyh, TTri, pTri0, pTri1, pTri2);
660 gp_Pnt Pa=ToolPolyh::Point(thePolyh, pTri0);
661 gp_Pnt Pb=ToolPolyh::Point(thePolyh, pTri1);
662 gp_Pnt Pc=ToolPolyh::Point(thePolyh, pTri2);
665 gp_Vec Normale = PaPb.Crossed(PaPc);
666 Standard_Real Norm_Normale=Normale.Magnitude();
667 if(Norm_Normale<1e-14)
670 //-- Equation du Plan
671 Standard_Real A=Normale.X()/Norm_Normale;
672 Standard_Real B=Normale.Y()/Norm_Normale;
673 Standard_Real C=Normale.Z()/Norm_Normale;
674 Standard_Real D=-(A*Pa.X()+B*Pa.Y()+C*Pa.Z());
676 gp_Vec BegOEndO(BegO,EndO);
677 Standard_Real Norm_BegOEndO=BegOEndO.Magnitude();
678 if(Norm_BegOEndO<1e-14)
680 Standard_Real Lx=BegOEndO.X()/Norm_BegOEndO;
681 Standard_Real Ly=BegOEndO.Y()/Norm_BegOEndO;
682 Standard_Real Lz=BegOEndO.Z()/Norm_BegOEndO;
684 Standard_Real Vd=A*Lx+B*Ly+C*Lz; //-- DirLigne . NormalePlan
686 if(Vd==0) { //-- Droite parallele au plan
691 //-- Calcul du parametre sur la ligne
692 Standard_Real t=-(A*BegO.X()+B*BegO.Y()+C*BegO.Z()+D) / Vd;
694 Standard_Real tol=1e-8; //-- Deflection sur le triangle
695 if(t<-tol || t>(Norm_BegOEndO+tol)) {
696 if(Infinite==Standard_False) {
700 //-- On a une intersection droite plan
701 //-- On teste si c est dans le triangle
702 gp_Pnt PRes(BegO.X()+t*Lx,BegO.Y()+t*Ly,BegO.Z()+t*Lz);
704 Standard_Real AbsA=A; if(AbsA<0) AbsA=-AbsA;
705 Standard_Real AbsB=B; if(AbsB<0) AbsB=-AbsB;
706 Standard_Real AbsC=C; if(AbsC<0) AbsC=-AbsC;
708 Standard_Real Au,Av,Bu,Bv,Cu,Cv,Pu,Pv;
711 //-- Projeter selon X
712 Au=Pa.Y(); Bu=Pb.Y(); Cu=Pc.Y(); Pu=PRes.Y();
713 Av=Pa.Z(); Bv=Pb.Z(); Cv=Pc.Z(); Pv=PRes.Z();
716 //-- Projeter selon Z
717 Au=Pa.Y(); Bu=Pb.Y(); Cu=Pc.Y(); Pu=PRes.Y();
718 Av=Pa.X(); Bv=Pb.X(); Cv=Pc.X(); Pv=PRes.X();
723 //-- projeter selon Y
724 Au=Pa.Z(); Bu=Pb.Z(); Cu=Pc.Z(); Pu=PRes.Z();
725 Av=Pa.X(); Bv=Pb.X(); Cv=Pc.X(); Pv=PRes.X();
728 //-- projeter selon Z
729 Au=Pa.Y(); Bu=Pb.Y(); Cu=Pc.Y(); Pu=PRes.Y();
730 Av=Pa.X(); Bv=Pb.X(); Cv=Pc.X(); Pv=PRes.X();
734 Standard_Real ABu=Bu-Au; Standard_Real ABv=Bv-Av;
735 Standard_Real ACu=Cu-Au; Standard_Real ACv=Cv-Av;
736 Standard_Real BCu=Cu-Bu; Standard_Real BCv=Cv-Bv;
739 //-- Test sur AB et C
742 if(t1<0) { if(t2>0) return; } else { if(t2<0) return; }
744 //-- Test sur AC et B
747 if(t1<0) { if(t2>0) return; } else { if(t2<0) return; }
749 //-- Test sur BC et A
752 if(t1<0) { if(t2>0) return; } else { if(t2<0) return; }
755 Intf_SectionPoint SP(PRes,
758 iLin, //-- !!!!! VARIABLE STATIQUE
765 void Intf_InterferencePolygonPolyhedron::Intersect
766 (const gp_Pnt& BegO, const gp_Pnt& EndO, const Standard_Boolean Infinite,
767 const Standard_Integer TTri, const Polyhedron& thePolyh)
769 Intf_PIType typOnG=Intf_EDGE;
771 Standard_Integer pTri[3];
772 ToolPolyh::Triangle(thePolyh, TTri, pTri[0], pTri[1], pTri[2]);
773 gp_XYZ triNor; // Vecteur normal.
774 Standard_Real triDp; // Distance polaire.
776 Intf::PlaneEquation(ToolPolyh::Point(thePolyh, pTri[0]),
777 ToolPolyh::Point(thePolyh, pTri[1]),
778 ToolPolyh::Point(thePolyh, pTri[2]),
782 Standard_Real dBegTri=(triNor*BegO.XYZ())-triDp; // Distance <BegO> plan
783 Standard_Real dEndTri=(triNor*EndO.XYZ())-triDp; // Distance <EndO> plan
784 gp_XYZ segO=EndO.XYZ()-BegO.XYZ();
786 Standard_Boolean NoIntersectionWithTriangle = Standard_False;
787 Standard_Boolean PolygonCutsPlane = Standard_True;
791 if (t >= 1.e-16 || t<=-1.e-16)
793 else param = dBegTri;
794 Standard_Real floatgap=Epsilon(1000.);
797 if (dBegTri<=floatgap && dBegTri>=-floatgap ) {
798 param=0.;typOnG=Intf_VERTEX;
799 if (BeginOfClosedPolygon)
800 NoIntersectionWithTriangle = Standard_False;
802 else if (dEndTri<=floatgap && dEndTri>=-floatgap) {
803 param=1.;typOnG=Intf_VERTEX;
804 NoIntersectionWithTriangle = Standard_False;
806 if (param<0. || param>1.) {
807 PolygonCutsPlane = Standard_False;
808 NoIntersectionWithTriangle = Standard_True;
811 if(NoIntersectionWithTriangle == Standard_False) {
812 gp_XYZ spLieu=BegO.XYZ()+((EndO.XYZ()-BegO.XYZ())*param);
813 Standard_Real dPiE[3], dPtPi[3], sigd;
814 Standard_Integer is = 0;
815 Standard_Integer sEdge=-1;
816 Standard_Integer sVertex=-1;
817 Standard_Integer tbreak=0;
819 gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[1]).XYZ()-
820 ToolPolyh::Point(thePolyh, pTri[0]).XYZ());
821 gp_XYZ vecP(spLieu-ToolPolyh::Point(thePolyh, pTri[0]).XYZ());
822 dPtPi[0]=vecP.Modulus();
823 if (dPtPi[0]<=floatgap) {
829 gp_XYZ segT_x_vecP(segT^vecP);
830 Standard_Real Modulus_segT_x_vecP = segT_x_vecP.Modulus();
831 sigd = segT_x_vecP*triNor;
834 else if(sigd<-floatgap)
839 dPiE[0]=sigd*(Modulus_segT_x_vecP/segT.Modulus());
840 if (dPiE[0]<=floatgap && dPiE[0]>=-floatgap) {
848 if(tbreak==0) { //-- is = 1
849 gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[2]).XYZ()-
850 ToolPolyh::Point(thePolyh, pTri[1]).XYZ());
851 gp_XYZ vecP(spLieu-ToolPolyh::Point(thePolyh, pTri[1]).XYZ());
852 dPtPi[1]=vecP.Modulus();
853 if (dPtPi[1]<=floatgap) {
859 gp_XYZ segT_x_vecP(segT^vecP);
860 Standard_Real Modulus_segT_x_vecP = segT_x_vecP.Modulus();
861 sigd = segT_x_vecP*triNor;
864 else if(sigd<-floatgap)
869 dPiE[1]=sigd*(Modulus_segT_x_vecP/segT.Modulus());
870 if (dPiE[1]<=floatgap && dPiE[1]>=-floatgap) {
877 if(tbreak==0) { //-- is = 2
878 gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[0]).XYZ()-
879 ToolPolyh::Point(thePolyh, pTri[2]).XYZ());
880 gp_XYZ vecP(spLieu-ToolPolyh::Point(thePolyh, pTri[2]).XYZ());
881 dPtPi[2]=vecP.Modulus();
882 if (dPtPi[2]<=floatgap) {
886 gp_XYZ segT_x_vecP(segT^vecP);
887 Standard_Real Modulus_segT_x_vecP = segT_x_vecP.Modulus();
888 sigd = segT_x_vecP*triNor;
891 else if(sigd<-floatgap)
896 dPiE[2]=sigd*(Modulus_segT_x_vecP/segT.Modulus());
897 if (dPiE[2]<=floatgap && dPiE[2]>=-floatgap) {
902 //-- fin for i=0 to 2
905 Standard_Integer triCon, pedg;
908 pedg=pTri[Pourcent3[sVertex+1]];
909 //-- while (triCon!=0) {
910 //-- ToolPolyh::TriConnex(thePolyh, triCon,pTri[sVertex],pedg,triCon,pedg);
911 //-- //-- if (triCon<TTri) return;
912 //-- if (triCon==TTri) break;
914 Intf_SectionPoint SP(spLieu,
915 typOnG, 0, iLin, param,
916 Intf_VERTEX, pTri[is], 0, 0.,
921 ToolPolyh::TriConnex(thePolyh, TTri, pTri[sEdge], pTri[Pourcent3[sEdge+1]],
923 //-- if (triCon<=TTri) return; ???????????????????? LBR
924 // !!cout<<" sEdge "<<endl;
925 Intf_SectionPoint SP(spLieu,
926 typOnG, 0, iLin, param,
927 Intf_EDGE, Min(pTri[sEdge], pTri[Pourcent3[sEdge+1]]),
928 Max(pTri[sEdge], pTri[Pourcent3[sEdge+1]]), 0.,
932 else if (dPiE[0]>0. && dPiE[1]>0. && dPiE[2]>0.) {
933 // !!cout<<" 3 Positifs "<<endl;
934 Intf_SectionPoint SP(spLieu,
935 typOnG, 0, iLin, param,
936 Intf_FACE, TTri, 0, 0.,
940 // Modified by Sergey KHROMOV - Fri Dec 7 14:40:11 2001 Begin
941 // Sometimes triangulation doesn't cover whole the face. In this
942 // case it is necessary to take into account the deflection between boundary
943 // isolines of the surface and boundary trianles. Computed value of this
944 // deflection is contained in thePolyh.
948 for (i = 1; i <= 3; i++) {
949 Standard_Integer indP1 = (i == 3) ? pTri[0] : pTri[i];
950 Standard_Integer indP2 = pTri[i - 1];
952 if (ToolPolyh::IsOnBound(thePolyh, indP1, indP2)) {
953 // For boundary line it is necessary to check the border deflection.
954 Standard_Real Deflection = ToolPolyh::GetBorderDeflection(thePolyh);
955 const gp_Pnt &BegP = ToolPolyh::Point(thePolyh, indP1);
956 const gp_Pnt &EndP = ToolPolyh::Point(thePolyh, indP2);
957 gp_Vec VecTri(BegP,EndP);
958 gp_Dir DirTri(VecTri);
959 gp_Lin LinTri(BegP,DirTri);
960 gp_Pnt aPOnE(spLieu);
961 Standard_Real aDist = LinTri.Distance(aPOnE);
963 if (aDist <= Deflection) {
964 gp_Vec aVLocPOnE(BegP, aPOnE);
965 gp_Vec aVecDirTri(DirTri);
966 Standard_Real aPar = aVLocPOnE*aVecDirTri;
967 Standard_Real aMaxPar = VecTri.Magnitude();
969 if (aPar >= 0 && aPar <= aMaxPar) {
970 Intf_SectionPoint SP(spLieu,
971 typOnG, 0, iLin, param,
972 Intf_FACE, TTri, 0, 0.,
980 // Modified by Sergey KHROMOV - Fri Dec 7 14:40:29 2001 End
981 } //---- if(NoIntersectionWithTriangle == Standard_False)
983 //---------------------------------------------------------------------------
984 //-- On teste la distance entre les cotes du triangle et le polygone
986 //-- Si cette distance est inferieure a Tolerance, on cree un SP.
988 //-- printf("\nIntf_InterferencePolygPolyh : dBegTri=%g dEndTri=%g Tolerance=%g\n",dBegTri,dEndTri,Tolerance);
989 if(1 || (Abs(dBegTri) <= Tolerance)
990 || (Abs(dEndTri) <= Tolerance)) {
991 gp_Vec VecPol(BegO,EndO);
992 Standard_Real NVecPol = VecPol.Magnitude();
993 gp_Dir DirPol(VecPol);
994 gp_Lin LinPol(BegO,DirPol);
995 Standard_Real dist2,ParamOnO,ParamOnT;
997 for (Standard_Integer i=0; i<3; i++) {
998 Standard_Integer pTri_ip1pc3 = pTri[Pourcent3[i+1]];
999 Standard_Integer pTri_i = pTri[i];
1000 const gp_Pnt& BegT = ToolPolyh::Point(thePolyh, pTri_ip1pc3);
1001 const gp_Pnt& EndT = ToolPolyh::Point(thePolyh, pTri_i);
1002 gp_Vec VecTri(BegT,EndT);
1003 Standard_Real NVecTri = VecTri.Magnitude();
1004 gp_Dir DirTri(VecTri);
1005 gp_Lin LinTri(BegT,DirTri);
1006 Extrema_ExtElC Extrema(LinPol,LinTri,0.00000001);
1007 if(Extrema.IsDone()) {
1008 if(Extrema.IsParallel() == Standard_False) {
1009 if(Extrema.NbExt()) {
1010 dist2 = Extrema.SquareDistance();
1011 if(dist2<=Tolerance * Tolerance) {
1012 Extrema_POnCurv POnC1,POnC2;
1013 Extrema.Points(1,POnC1,POnC2);
1014 const gp_Pnt& PO = POnC1.Value();
1015 const gp_Pnt& PT = POnC2.Value();
1016 //--cout<<" ** Nouveau "<<dist2<<endl;
1017 if(IsInSegment(VecPol,gp_Vec(BegO,PO),NVecPol,ParamOnO,Tolerance)) {
1018 if(IsInSegment(VecTri,gp_Vec(BegT,PT),NVecTri,ParamOnT,Tolerance)) {
1019 //-- cout<<" * "<<endl;
1020 gp_XYZ spLieu=BegT.XYZ()+((EndT.XYZ()-BegT.XYZ())*param);
1021 Standard_Integer tmin,tmax;
1022 if(pTri_i>pTri_ip1pc3) {
1023 tmin=pTri_ip1pc3; tmax=pTri_i;
1026 tmax=pTri_ip1pc3; tmin=pTri_i;
1028 Intf_SectionPoint SP(spLieu,
1029 typOnG, 0, iLin, ParamOnO,
1034 mySPoins.Append(SP);
1047 void Intf_InterferencePolygonPolyhedron::Intersect (const gp_Pnt& BegO,
1049 const Standard_Boolean Infinite,
1050 const Standard_Integer TTri,
1051 const Polyhedron& thePolyh,
1052 const gp_XYZ& TriNormal,
1053 const Standard_Real /*TriDp*/,
1054 const Standard_Real dBegTri,
1055 const Standard_Real dEndTri)
1057 Intf_PIType typOnG=Intf_EDGE;
1059 Standard_Integer pTri[3];
1060 ToolPolyh::Triangle(thePolyh, TTri, pTri[0], pTri[1], pTri[2]);
1061 gp_XYZ triNor = TriNormal; // Vecteur normal.
1062 //Standard_Real triDp = TriDp; // Distance polaire.
1065 // Standard_Real dBegTri=(triNor*BegO.XYZ())-triDp; // Distance <BegO> plan
1066 // Standard_Real dEndTri=(triNor*EndO.XYZ())-triDp; // Distance <EndO> plan
1068 Standard_Boolean NoIntersectionWithTriangle = Standard_False;
1069 Standard_Boolean PolygonCutsPlane = Standard_True;
1071 Standard_Real param;
1072 t = dBegTri-dEndTri;
1073 if (t >= 1.e-16 || t<=-1.e-16)
1075 else param = dBegTri;
1076 Standard_Real floatgap=Epsilon(1000.);
1079 if (dBegTri<=floatgap && dBegTri>=-floatgap ) {
1080 param=0.;typOnG=Intf_VERTEX;
1081 if (BeginOfClosedPolygon)
1082 NoIntersectionWithTriangle = Standard_False;
1084 else if (dEndTri<=floatgap && dEndTri>=-floatgap) {
1085 param=1.;typOnG=Intf_VERTEX;
1086 NoIntersectionWithTriangle = Standard_False;
1088 if (param<0. || param>1.) {
1089 PolygonCutsPlane = Standard_False;
1090 NoIntersectionWithTriangle = Standard_True;
1093 if(NoIntersectionWithTriangle == Standard_False) {
1094 gp_XYZ spLieu=BegO.XYZ()+((EndO.XYZ()-BegO.XYZ())*param);
1095 Standard_Real dPiE[3], dPtPi[3], sigd;
1096 Standard_Integer is = 0;
1097 Standard_Integer sEdge=-1;
1098 Standard_Integer sVertex=-1;
1099 Standard_Integer tbreak=0;
1101 gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[1]).XYZ()-
1102 ToolPolyh::Point(thePolyh, pTri[0]).XYZ());
1103 gp_XYZ vecP(spLieu-ToolPolyh::Point(thePolyh, pTri[0]).XYZ());
1104 dPtPi[0]=vecP.Modulus();
1105 if (dPtPi[0]<=floatgap) {
1111 gp_XYZ segT_x_vecP(segT^vecP);
1112 Standard_Real Modulus_segT_x_vecP = segT_x_vecP.Modulus();
1113 sigd = segT_x_vecP*triNor;
1116 else if(sigd<-floatgap)
1121 dPiE[0]=sigd*(Modulus_segT_x_vecP/segT.Modulus());
1122 if (dPiE[0]<=floatgap && dPiE[0]>=-floatgap) {
1130 if(tbreak==0) { //-- is = 1
1131 gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[2]).XYZ()-
1132 ToolPolyh::Point(thePolyh, pTri[1]).XYZ());
1133 gp_XYZ vecP(spLieu-ToolPolyh::Point(thePolyh, pTri[1]).XYZ());
1134 dPtPi[1]=vecP.Modulus();
1135 if (dPtPi[1]<=floatgap) {
1141 gp_XYZ segT_x_vecP(segT^vecP);
1142 Standard_Real Modulus_segT_x_vecP = segT_x_vecP.Modulus();
1143 sigd = segT_x_vecP*triNor;
1146 else if(sigd<-floatgap)
1151 dPiE[1]=sigd*(Modulus_segT_x_vecP/segT.Modulus());
1152 if (dPiE[1]<=floatgap && dPiE[1]>=-floatgap) {
1159 if(tbreak==0) { //-- is = 2
1160 gp_XYZ segT(ToolPolyh::Point(thePolyh, pTri[0]).XYZ()-
1161 ToolPolyh::Point(thePolyh, pTri[2]).XYZ());
1162 gp_XYZ vecP(spLieu-ToolPolyh::Point(thePolyh, pTri[2]).XYZ());
1163 dPtPi[2]=vecP.Modulus();
1164 if (dPtPi[2]<=floatgap) {
1168 gp_XYZ segT_x_vecP(segT^vecP);
1169 Standard_Real Modulus_segT_x_vecP = segT_x_vecP.Modulus();
1170 sigd = segT_x_vecP*triNor;
1173 else if(sigd<-floatgap)
1178 dPiE[2]=sigd*(Modulus_segT_x_vecP/segT.Modulus());
1179 if (dPiE[2]<=floatgap && dPiE[2]>=-floatgap) {
1184 //-- fin for i=0 to 2
1187 Standard_Integer triCon, pedg;
1190 pedg=pTri[Pourcent3[sVertex+1]];
1191 //-- while (triCon!=0) {
1192 //-- ToolPolyh::TriConnex(thePolyh, triCon,pTri[sVertex],pedg,triCon,pedg);
1193 //-- //-- if (triCon<TTri) return;
1194 //-- if (triCon==TTri) break;
1196 Intf_SectionPoint SP(spLieu,
1197 typOnG, 0, iLin, param,
1198 Intf_VERTEX, pTri[is], 0, 0.,
1200 mySPoins.Append(SP);
1202 else if (sEdge>-1) {
1203 ToolPolyh::TriConnex(thePolyh, TTri, pTri[sEdge], pTri[Pourcent3[sEdge+1]],
1205 //-- if (triCon<=TTri) return; ???????????????????? LBR
1206 // !!cout<<" sEdge "<<endl;
1207 Intf_SectionPoint SP(spLieu,
1208 typOnG, 0, iLin, param,
1209 Intf_EDGE, Min(pTri[sEdge], pTri[Pourcent3[sEdge+1]]),
1210 Max(pTri[sEdge], pTri[Pourcent3[sEdge+1]]), 0.,
1212 mySPoins.Append(SP);
1214 else if (dPiE[0]>0. && dPiE[1]>0. && dPiE[2]>0.) {
1215 // !!cout<<" 3 Positifs "<<endl;
1216 Intf_SectionPoint SP(spLieu,
1217 typOnG, 0, iLin, param,
1218 Intf_FACE, TTri, 0, 0.,
1220 mySPoins.Append(SP);
1222 // Modified by Sergey KHROMOV - Fri Dec 7 14:40:11 2001 Begin
1223 // Sometimes triangulation doesn't cover whole the face. In this
1224 // case it is necessary to take into account the deflection between boundary
1225 // isolines of the surface and boundary trianles. Computed value of this
1226 // deflection is contained in thePolyh.
1230 for (i = 1; i <= 3; i++) {
1231 Standard_Integer indP1 = (i == 3) ? pTri[0] : pTri[i];
1232 Standard_Integer indP2 = pTri[i - 1];
1234 if (ToolPolyh::IsOnBound(thePolyh, indP1, indP2)) {
1235 // For boundary line it is necessary to check the border deflection.
1236 Standard_Real Deflection = ToolPolyh::GetBorderDeflection(thePolyh);
1237 const gp_Pnt &BegP = ToolPolyh::Point(thePolyh, indP1);
1238 const gp_Pnt &EndP = ToolPolyh::Point(thePolyh, indP2);
1239 gp_Vec VecTri(BegP,EndP);
1240 gp_Dir DirTri(VecTri);
1241 gp_Lin LinTri(BegP,DirTri);
1242 gp_Pnt aPOnE(spLieu);
1243 Standard_Real aDist = LinTri.Distance(aPOnE);
1245 if (aDist <= Deflection) {
1246 gp_Vec aVLocPOnE(BegP, aPOnE);
1247 gp_Vec aVecDirTri(DirTri);
1248 Standard_Real aPar = aVLocPOnE*aVecDirTri;
1249 Standard_Real aMaxPar = VecTri.Magnitude();
1251 if (aPar >= 0 && aPar <= aMaxPar) {
1252 Intf_SectionPoint SP(spLieu,
1253 typOnG, 0, iLin, param,
1254 Intf_FACE, TTri, 0, 0.,
1256 mySPoins.Append(SP);
1262 // Modified by Sergey KHROMOV - Fri Dec 7 14:40:29 2001 End
1263 } //---- if(NoIntersectionWithTriangle == Standard_False)
1265 //---------------------------------------------------------------------------
1266 //-- On teste la distance entre les cotes du triangle et le polygone
1268 //-- Si cette distance est inferieure a Tolerance, on cree un SP.
1270 //-- printf("\nIntf_InterferencePolygPolyh : dBegTri=%g dEndTri=%g Tolerance=%g\n",dBegTri,dEndTri,Tolerance);
1271 if(1 || (Abs(dBegTri) <= Tolerance)
1272 || (Abs(dEndTri) <= Tolerance)) {
1273 gp_Vec VecPol(BegO,EndO);
1274 Standard_Real NVecPol = VecPol.Magnitude();
1275 gp_Dir DirPol(VecPol);
1276 gp_Lin LinPol(BegO,DirPol);
1277 Standard_Real dist2,ParamOnO,ParamOnT;
1279 for (Standard_Integer i=0; i<3; i++) {
1280 Standard_Integer pTri_ip1pc3 = pTri[Pourcent3[i+1]];
1281 Standard_Integer pTri_i = pTri[i];
1282 const gp_Pnt& BegT = ToolPolyh::Point(thePolyh, pTri_ip1pc3);
1283 const gp_Pnt& EndT = ToolPolyh::Point(thePolyh, pTri_i);
1284 gp_Vec VecTri(BegT,EndT);
1285 Standard_Real NVecTri = VecTri.Magnitude();
1286 gp_Dir DirTri(VecTri);
1287 gp_Lin LinTri(BegT,DirTri);
1288 Extrema_ExtElC Extrema(LinPol,LinTri,0.00000001);
1289 if(Extrema.IsDone()) {
1290 if(Extrema.IsParallel() == Standard_False) {
1291 if(Extrema.NbExt()) {
1292 dist2 = Extrema.SquareDistance();
1293 if(dist2<=Tolerance * Tolerance) {
1294 Extrema_POnCurv POnC1,POnC2;
1295 Extrema.Points(1,POnC1,POnC2);
1296 const gp_Pnt& PO = POnC1.Value();
1297 const gp_Pnt& PT = POnC2.Value();
1298 //--cout<<" ** Nouveau "<<dist2<<endl;
1299 if(IsInSegment(VecPol,gp_Vec(BegO,PO),NVecPol,ParamOnO,Tolerance)) {
1300 if(IsInSegment(VecTri,gp_Vec(BegT,PT),NVecTri,ParamOnT,Tolerance)) {
1301 //-- cout<<" * "<<endl;
1302 gp_XYZ spLieu=BegT.XYZ()+((EndT.XYZ()-BegT.XYZ())*param);
1303 Standard_Integer tmin,tmax;
1304 if(pTri_i>pTri_ip1pc3) {
1305 tmin=pTri_ip1pc3; tmax=pTri_i;
1308 tmax=pTri_ip1pc3; tmin=pTri_i;
1310 Intf_SectionPoint SP(spLieu,
1311 typOnG, 0, iLin, ParamOnO,
1316 mySPoins.Append(SP);