1 // Created on: 1992-11-09
2 // Created by: Didier PIFFAULT
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Bnd_BoundSortBox.hxx>
19 #include <Bnd_HArray1OfBox.hxx>
24 #include <Intf_SectionLine.hxx>
25 #include <Intf_SectionPoint.hxx>
26 #include <Intf_SeqOfSectionLine.hxx>
27 #include <Intf_SeqOfSectionPoint.hxx>
28 #include <Intf_SeqOfTangentZone.hxx>
29 #include <Intf_TangentZone.hxx>
30 #include <IntPatch_InterferencePolyhedron.hxx>
31 #include <IntPatch_Polyhedron.hxx>
32 #include <IntPatch_PolyhedronTool.hxx>
33 #include <NCollection_LocalArray.hxx>
34 #include <TColStd_ListIteratorOfListOfInteger.hxx>
35 #include <TColStd_ListOfInteger.hxx>
37 static const int Pourcent3[9] = {0, 1, 2, 0, 1, 2, 0, 1, 2};
39 //=======================================================================
40 //function : IntPatch_InterferencePolyhedron
41 //purpose : Empty constructor.
42 //=======================================================================
44 IntPatch_InterferencePolyhedron::IntPatch_InterferencePolyhedron ()
45 : Intf_Interference(Standard_False),
48 memset (OI, 0, sizeof (OI));
49 memset (TI, 0, sizeof (TI));
50 memset (dpOeT, 0, sizeof (dpOeT));
51 memset (dpOpT, 0, sizeof (dpOpT));
52 memset (deOpT, 0, sizeof (deOpT));
55 //=======================================================================
56 //function : IntPatch_InterferencePolyhedron
58 //=======================================================================
60 IntPatch_InterferencePolyhedron::IntPatch_InterferencePolyhedron
61 (const IntPatch_Polyhedron& FirstPol, const IntPatch_Polyhedron& SeconPol)
62 : Intf_Interference(Standard_False),
65 memset (OI, 0, sizeof (OI));
66 memset (TI, 0, sizeof (TI));
67 memset (dpOeT, 0, sizeof (dpOeT));
68 memset (dpOpT, 0, sizeof (dpOpT));
69 memset (deOpT, 0, sizeof (deOpT));
70 if (!IntPatch_PolyhedronTool::Bounding(FirstPol).IsOut
71 (IntPatch_PolyhedronTool::Bounding(SeconPol))) {
72 Tolerance=IntPatch_PolyhedronTool::DeflectionOverEstimation(FirstPol)+
73 IntPatch_PolyhedronTool::DeflectionOverEstimation(SeconPol);
75 Tolerance=Epsilon(1000.);
76 Interference(FirstPol, SeconPol);
80 //=======================================================================
81 //function : IntPatch_InterferencePolyhedron
83 //=======================================================================
85 IntPatch_InterferencePolyhedron::IntPatch_InterferencePolyhedron
86 (const IntPatch_Polyhedron& Objet)
87 : Intf_Interference(Standard_True),
90 memset (OI, 0, sizeof (OI));
91 memset (TI, 0, sizeof (TI));
92 memset (dpOeT, 0, sizeof (dpOeT));
93 memset (dpOpT, 0, sizeof (dpOpT));
94 memset (deOpT, 0, sizeof (deOpT));
95 Tolerance=IntPatch_PolyhedronTool::DeflectionOverEstimation(Objet)*2;
97 Tolerance=Epsilon(1000.);
98 Interference(Objet,Objet); //-- lbr le 5 juillet 96
102 //=======================================================================
105 //=======================================================================
107 void IntPatch_InterferencePolyhedron::Perform
108 (const IntPatch_Polyhedron& FirstPol, const IntPatch_Polyhedron& SeconPol)
110 SelfInterference(Standard_False);
111 if (!IntPatch_PolyhedronTool::Bounding(FirstPol).IsOut
112 (IntPatch_PolyhedronTool::Bounding(SeconPol))) {
113 Tolerance=IntPatch_PolyhedronTool::DeflectionOverEstimation(FirstPol)+
114 IntPatch_PolyhedronTool::DeflectionOverEstimation(SeconPol);
116 Tolerance=Epsilon(1000.);
117 Interference(FirstPol, SeconPol);
121 //=======================================================================
124 //=======================================================================
126 void IntPatch_InterferencePolyhedron::Perform
127 (const IntPatch_Polyhedron& Objet)
129 SelfInterference(Standard_True);
130 Tolerance=IntPatch_PolyhedronTool::DeflectionOverEstimation(Objet)*2;
132 Tolerance=Epsilon(1000.);
137 //=======================================================================
138 //function : Interference
140 //=======================================================================
142 void IntPatch_InterferencePolyhedron::Interference
143 (const IntPatch_Polyhedron&)
146 void IntPatch_InterferencePolyhedron::Interference
147 (const IntPatch_Polyhedron& FirstPol, const IntPatch_Polyhedron& SeconPol)
149 Standard_Boolean gridOnFirst=Standard_True;
150 Standard_Integer NbTrianglesFirstPol = IntPatch_PolyhedronTool::NbTriangles(FirstPol);
151 Standard_Integer NbTrianglesSecondPol = IntPatch_PolyhedronTool::NbTriangles(SeconPol);
152 Standard_Integer iFirst, iSecon;
154 //------------------------------------------------------------------------------------------
155 //-- the same number of triangles it is necessary to test better on
156 //-- the size of boxes.
158 //-- the second is chosen if nbTri1 > 2*nbTri2 or if VolBoit1 > 2*VolBoit2
160 //--if (!SelfIntf && NbTrianglesFirstPol>NbTrianglesSecondPol)
161 //-- gridOnFirst=Standard_False;
164 if(NbTrianglesFirstPol > NbTrianglesSecondPol+NbTrianglesSecondPol) gridOnFirst=Standard_False;
166 Standard_Real vol1,vol2,Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
167 IntPatch_PolyhedronTool::Bounding(FirstPol).Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
168 vol1 = (Xmax-Xmin)*(Ymax-Ymin)*(Zmax-Zmin);
170 IntPatch_PolyhedronTool::Bounding(SeconPol).Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
171 vol2 = (Xmax-Xmin)*(Ymax-Ymin)*(Zmax-Zmin);
173 if(vol1> 8.0*vol2) gridOnFirst=Standard_False;
178 Bnd_BoundSortBox TheGridFirst;
179 TheGridFirst.Initialize(IntPatch_PolyhedronTool::Bounding(FirstPol),
180 IntPatch_PolyhedronTool::ComponentsBounding(FirstPol));
182 for (iSecon=1; iSecon<=NbTrianglesSecondPol; iSecon++) {
184 TColStd_ListIteratorOfListOfInteger iLoI(TheGridFirst.Compare
185 (IntPatch_PolyhedronTool::ComponentsBounding(SeconPol)->Value(iSecon)));
186 while (iLoI.More()) {
190 Intersect(iFirst, FirstPol, iSecon, SeconPol);
193 Intersect(iFirst, FirstPol, iSecon, SeconPol);
200 Bnd_BoundSortBox TheGridSecond;
201 TheGridSecond.Initialize(IntPatch_PolyhedronTool::Bounding(SeconPol),
202 IntPatch_PolyhedronTool::ComponentsBounding(SeconPol));
204 for (iFirst=1; iFirst<=NbTrianglesFirstPol; iFirst++) {
205 TColStd_ListIteratorOfListOfInteger
206 iLoI(TheGridSecond.Compare
207 (IntPatch_PolyhedronTool::ComponentsBounding(FirstPol)->Value(iFirst)));
209 while (iLoI.More()) {
213 Intersect(iFirst, FirstPol, iSecon, SeconPol);
216 Intersect(iFirst, FirstPol, iSecon, SeconPol);
224 //=======================================================================
225 //function : Intersect
226 //purpose : Intersection of two triangles issue from two Polyhedron.
227 //=======================================================================
229 void IntPatch_InterferencePolyhedron::Intersect
230 (const Standard_Integer Tri1, const IntPatch_Polyhedron& FirstPol,
231 const Standard_Integer Tri2, const IntPatch_Polyhedron& SeconPol)
233 IntPatch_PolyhedronTool::Triangle(FirstPol, Tri1,OI[0],OI[1],OI[2]);
234 IntPatch_PolyhedronTool::Triangle(SeconPol, Tri2,TI[0],TI[1],TI[2]);
236 // If there is an intersection of a polyhedron with itself, the
237 // intersections are excluded
238 // from a triangle with connected triangles :
241 if (OI[0]==TI[0] || OI[0]==TI[1] || OI[0]==TI[2] ||
242 OI[1]==TI[0] || OI[1]==TI[1] || OI[1]==TI[2] ||
243 OI[2]==TI[0] || OI[2]==TI[1] || OI[2]==TI[2] ) return;
246 // The precision of intersections includes two values ;
248 // - Tolerance :This value allows detecting potential
249 // intersections in all cases. The value should be the
250 // sum of upper bounds of tops pof two polyhedrons.
252 // - floatGap : This value is the actual precision of calculation
253 // of line of section.Its value is very small, it
254 // allows having the same behaviour for
255 // geometry tests as for the values used.
257 Standard_Real floatGap=1e-13 ; //-- Epsilon(1000.);
260 // Equation of the triangle plane of the objet
261 gp_XYZ ONor; // Normal vector.
262 Standard_Real Odp; // Polar Distance.
263 Intf::PlaneEquation(IntPatch_PolyhedronTool::Point(FirstPol, OI[0]),
264 IntPatch_PolyhedronTool::Point(FirstPol, OI[1]),
265 IntPatch_PolyhedronTool::Point(FirstPol, OI[2]),
269 // Equation of the triangle plane of the tool
270 gp_XYZ TNor; // Normal vector.
271 Standard_Real Tdp; // Polar distance.
272 Intf::PlaneEquation(IntPatch_PolyhedronTool::Point(SeconPol, TI[0]),
273 IntPatch_PolyhedronTool::Point(SeconPol, TI[1]),
274 IntPatch_PolyhedronTool::Point(SeconPol, TI[2]),
278 // Scalar product of two normalized vectors -> cosinus of the angle
279 Incidence= Abs(TNor*ONor);
281 // Distance of the plane of the triangle from the object by three points of SeconPol
282 Standard_Real dfOpT[3];
283 dfOpT[0]=ONor*(IntPatch_PolyhedronTool::Point(SeconPol, TI[0]).XYZ())-Odp;
284 dfOpT[1]=ONor*(IntPatch_PolyhedronTool::Point(SeconPol, TI[1]).XYZ())-Odp;
285 dfOpT[2]=ONor*(IntPatch_PolyhedronTool::Point(SeconPol, TI[2]).XYZ())-Odp;
287 // Distance of the plane of the triangle from the tool by three points of FirstPol
288 Standard_Real dpOfT[3];
289 dpOfT[0]=TNor*(IntPatch_PolyhedronTool::Point(FirstPol, OI[0]).XYZ())-Tdp;
290 dpOfT[1]=TNor*(IntPatch_PolyhedronTool::Point(FirstPol, OI[1]).XYZ())-Tdp;
291 dpOfT[2]=TNor*(IntPatch_PolyhedronTool::Point(FirstPol, OI[2]).XYZ())-Tdp;
293 // Values defining the couple of triangle dpOpT, dpOeT, deOpT
294 CoupleCharacteristics(FirstPol, SeconPol);
296 // If three points of the triangle of <SeconPol> are in the plane of the
297 // triangle of <Obje> within <Tolerance> the eventual tangency zone is found.
299 Intf_TangentZone TheTZ;
300 if ((Abs(dfOpT[0])<=Tolerance &&
301 Abs(dfOpT[1])<=Tolerance &&
302 Abs(dfOpT[2])<=Tolerance) &&
303 (Abs(dpOfT[0])<=Tolerance &&
304 Abs(dpOfT[1])<=Tolerance &&
305 Abs(dpOfT[2])<=Tolerance) &&
306 (Abs(dfOpT[0]+dfOpT[1]+dfOpT[2])!=
307 Abs(dfOpT[0])+Abs(dfOpT[1])+Abs(dfOpT[2])) &&
308 (Abs(dpOfT[0]+dpOfT[1]+dpOfT[2])!=
309 Abs(dpOfT[0])+Abs(dpOfT[1])+Abs(dpOfT[2]))){
311 if (TangentZoneValue(TheTZ, FirstPol, Tri1, SeconPol, Tri2))
313 if (!Insert(TheTZ)) myTZones.Append(TheTZ);
317 // Otherwise line of section is calculated:
319 Standard_Integer iObj, iToo;
321 // Zone de stockage des resultats :
322 Standard_Integer nbpiOT=0;
323 Standard_Integer nbpiO=0;
324 Standard_Integer nbpiT=0;
325 Intf_SeqOfSectionPoint piOT;
326 Standard_Real parO[3];
327 Standard_Real parT[3];
329 // Indicateurs d arete touchee
330 Standard_Integer edOT[3];
331 Standard_Integer edTT[3];
334 //--for (iObj=0; iObj<3; iObj++) {
335 // parO[iObj]=parT[iObj]=-1.;
336 // edOT[iObj]=edTT[iObj]=1;
338 parO[0]=parT[0]=parO[1]=parT[1]=parO[2]=parT[2]=-1.0;
339 edOT[0]=edTT[0]=edOT[1]=edTT[1]=edOT[2]=edTT[2]= 1;
341 // Singularite VERTEX VERTEX
342 //for (iObj=0; iObj<3; iObj++) {
343 // for (iToo=0; iToo<3; iToo++) {
344 // if (dpOpT[iObj][iToo] <= floatGap) {
345 // piOT.Append(Intf_SectionPoint(IntPatch_PolyhedronTool::Point(FirstPol, OI[iObj]),
346 // Intf_VERTEX, OI[iObj], 0, 0.,
347 // Intf_VERTEX, TI[iToo], 0, 0.,
351 // edOT[Pourcent3[iObj+2]]=0; edOT[iObj]=0;
352 // edTT[Pourcent3[iToo+2]]=0; edTT[iToo]=0;
353 // nbpiOT++; nbpiO++; nbpiT++;
357 //---------------------------->
358 for (iObj=0; iObj<3; iObj++) {
359 for (iToo=0; iToo<3; iToo++) {
360 if (dpOpT[iObj][iToo] <= floatGap) {
361 piOT.Append(Intf_SectionPoint(IntPatch_PolyhedronTool::Point(FirstPol, OI[iObj]),
362 Intf_VERTEX, OI[iObj], 0, 0.,
363 Intf_VERTEX, TI[iToo], 0, 0.,
365 parO[iObj]=parT[iToo]=0.0;
366 edOT[Pourcent3[iObj+2]]=edOT[iObj]=edTT[Pourcent3[iToo+2]]=edTT[iToo]=0;
367 nbpiOT++; nbpiO++; nbpiT++;
373 // Singularite VERTEX EDGE
374 Standard_Integer inext, jnext;
375 for (iObj=0; iObj<3; iObj++) {
376 if (parO[iObj]==-1.) {
377 for (iToo=0; iToo<3; iToo++) {
378 inext=Pourcent3[iToo+1];
380 if (dpOeT[iObj][iToo] <= floatGap && dpOeT[iObj][iToo]>=-floatGap ) {
381 if ((dpOpT[iObj][iToo]+dpOpT[iObj][inext])<vtt[iToo].Modulus()) {
382 parT[iToo]=dpOpT[iObj][iToo]/(dpOpT[iObj][iToo]+
384 if (TI[iToo]>TI[inext]) parT[iToo]=1.-parT[iToo];
385 piOT.Append(Intf_SectionPoint
386 (IntPatch_PolyhedronTool::Point(FirstPol, OI[iObj]),
387 Intf_VERTEX, OI[iObj], 0, 0.,
388 Intf_EDGE, Min(TI[iToo],TI[inext]),
389 Max(TI[iToo],TI[inext]), parT[iToo],
392 edOT[Pourcent3[iObj+2]]=0; edOT[iObj]=0;
394 nbpiOT++; nbpiO++; nbpiT++;
402 // Singularite EDGE VERTEX
403 for (iToo=0; iToo<3; iToo++) {
404 if (parT[iToo]==-1.) {
405 for (iObj=0; iObj<3; iObj++) {
406 inext=Pourcent3[iObj+1];
408 if (Abs(deOpT[iObj][iToo]) <= floatGap) {
409 if ((dpOpT[iObj][iToo]+dpOpT[inext][iToo])<voo[iObj].Modulus()){
410 parO[iObj]=dpOpT[iObj][iToo]/(dpOpT[iObj][iToo]+
412 if (OI[iObj]>OI[inext]) parO[iObj]=1.-parO[iObj];
413 piOT.Append(Intf_SectionPoint
414 (IntPatch_PolyhedronTool::Point(SeconPol, TI[iToo]),
415 Intf_EDGE, Min(OI[iObj],OI[inext]),
416 Max(OI[iObj],OI[inext]), parO[iObj],
417 Intf_VERTEX, TI[iToo], 0, 0.,
420 edOT[iObj]=edTT[Pourcent3[iToo+2]]=edTT[iToo]=0;
421 nbpiOT++; nbpiO++; nbpiT++;
429 // Singularite FACE VERTEX
430 for (iToo=0; iToo<3; iToo++) {
431 if (parT[iToo]!=0.) {
432 if (Abs(dfOpT[iToo]) <= floatGap) {
433 piOT.Append(Intf_SectionPoint(IntPatch_PolyhedronTool::Point(SeconPol, TI[iToo]),
434 Intf_FACE, Tri1, 0, 0.,
435 Intf_VERTEX, TI[iToo], 0, 0.,
438 edTT[Pourcent3[iToo+2]]=edTT[iToo]=0;
444 // Singularite VERTEX FACE
445 for (iObj=0; iObj<3; iObj++) {
446 if (parO[iObj]!=0.) {
447 if (Abs(dpOfT[iObj]) <= floatGap) {
448 piOT.Append(Intf_SectionPoint(IntPatch_PolyhedronTool::Point(FirstPol, OI[iObj]),
449 Intf_VERTEX, OI[iObj], 0, 0.,
450 Intf_FACE, Tri2, 0, 0.,
453 edOT[Pourcent3[iObj+2]]=edOT[iObj]=0;
459 // Singularite EDGE EDGE
463 for (iObj=0; iObj<3; iObj++) {
464 inext=Pourcent3[iObj+1];
465 if (edOT[iObj]==1 && (dpOfT[iObj]*dpOfT[inext])<0.) {
466 lg=dpOfT[iObj]/(dpOfT[iObj]-dpOfT[inext]);
467 if (lg>0. && lg<1.) {
468 for (iToo=0; iToo<3; iToo++) {
469 jnext=Pourcent3[iToo+1];
470 if (edTT[iToo]==1 && (dfOpT[iToo]*dfOpT[jnext])<0.) {
471 lg=dfOpT[iToo]/(dfOpT[iToo]-dfOpT[jnext]);
472 if (lg>0. && lg<1.) {
473 Standard_Boolean Pb=Standard_False;
474 if (OI[iObj]>OI[inext]) {
475 Standard_Real div=(dpOeT[inext][iToo]-dpOeT[iObj][iToo]);
476 if(div>floatGap || div<-floatGap) {
477 parO[iObj]=dpOeT[inext][iToo]/div;
478 piO=(IntPatch_PolyhedronTool::Point(FirstPol,OI[inext]).XYZ()) +
479 (voo[iObj].Reversed()*parO[iObj]);
485 Standard_Real div = dpOeT[iObj][iToo]-dpOeT[inext][iToo];
486 if(div>floatGap || div<-floatGap) {
487 parO[iObj]=dpOeT[iObj][iToo]/
488 (dpOeT[iObj][iToo]-dpOeT[inext][iToo]);
489 piO=(IntPatch_PolyhedronTool::Point(FirstPol,OI[iObj]).XYZ()) +
490 (voo[iObj]*parO[iObj]);
495 if (TI[iToo]>TI[jnext]) {
496 Standard_Real div=(deOpT[iObj][jnext]-deOpT[iObj][iToo]);
497 if(div>floatGap || div<-floatGap) {
498 parT[iToo]=deOpT[iObj][jnext]/div;
499 piT=(IntPatch_PolyhedronTool::Point(SeconPol,TI[jnext]).XYZ()) +
500 (vtt[iToo].Reversed()*parT[iToo]);
506 Standard_Real div=(deOpT[iObj][iToo]-deOpT[iObj][jnext]);
507 if(div>floatGap || div<-floatGap) {
508 parT[iToo]=deOpT[iObj][iToo]/div;
509 piT=(IntPatch_PolyhedronTool::Point(SeconPol,TI[iToo]).XYZ()) +
510 (vtt[iToo]*parT[iToo]);
515 if(Pb==Standard_False) {
519 piOT.Append(Intf_SectionPoint
521 Intf_EDGE, Min(OI[iObj],OI[inext]),
522 Max(OI[iObj],OI[inext]), parO[iObj],
523 Intf_EDGE, Min(TI[iToo],TI[jnext]),
524 Max(TI[iToo],TI[jnext]), parT[iToo],
526 edOT[iObj]=edTT[iToo]=0;
527 nbpiOT++; nbpiO++; nbpiT++;
537 // Intersection EDGE FACE
538 for (iObj=0; iObj<3; iObj++) {
539 inext=Pourcent3[iObj+1];
540 if (edOT[iObj]==1 && (dpOfT[iObj]*dpOfT[inext])<0.) {
541 lg=dpOfT[iObj]/(dpOfT[iObj]-dpOfT[inext]);
542 if (lg>0. && lg<1.) {
544 piO=(IntPatch_PolyhedronTool::Point(FirstPol, OI[iObj]).XYZ())+
545 (voo[iObj]*parO[iObj]);
546 if (OI[iObj]>OI[inext]) parO[iObj]=1.-parO[iObj];
548 Intf_SectionPoint (piO,
549 Intf_EDGE, Min(OI[iObj],OI[inext]),
550 Max(OI[iObj],OI[inext]), parO[iObj],
551 Intf_FACE, Tri2, 0, 0., Incidence));
557 // Intersection FACE EDGE
558 for (iToo=0; iToo<3; iToo++) {
559 jnext=Pourcent3[iToo+1];
560 if (edTT[iToo]==1 && (dfOpT[iToo]*dfOpT[jnext])<0.) {
561 lg=dfOpT[iToo]/(dfOpT[iToo]-dfOpT[jnext]);
562 if (lg>0. && lg<1.) {
564 piO=(IntPatch_PolyhedronTool::Point(SeconPol, TI[iToo]).XYZ())+
565 (vtt[iToo]*parT[iToo]);
566 if (TI[iToo]>TI[jnext]) parT[iToo]=1.-parT[iToo];
567 piOT.Append(Intf_SectionPoint
569 Intf_FACE, Tri1, 0, 0.,
570 Intf_EDGE, Min(TI[iToo],TI[jnext]),
571 Max(TI[iToo],TI[jnext]), parT[iToo],
578 NCollection_LocalArray <Standard_Integer> id(Max(nbpiOT, 4));
580 Standard_Integer ideb=-1;
581 Standard_Integer ifin=-2;
585 // Sort the <nbpiOT> sections points along the intersection between the
588 gp_XYZ dir=ONor^TNor;
589 NCollection_LocalArray <Standard_Real> d(nbpiOT);
590 Standard_Integer iPi, iPs;
591 for (iPi=0; iPi<nbpiOT; iPi++) {
592 d[iPi]=dir*piOT(iPi+1).Pnt().XYZ();
597 for (iPi=1; iPi<nbpiOT; iPi++) {
599 for (iPs=iPi-1; iPs>=0; iPs--) {
600 if (d[id[iPs]] > d[id[iPs+1]]) {
610 // Possibility of line of section :
612 if (nbpiO==2 && nbpiT==2) {
614 // In the case when an edge is in the plane of the other triangle
615 // it is necessary to check if it has not been already processed
616 // on a connected triangle :
619 Standard_Integer pivo=-1;
620 Standard_Integer pedg=-1;
623 if (parO[1]==0.) pedg=1;
624 else if (parO[2]==0.) pedg=2;
626 else if (parO[1]==0.) {
628 if (parO[2]==0.) pedg=2;
630 if (pivo>=0 && pedg>=0) {
631 IntPatch_PolyhedronTool::TriConnex(FirstPol, Tri1,OI[pivo],OI[pedg],pivo,pedg);
634 ideb=-1; // On a deja trouve celle ci
644 if (parT[1]==0.) pedg=1;
645 else if (parT[2]==0.) pedg=2;
647 else if (parT[1]==0.) {
649 if (parT[2]==0.) pedg=2;
651 if (pivo>=0 && pedg>=0) {
652 IntPatch_PolyhedronTool::TriConnex(SeconPol, Tri2,TI[pivo],TI[pedg],pivo,pedg);
655 ideb=-1; // It has been already found
662 // If there is a covering up : insert the section line in the existent
663 // list or create a new section line :
665 if (piOT(id[0]+1).TypeOnFirst()==Intf_FACE) {
666 if (piOT(id[1]+1).TypeOnFirst()==Intf_FACE) {
667 ideb=-id[0]-1; // No line of section possible
670 else if (piOT(id[1]+1).TypeOnSecond()!=Intf_FACE) {
671 ideb=id[1]; // No line of section possible
672 ifin=id[1]; // only a pointersec
674 else if (nbpiOT>=3) {
675 ideb=id[1]; // Retrieve 2 segments of section
679 ideb=-999; // No line of section possible
683 else if (piOT(id[0]+1).TypeOnSecond()==Intf_FACE) {
684 if (piOT(id[1]+1).TypeOnSecond()==Intf_FACE) {
685 ideb=-id[0]-1; // No line of section possible
688 else if (piOT(id[1]+1).TypeOnFirst()!=Intf_FACE) {
689 ideb=id[1]; // No line of section possible
690 ifin=id[1]; // only a pointersec
692 else if (nbpiOT>=3) {
693 ideb=id[1]; // Recouvrement des 2 segments de section
697 ideb=-999; // No line of section possible
702 else { // Singularity on the first point there is only two or
703 ideb=id[0]; // three pointersec, so the first is a solution
704 ifin=id[1]; // and the second too.
709 // Insertion of the segment found in the existing section lines :
714 //static unsigned nisp=0;
715 Standard_Real d=piOT(-ideb).Pnt().Distance(piOT(-ifin).Pnt());
717 Insert(piOT(-ideb), piOT(-ifin));
718 //-- std::cout<<"Insertion Point IntPatch_InterferencePolyhedron 1,2 d="<<d<<" Tol="<<Tolerance<<" num:"<<++nisp<<std::endl;
719 //-- piOT(-ideb).Dump(1); piOT(-ifin).Dump(0);
720 //-- std::cout<<"point p"<<++nisp<<" "<<piOT(-ideb).Pnt().X()<<" "<<piOT(-ideb).Pnt().Y()<<" "<<piOT(-ideb).Pnt().Z()<<std::endl;
723 //-- std::cout<<"Insertion Point IntPatch_InterferencePolyhedron 1,2 d="<<d<<" Tol="<<Tolerance<<" NON INSERE "<<std::endl;
730 Insert(piOT(ideb+1), piOT(ifin+1));
733 // un pointersec : It is necessary to check if it has not been already found
734 // and if not insert it in the list.
735 // Attention! It is necessary to check
736 // for each new segment if a point is in the list
737 // and in this case remove it from the list.
745 //=======================================================================
746 //function : TangentZoneValue
748 //=======================================================================
750 Standard_Boolean IntPatch_InterferencePolyhedron::TangentZoneValue
751 (Intf_TangentZone& TheTZ,
752 const IntPatch_Polyhedron& FirstPol,
753 const Standard_Integer Tri1,
754 const IntPatch_Polyhedron& SeconPol,
755 const Standard_Integer Tri2) const
757 // Potential tangent Zone !
758 // ------------------------
760 Standard_Boolean finished=Standard_False;
761 Standard_Integer nob, nou, nob2, nou2;
766 for (nou=0; nou<3; nou++) {
767 tOP[nou]= Intf_EXTERNAL;
768 tTP[nou]= Intf_EXTERNAL;
771 Standard_Integer nbpInt=0;
772 Intf_SeqOfSectionPoint Tpi;
774 // Compute the positions of the points of <Tri1> in the triangle <Tri2>.
775 for (nob=0; nob<=2; nob++) {
776 nob2=Pourcent3[nob+1];
777 for (nou=0; nou<=2; nou++) {
778 nou2=Pourcent3[nou+1];
779 if (dpOpT[nob][nou]<=Tolerance) {
780 Tpi.Append(Intf_SectionPoint(IntPatch_PolyhedronTool::Point(FirstPol, OI[nob]),
781 Intf_VERTEX, OI[nob], 0, 0.,
782 Intf_VERTEX, TI[nou], 0, 0.,
784 tOP[nob]=Intf_VERTEX;
785 tTP[nou]=Intf_VERTEX;
789 else if (Abs(dpOeT[nob][nou])<=Tolerance) {
790 if (dpOpT[nob][nou]+dpOpT[nob][nou2]<vtt[nou].Modulus()) {
791 par=dpOpT[nob][nou]/(dpOpT[nob][nou]+dpOpT[nob][nou2]);
792 if (TI[nou]>TI[nou2]) par=1.-par;
793 Tpi.Append(Intf_SectionPoint (IntPatch_PolyhedronTool::Point(FirstPol, OI[nob]),
794 Intf_VERTEX, OI[nob], 0, 0.,
795 Intf_EDGE, Min(TI[nou], TI[nou2]),
796 Max(TI[nou], TI[nou2]), par,
804 if (tOP[nob]==Intf_EXTERNAL) {
805 if (Intf::Contain(IntPatch_PolyhedronTool::Point(SeconPol, TI[0]),
806 IntPatch_PolyhedronTool::Point(SeconPol, TI[1]),
807 IntPatch_PolyhedronTool::Point(SeconPol, TI[2]),
808 IntPatch_PolyhedronTool::Point(FirstPol, OI[nob]))) {
809 Tpi.Append(Intf_SectionPoint(IntPatch_PolyhedronTool::Point(FirstPol, OI[nob]),
810 Intf_VERTEX, OI[nob], 0, 0.,
811 Intf_FACE, Tri2, 0, 0.,
819 // If the three points of <Tri1> are in <Tri2> the triangle Tri1 is
820 // itself the tangent zone else compute the positions of the points
821 // of <Tri2> in <Tri1>.
823 for (nou=0; nou<=2; nou++) {
824 nou2=Pourcent3[nou+1];
825 if (tTP[nou]==Intf_EXTERNAL) {
826 for (nob=0; nob<=2; nob++) {
827 nob2=Pourcent3[nob+1];
828 if (Abs(deOpT[nob][nou])<=Tolerance) {
829 if (dpOpT[nob][nou]+dpOpT[nob2][nou]<voo[nob].Modulus()) {
830 par=dpOpT[nob][nou]/(dpOpT[nob][nou]+dpOpT[nob2][nou]);
831 if (OI[nob]>OI[nob2]) par=1.-par;
832 Tpi.Append(Intf_SectionPoint(IntPatch_PolyhedronTool::Point(SeconPol,TI[nou]),
833 Intf_EDGE, Min(OI[nob], OI[nob2]),
834 Max(OI[nob], OI[nob2]), par,
835 Intf_VERTEX, TI[nou], 0, 0., 1.));
842 if (tTP[nou]==Intf_EXTERNAL) {
843 if (Intf::Contain(IntPatch_PolyhedronTool::Point(FirstPol, OI[0]),
844 IntPatch_PolyhedronTool::Point(FirstPol, OI[1]),
845 IntPatch_PolyhedronTool::Point(FirstPol, OI[2]),
846 IntPatch_PolyhedronTool::Point(SeconPol, TI[nou]))) {
847 Tpi.Append(Intf_SectionPoint(IntPatch_PolyhedronTool::Point(SeconPol, TI[nou]),
848 Intf_FACE, Tri1, 0, 0.,
849 Intf_VERTEX, TI[nou], 0, 0.,
857 if (tTP[0]!=Intf_EXTERNAL &&
858 tTP[1]!=Intf_EXTERNAL &&
859 tTP[2]!=Intf_EXTERNAL)
860 finished=Standard_True;
863 finished=Standard_True;
865 // Insertion of the points of intersection in the zone of tangency :
866 for (nob=1; nob<=nbpInt; nob++)
867 TheTZ.Append(Tpi(nob));
870 // If one of the triangles is not in the zone of tangency, it is necessary to find
871 // the points of intersection edge/edge :
873 // Last indexes are not used.
874 // Arrays are increased to eliminate gcc warning.
875 Standard_Real parO[10], parT[10];
876 Standard_Integer nbNoInserted=0;
877 Standard_Integer piToInsert[17]; // for GCC 4.9
879 for (nob=0; nob<3; nob++) {
880 //processing of the object segment P[nob], P[nob+1]
881 nob2=Pourcent3[nob+1];
883 for (nou=0; nou<3; nou++) {
884 //processing of the segment of the tool P[nou], P[nou+1]
885 nou2=Pourcent3[nou+1];
887 if (dpOeT[nob][nou]*dpOeT[nob2][nou]<0. &&
888 deOpT[nob][nou]*deOpT[nob][nou2]<0.) {
894 parO[nbpInt]=dpOeT[nob][nou]/(dpOeT[nob][nou]-dpOeT[nob2][nou]);
895 parT[nbpInt]=deOpT[nob][nou]/(deOpT[nob][nou]-deOpT[nob][nou2]);
896 gp_Pnt lepi=IntPatch_PolyhedronTool::Point(SeconPol, TI[nou]).Translated
897 (gp_Vec(vtt[nou]*parT[nbpInt]));
898 if (OI[nob]>OI[nob2]) parO[nbpInt]=1.-parO[nbpInt];
899 if (TI[nou]>TI[nou2]) parT[nbpInt]=1.-parT[nbpInt];
900 Tpi.Append(Intf_SectionPoint(lepi,
901 Intf_EDGE, Min(OI[nob],OI[nob2]),
902 Max(OI[nob],OI[nob2]), parO[nbpInt],
903 Intf_EDGE, Min(TI[nou],TI[nou2]),
904 Max(TI[nou],TI[nou2]), parT[nbpInt],
907 if (!TheTZ.Insert(Tpi(nbpInt))) {
908 piToInsert[nbNoInserted]=nbpInt;
914 if (nbpInt>=5) break; // Number of pi passed in TZ !
918 while (!TheTZ.Insert(Tpi(piToInsert[nob]))) {
924 while (nob < nbNoInserted) {
925 piToInsert[nob]=piToInsert[nob+1];
931 if (nbNoInserted>0) {
934 Tpi(piToInsert[nob--]).Dump(4);
938 if (nbpInt<3) nbpInt=0;
943 //=======================================================================
944 //function : CoupleCharacteristics
946 //=======================================================================
948 void IntPatch_InterferencePolyhedron::CoupleCharacteristics (const IntPatch_Polyhedron& FirstPol,
949 const IntPatch_Polyhedron& SeconPol)
951 Standard_Integer n1, n2;
954 for (n1=0; n1<3; n1++) {
956 voo[n1]=IntPatch_PolyhedronTool::Point(FirstPol, OI[n2]).XYZ()-
957 IntPatch_PolyhedronTool::Point(FirstPol, OI[n1]).XYZ();
958 vtt[n1]=IntPatch_PolyhedronTool::Point(SeconPol, TI[n2]).XYZ()-
959 IntPatch_PolyhedronTool::Point(SeconPol, TI[n1]).XYZ();
962 gp_XYZ vvec=(voo[0]^voo[1])+(voo[1]^voo[2])+(voo[2]^voo[0]);
963 gp_XYZ vnorT=(vtt[0]^vtt[1])+(vtt[1]^vtt[2])+(vtt[2]^vtt[0]);
964 if (vnorT.Modulus()>vvec.Modulus())
967 for (n1=0; n1<3; n1++) {
969 for (n2=0; n2<3; n2++) {
971 gp_XYZ vto=IntPatch_PolyhedronTool::Point(FirstPol, OI[n1]).XYZ()-
972 IntPatch_PolyhedronTool::Point(SeconPol, TI[n2]).XYZ();
973 dpOpT[n1][n2]=vto.Modulus();
975 lg=vtt[n2].Modulus();
976 if (lg > 1e-16) { //-- RealEpsilon()
977 gp_XYZ vv=vto^vtt[n2];
978 lg=(vvec*vv)>0.0 ? lg : -lg;
979 dpOeT[n1][n2]=vv.Modulus()/lg;
982 dpOeT[n1][n2]=dpOpT[n1][n2];
984 lg=voo[n1].Modulus();
985 if (lg > 1e-16) { //-- RealEpsilon())
986 gp_XYZ vv=vto^voo[n1];
987 lg=(vvec*vv)>0.0 ? -lg : lg;
988 deOpT[n1][n2]=vv.Modulus()/lg;
991 deOpT[n1][n2]=dpOpT[n1][n2];