7669ba4119e4888c1755e4f1bf90a1f906cd30bb
[occt.git] / src / IntPolyh / IntPolyh_Triangle.cxx
1 // Created on: 1999-03-08
2 // Created by: Fabrice SERVANT
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
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.
10 //
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.
13 //
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.
20
21
22
23 #include <IntPolyh_Triangle.ixx>
24 #include <IntPolyh_Point.ixx>
25 #include <IntPolyh_Edge.ixx>
26 #include <IntPolyh_StartPoint.ixx>
27 #include <IntPolyh_Couple.ixx>
28 #include <stdio.h>
29
30 #define MyTolerance 10.0e-7
31 #define MyConfusionPrecision 10.0e-12
32 #define SquareMyConfusionPrecision 10.0e-24
33
34 static
35   void GetInfoTA(const Standard_Integer numP1,
36                  const Standard_Integer numP2,
37                  const Standard_Integer numTA,
38                  const IntPolyh_ArrayOfTriangles & TTriangles,
39                  Standard_Integer & numP3b,
40                  Standard_Integer & P3bIndex,
41                  Standard_Integer & Edge2b,
42                  Standard_Integer & Edge3b);
43 static
44   void NewTriangle(const Standard_Integer P1,
45                    const Standard_Integer P2,
46                    const Standard_Integer P3,
47                    IntPolyh_ArrayOfTriangles &TTriangles,
48                    const Handle(Adaptor3d_HSurface)& MySurface,
49                    IntPolyh_ArrayOfPoints &TPoints);
50 static
51   void NewEdge(const Standard_Integer P1,
52                const Standard_Integer P2,
53                const Standard_Integer T1,
54                const Standard_Integer T2,
55              IntPolyh_ArrayOfEdges & TEdges); 
56 static
57   void OldEdge(const Standard_Integer EdgeN,
58                const Standard_Integer NumTri,
59                const Standard_Integer NewTriNum,
60                IntPolyh_ArrayOfEdges & TEdges) ;
61
62 //=======================================================================
63 //function : IntPolyh_Triangle
64 //purpose  : 
65 //=======================================================================
66 IntPolyh_Triangle::IntPolyh_Triangle() 
67
68   p1(-1),p2(-1),p3(-1),
69   e1(-1),oe1(0),e2(-1),oe2(0),e3(-1),oe3(0),
70   II(0),IP(1),Fleche(0.0) 
71 {
72
73 //=======================================================================
74 //function : IntPolyh_Triangle
75 //purpose  : 
76 //=======================================================================
77 IntPolyh_Triangle::IntPolyh_Triangle(const Standard_Integer a,
78                                      const Standard_Integer b,
79                                      const Standard_Integer c) 
80 :
81   p1(a),p2(b),p3(c),
82   e1(-1),oe1(0),e2(-1),oe2(0),e3(-1),oe3(0),
83   II(0),IP(1),Fleche(0.0) 
84
85 }
86 //=======================================================================
87 //function : FirstPoint
88 //purpose  : 
89 //=======================================================================
90 Standard_Integer IntPolyh_Triangle::FirstPoint() const 
91
92   return(p1); 
93
94 //=======================================================================
95 //function : SecondPoint
96 //purpose  : 
97 //=======================================================================
98 Standard_Integer IntPolyh_Triangle::SecondPoint() const 
99
100   return(p2); 
101 }
102 //=======================================================================
103 //function : ThirdPoint
104 //purpose  : 
105 //=======================================================================
106 Standard_Integer IntPolyh_Triangle::ThirdPoint() const 
107 {
108   return(p3); 
109 }
110 //=======================================================================
111 //function : FirstEdge
112 //purpose  : 
113 //=======================================================================
114 Standard_Integer IntPolyh_Triangle::FirstEdge() const
115 {
116   return(e1); 
117 }
118 //=======================================================================
119 //function : FirstEdgeOrientation
120 //purpose  : 
121 //=======================================================================
122 Standard_Integer IntPolyh_Triangle::FirstEdgeOrientation() const 
123 {
124   return(oe1); 
125 }
126 //=======================================================================
127 //function : SecondEdge
128 //purpose  : 
129 //=======================================================================
130 Standard_Integer IntPolyh_Triangle::SecondEdge() const 
131 {
132   return(e2); 
133 }
134 //=======================================================================
135 //function : SecondEdgeOrientation
136 //purpose  : 
137 //=======================================================================
138 Standard_Integer IntPolyh_Triangle::SecondEdgeOrientation() const 
139
140   return(oe2); 
141 }
142 //=======================================================================
143 //function : ThirdEdge
144 //purpose  : 
145 //=======================================================================
146 Standard_Integer IntPolyh_Triangle::ThirdEdge() const 
147 {
148   return(e3); 
149 }
150 //=======================================================================
151 //function : ThirdEdgeOrientation
152 //purpose  : 
153 //=======================================================================
154 Standard_Integer IntPolyh_Triangle::ThirdEdgeOrientation() const
155 {
156   return(oe3); 
157 }
158 //=======================================================================
159 //function : GetFleche
160 //purpose  : 
161 //=======================================================================
162 Standard_Real IntPolyh_Triangle::GetFleche() const 
163 {
164   return(Fleche); 
165 }
166 //=======================================================================
167 //function : IndiceIntersectionPossible
168 //purpose  : 
169 //=======================================================================
170 Standard_Integer IntPolyh_Triangle::IndiceIntersectionPossible() const 
171 {
172   return(IP); 
173 }
174 //=======================================================================
175 //function : IndiceIntersection
176 //purpose  : 
177 //=======================================================================
178 Standard_Integer IntPolyh_Triangle::IndiceIntersection() const 
179 {
180   return(II); 
181 }
182 //=======================================================================
183 //function : SetFirstPoint
184 //purpose  : 
185 //=======================================================================
186 void IntPolyh_Triangle::SetFirstPoint(const Standard_Integer a) 
187 {
188   p1=a; 
189
190 //=======================================================================
191 //function : SetSecondPoint
192 //purpose  : 
193 //=======================================================================
194 void IntPolyh_Triangle::SetSecondPoint(const Standard_Integer b)
195 {
196   p2=b; 
197 }    
198 //=======================================================================
199 //function : SetThirdPoint
200 //purpose  : 
201 //=======================================================================
202 void IntPolyh_Triangle::SetThirdPoint(const Standard_Integer c) 
203
204   p3=c;
205 }
206 //=======================================================================
207 //function : SetFirstEdge
208 //purpose  : 
209 //=======================================================================
210 void IntPolyh_Triangle::SetFirstEdge(const Standard_Integer e, 
211                                      const Standard_Integer oe) 
212 {
213   e1=e; 
214   oe1=oe;
215 }
216 //=======================================================================
217 //function : SetSecondEdge
218 //purpose  : 
219 //=======================================================================
220 void IntPolyh_Triangle::SetSecondEdge(const Standard_Integer f, 
221                                       const Standard_Integer of) 
222 {
223   e2=f; 
224   oe2=of; 
225 }
226 //=======================================================================
227 //function : SetThirdEdge
228 //purpose  : 
229 //=======================================================================
230 void IntPolyh_Triangle::SetThirdEdge(const Standard_Integer g, 
231                                      const Standard_Integer og) 
232 {
233   e3=g; 
234   oe3=og; 
235 }
236 //=======================================================================
237 //function : SetFleche
238 //purpose  : 
239 //=======================================================================
240 void IntPolyh_Triangle::SetFleche(const Standard_Real A) 
241 {
242   Fleche=A;
243 }
244 //=======================================================================
245 //function : SetIndiceIntersectionPossible
246 //purpose  : 
247 //=======================================================================
248 void IntPolyh_Triangle::SetIndiceIntersectionPossible(const Standard_Integer I) 
249 {
250   IP=I; 
251 }
252 //=======================================================================
253 //function : SetIndiceIntersection
254 //purpose  : 
255 //=======================================================================
256 void IntPolyh_Triangle::SetIndiceIntersection(const Standard_Integer I)
257 {
258   II=I; 
259 }
260 //=======================================================================
261 //function : GetEdgeNumber
262 //purpose  : 
263 //=======================================================================
264 Standard_Integer 
265   IntPolyh_Triangle::GetEdgeNumber(const Standard_Integer EdgeIndex) const 
266
267   if(EdgeIndex==1)
268     return(e1);
269   if(EdgeIndex==2)
270     return(e2);
271   if(EdgeIndex==3)
272     return(e3);
273
274   return 0;
275 }  
276 //=======================================================================
277 //function : SetEdge
278 //purpose  : 
279 //=======================================================================
280 void IntPolyh_Triangle::SetEdge(const Standard_Integer EdgeIndex,
281                                 const Standard_Integer EdgeNumber) 
282 {
283   if(EdgeIndex==1)
284     e1=EdgeNumber;
285   if(EdgeIndex==2)
286     e2=EdgeNumber;
287   if(EdgeIndex==3)
288     e3=EdgeNumber;
289 }  
290 //=======================================================================
291 //function : GetEdgeOrientation
292 //purpose  : 
293 //=======================================================================
294 Standard_Integer 
295   IntPolyh_Triangle::GetEdgeOrientation(const Standard_Integer EdgeIndex) const 
296 {
297   if(EdgeIndex==1)
298     return(oe1);
299   if(EdgeIndex==2)
300     return(oe2);
301   if(EdgeIndex==3)
302     return(oe3);
303
304   return 0;
305
306 }  
307 //=======================================================================
308 //function : SetEdgeOrientation
309 //purpose  : 
310 //=======================================================================
311 void IntPolyh_Triangle::SetEdgeOrientation(const Standard_Integer EdgeIndex,
312                                            const Standard_Integer OrEd) 
313 {
314   if(EdgeIndex==1)
315     oe1=OrEd;
316   if(EdgeIndex==2)
317     oe2=OrEd;
318   if(EdgeIndex==3)
319     oe3=OrEd;
320 }  
321
322       
323 //=======================================================================
324 //function : TriangleDeflection
325 //purpose  : 
326 /*Calcul de la fleche pour un triangle**************
327   Distance entre le plan forme par le triangle et
328   le barycentre situe sur la surface calcule avec les coordonnees Gu,Gv
329   (coordonnees du barycentre du triangle dans l'espace UV)*/
330 //=======================================================================
331 void IntPolyh_Triangle::TriangleDeflection(const Handle(Adaptor3d_HSurface)& MySurface,
332                                            const IntPolyh_ArrayOfPoints& TPoints)
333 {
334   const IntPolyh_Point & P1 = TPoints[p1];
335   const IntPolyh_Point & P2 = TPoints[p2];
336   const IntPolyh_Point & P3 = TPoints[p3];
337   //
338   //modified by NIZNHY-PKV Fri Jan 20 14:25:11 2012f
339   {
340     Standard_Integer iDeg1, iDeg2, iDeg3, iDeg;
341     //
342     iDeg1=(P1.Degenerated()) ? 1 : 0;
343     iDeg2=(P2.Degenerated()) ? 1 : 0;
344     iDeg3=(P3.Degenerated()) ? 1 : 0;
345     iDeg=iDeg1+iDeg2+iDeg3;
346     if (iDeg>1) {
347       Fleche=0.;
348       return;
349     }
350   }
351   //modified by NIZNHY-PKV Fri Jan 20 14:25:13 2012t
352   Standard_Real Gu, Gv, SqNorme;
353   gp_Pnt PtXYZ;
354   //
355   Gu=(P1.U()+P2.U()+P3.U())/3.0;
356   Gv=(P1.V()+P2.V()+P3.V())/3.0;
357
358   PtXYZ = (MySurface)->Value( Gu, Gv);
359   IntPolyh_Point BarycentreReel(PtXYZ.X(), PtXYZ.Y(), PtXYZ.Z(), Gu, Gv);
360   IntPolyh_Point NormaleTri;
361   NormaleTri.Cross(P2-P1,P3-P1);
362   SqNorme=NormaleTri.SquareModulus();
363   
364   if (SqNorme > SquareMyConfusionPrecision) {
365     NormaleTri=NormaleTri/sqrt(SqNorme);
366     Fleche=Abs(NormaleTri.Dot( BarycentreReel-P1));
367   }
368   else {
369     // On calcule la fleche sur le plus grand des edges
370     // calcul des longueurs des cotes au carre
371       Standard_Real L12 = P1.SquareDistance(P2);
372       Standard_Real L23 = P2.SquareDistance(P3);
373       Standard_Real L31 = P3.SquareDistance(P1);
374
375       IntPolyh_Point Milieu; // milieu du plus grand des edges
376
377       if ((L12>L23) && (L12>L31))
378         Milieu.Middle( MySurface,P1, P2);
379       else if ((L23>L31) && (L23>L12))
380         Milieu.Middle( MySurface,P2, P3);
381       else if ((L31>L12) && (L31>L23))
382         Milieu.Middle( MySurface,P3, P1);
383         
384         
385       gp_Pnt PtXYZ = (MySurface)->Value( Milieu.U(), Milieu.V());
386       IntPolyh_Point MilieuReel(PtXYZ.X(), PtXYZ.Y(), PtXYZ.Z(), Milieu.U(), Milieu.V());
387       Fleche = sqrt(Milieu.SquareDistance(MilieuReel));
388     }
389 }
390
391 //=======================================================================
392 //function : CheckCommonEdge
393 //purpose  : 
394 //=======================================================================
395 Standard_Integer 
396   IntPolyh_Triangle::CheckCommonEdge(const Standard_Integer PT1,
397                                      const Standard_Integer PT2,
398                                      const Standard_Integer PT3,
399                                      const Standard_Integer Index,
400                                      const IntPolyh_ArrayOfTriangles &TTriangles)  const 
401 {
402   Standard_Integer P1,P2,P3,res=-1;
403   P1=TTriangles[Index].FirstPoint();
404   P2=TTriangles[Index].SecondPoint();
405   P3=TTriangles[Index].ThirdPoint();
406   
407   if ( (P1==PT1)||(P1==PT2) ) {
408     if ( ( (P2==PT1)||(P2==PT2) )&&(P3!=PT3) ) res = Index; //edge commun P1P2
409     else if ( ( (P3==PT1)||(P3==PT2) )&&(P2!=PT3) ) res = Index;//edge commun P1P3
410   }
411   else if ( (P2==PT1)||(P2==PT2) ) {
412     if ( ( (P3==PT1)||(P3==PT2) )&&(P1!=PT3) ) res = Index; //edge commun P2P3
413   }
414   else res=-1;
415   return(res);
416 }
417 //=======================================================================
418 //function : GetNextTriangle2
419 //purpose  : 
420 //=======================================================================
421 Standard_Integer 
422   IntPolyh_Triangle::GetNextTriangle2(const Standard_Integer NumTri,
423                                       const Standard_Integer NumEdge,
424                                       const IntPolyh_ArrayOfEdges &TEdges) const 
425 {
426   Standard_Integer NumNextTri=-1;
427   if (NumEdge==1) {
428     const IntPolyh_Edge & Edge1=TEdges[e1];
429     if(Edge1.FirstTriangle()==NumTri)
430       NumNextTri=Edge1.SecondTriangle();
431     else
432       NumNextTri=Edge1.FirstTriangle();
433   }
434   else if (NumEdge==2) {
435     const IntPolyh_Edge & Edge2=TEdges[e2];
436     if(Edge2.FirstTriangle()==NumTri)
437       NumNextTri=Edge2.SecondTriangle();
438     else
439       NumNextTri=Edge2.FirstTriangle();
440   }
441   else if (NumEdge==3) {
442     const IntPolyh_Edge & Edge3=TEdges[e3];
443     if(Edge3.FirstTriangle()==NumTri)
444       NumNextTri=Edge3.SecondTriangle();
445     else
446       NumNextTri=Edge3.FirstTriangle();
447   }
448   return (NumNextTri);
449 }
450
451
452 //=======================================================================
453 //function : LinkEdges2Triangle
454 //purpose  : 
455 //=======================================================================
456 void IntPolyh_Triangle::LinkEdges2Triangle(const IntPolyh_ArrayOfEdges & TEdges,
457                                            const Standard_Integer edge1,
458                                            const Standard_Integer edge2,
459                                            const Standard_Integer edge3) {
460   if( (edge1<0)||(edge2<0)||(edge3<0) ) {
461
462   }
463   else {
464     e1=edge1;  
465     e2=edge2;
466     e3=edge3;
467     
468     if(TEdges[e1].FirstPoint()==p1) oe1=1;
469     else oe1=-1;
470     if(TEdges[e2].FirstPoint()==p2) oe2=1;
471     else oe2=-1;
472     if(TEdges[e3].FirstPoint()==p3) oe3=1;
473     else oe3=-1;
474   }
475 }
476
477 //=======================================================================
478 //function : GetInfoTA
479 //purpose  : 
480 //=======================================================================
481 void GetInfoTA(const Standard_Integer numP1,
482                const Standard_Integer numP2,
483                const Standard_Integer numTA,
484                const IntPolyh_ArrayOfTriangles & TTriangles,
485                Standard_Integer & numP3b,
486                Standard_Integer & P3bIndex,
487                Standard_Integer & Edge2b,
488                Standard_Integer & Edge3b)
489 {
490   /// On veut savoir quel est le troisieme point du triangle
491   /// adjacent (TriAdj) et quel sont les edges partant de ce point
492   const IntPolyh_Triangle & TriAdj=TTriangles[numTA];
493   Standard_Integer P1b=TriAdj.FirstPoint();
494   Standard_Integer P2b=TriAdj.SecondPoint();
495   Standard_Integer P3b=TriAdj.ThirdPoint();
496
497   if ( (P1b!=numP1)&&(P1b!=numP2) ) { 
498     numP3b=P1b; 
499     P3bIndex=1;
500     if (P2b==numP1) {
501       ///P1bP2b==numP3bnumP1:Edge3b donc dans ce cas
502      Edge3b=TriAdj.FirstEdge();
503      /// Donc P1bP3b==numP3bnumP2:Edge2b
504      Edge2b=TriAdj.ThirdEdge();
505    }
506     else {
507      Edge2b=TriAdj.FirstEdge();
508      Edge3b=TriAdj.ThirdEdge();
509     }
510   }
511   else if( (P2b!=numP1)&&(P2b!=numP2) ) { 
512     numP3b=P2b; 
513     P3bIndex=2;
514     if (P1b==numP1) {
515       ///P2bP1b==numP3bnumP1:Edge3b donc dans ce cas
516      Edge3b=TriAdj.FirstEdge();
517      /// Donc P2bP3b==numP3bnumP2:Edge2b
518      Edge2b=TriAdj.SecondEdge();
519    }
520     else {
521      Edge2b=TriAdj.FirstEdge();
522      Edge3b=TriAdj.SecondEdge();
523     }
524   }
525   else if( (P3b!=numP1)&&(P3b!=numP2) ) { 
526     numP3b=P3b; 
527     P3bIndex=3; 
528     if (P2b==numP1) {
529       ///P3bP2b==numP3bnumP1:Edge3b donc dans ce cas
530      Edge3b=TriAdj.SecondEdge();
531      /// Donc P3bP1b==numP3bnumP2:Edge2b
532      Edge2b=TriAdj.ThirdEdge();
533    }
534     else {
535      Edge2b=TriAdj.SecondEdge();
536      Edge3b=TriAdj.ThirdEdge();
537     }
538   }      
539 }
540
541 //=======================================================================
542 //function : NewTriangle
543 //purpose  : 
544 //=======================================================================
545 void NewTriangle(const Standard_Integer P1,
546                  const Standard_Integer P2,
547                  const Standard_Integer P3,
548                  IntPolyh_ArrayOfTriangles &TTriangles,
549                  const Handle(Adaptor3d_HSurface)& MySurface,
550                  IntPolyh_ArrayOfPoints &TPoints) {
551   const Standard_Integer FinTT = TTriangles.NbItems();
552   TTriangles[FinTT].SetFirstPoint(P1);
553   TTriangles[FinTT].SetSecondPoint(P2);
554   TTriangles[FinTT].SetThirdPoint(P3);
555   TTriangles[FinTT].TriangleDeflection(MySurface, TPoints);
556   TTriangles.IncrementNbItems();
557 }
558
559 //=======================================================================
560 //function : NewEdge
561 //purpose  : 
562 //=======================================================================
563 void NewEdge(const Standard_Integer P1,
564              const Standard_Integer P2,
565              const Standard_Integer T1,
566              const Standard_Integer T2,
567              IntPolyh_ArrayOfEdges & TEdges)
568 {
569
570   const Standard_Integer FinTE = TEdges.NbItems();
571
572   TEdges[FinTE].SetFirstPoint(P1);
573   TEdges[FinTE].SetSecondPoint(P2);
574   TEdges[FinTE].SetFirstTriangle(T1);
575   TEdges[FinTE].SetSecondTriangle(T2);
576   TEdges.IncrementNbItems();
577 }
578
579 //=======================================================================
580 //function : OldEdge
581 //purpose  : 
582 //=======================================================================
583 void OldEdge(const Standard_Integer EdgeN,
584              const Standard_Integer NumTri,
585              const Standard_Integer NewTriNum,
586              IntPolyh_ArrayOfEdges & TEdges) 
587 {
588   if(TEdges[EdgeN].FirstTriangle()==NumTri){
589     TEdges[EdgeN].SetFirstTriangle(NewTriNum);
590   }
591   else{
592     TEdges[EdgeN].SetSecondTriangle(NewTriNum);
593   }
594 }
595
596 //=======================================================================
597 //function : MiddleRefinement
598 //purpose  : 
599 //=======================================================================
600 void IntPolyh_Triangle::MiddleRefinement(const Standard_Integer NumTri,
601                                          const Handle(Adaptor3d_HSurface)& MySurface,
602                                          IntPolyh_ArrayOfPoints &TPoints,
603                                          IntPolyh_ArrayOfTriangles &TTriangles,
604                                          IntPolyh_ArrayOfEdges & TEdges) {
605
606   Standard_Integer FinTE = TEdges.NbItems();
607   Standard_Integer FinTT = TTriangles.NbItems();
608   
609   ///Raffinage de la maille et de ses voisines par le milieu du plus grand des cotes
610
611   Standard_Integer numP1 = FirstPoint();
612   Standard_Integer numP2 = SecondPoint();
613   Standard_Integer numP3 = ThirdPoint();
614
615   IntPolyh_Point P1 = TPoints[numP1];
616   IntPolyh_Point P2 = TPoints[numP2];
617   IntPolyh_Point P3 = TPoints[numP3];
618
619
620   ///calcul des longueurs des cotes au carre
621         
622   Standard_Real L12 = P1.SquareDistance(P2);
623   Standard_Real L23 = P2.SquareDistance(P3);
624   Standard_Real L31 = P3.SquareDistance(P1);
625
626   if ((L12>L23) && (L12>L31)) {
627     const Standard_Integer FinTP = TPoints.NbItems();
628     (TPoints[FinTP]).Middle( MySurface,P1, P2);
629     
630     ///les nouveaux triangles
631     Standard_Integer T1,T2,T3,T4;
632
633     T1=FinTT;
634     NewTriangle(numP2,numP3,FinTP,TTriangles,MySurface,TPoints);
635     FinTT++;
636     T2=FinTT;;
637     NewTriangle(numP3,numP1,FinTP,TTriangles,MySurface,TPoints);
638     FinTT++;
639
640     ///***AFFINAGE DU TRIANGLE ADJACENT***
641
642     Standard_Integer numTA = GetNextTriangle2(NumTri,1,TEdges);
643
644     if (numTA>=0) {
645       Standard_Integer numP3b = -1;
646       Standard_Integer P3bIndex = -1;
647
648       Standard_Integer Edge2b = -1;
649       Standard_Integer Edge3b = -1;
650       
651       GetInfoTA(numP1,numP2,numTA,TTriangles,numP3b,P3bIndex,Edge2b,Edge3b);
652       
653       T3=FinTT;
654       NewTriangle(numP2,numP3b,FinTP,TTriangles,MySurface,TPoints);
655       FinTT++;
656       T4=FinTT;
657       NewTriangle(numP3b,numP1,FinTP,TTriangles,MySurface,TPoints);
658
659       ///On cree les nouveaux edges
660       Standard_Integer E1,E2,E3,E4;
661       
662       E1=FinTE;
663       NewEdge(numP1,FinTP,T2,T4,TEdges);
664       FinTE++;
665       E2=FinTE;
666       NewEdge(FinTP,numP2,T1,T3,TEdges);
667       FinTE++;
668       E3=FinTE;
669       NewEdge(FinTP,numP3,T1,T2,TEdges);
670       FinTE++;
671       E4=FinTE;
672       NewEdge(FinTP,numP3b,T3,T4,TEdges);
673
674       ///On met a jour les anciens edges
675       OldEdge(e2,NumTri,T1,TEdges);
676       OldEdge(e3,NumTri,T2,TEdges);
677       OldEdge(Edge2b,numTA,T3,TEdges);
678       OldEdge(Edge3b,numTA,T4,TEdges);
679       
680       /// On remplit les nouveaux triangles avec les edges
681       TTriangles[T1].LinkEdges2Triangle(TEdges,e2,E3,E2);
682       TTriangles[T2].LinkEdges2Triangle(TEdges,e3,E1,E3);
683       TTriangles[T3].LinkEdges2Triangle(TEdges,Edge2b,E4,E2);
684       TTriangles[T4].LinkEdges2Triangle(TEdges,Edge3b,E1,E4);
685
686       ///On tue le triangle adjacent
687       TTriangles[numTA].Fleche=-1.0;
688       TTriangles[numTA].IP=0;
689
690     }
691     else { ///seulement deux nouveaux triangles
692       //on cree les nouveaux edges avec T1 et T2
693       Standard_Integer E1,E2,E3;
694       
695       E1=FinTE;
696       NewEdge(numP1,FinTP,T2,-1,TEdges);
697       FinTE++;
698       E2=FinTE;
699       NewEdge(FinTP,numP2,T1,-1,TEdges);
700       FinTE++;
701       E3=FinTE;
702       NewEdge(FinTP,numP3,T1,T2,TEdges);
703
704       ///On met a jour les anciens edges
705       OldEdge(e2,NumTri,T1,TEdges);
706       OldEdge(e3,NumTri,T2,TEdges);
707       
708       /// On remplit les nouveaux triangles avec les edges
709       TTriangles[T1].LinkEdges2Triangle(TEdges,e2,E3,E2);
710       TTriangles[T2].LinkEdges2Triangle(TEdges,e3,E1,E3);
711     }
712   }
713   
714   else if ((L23>L31) && (L23>L12)){
715     const Standard_Integer FinTP = TPoints.NbItems();
716     (TPoints[FinTP]).Middle(MySurface, P2,P3);
717
718     ///les nouveaux triangles
719     Standard_Integer T1,T2,T3,T4;    
720     
721     T1=FinTT;
722     NewTriangle(numP1,numP2,FinTP,TTriangles,MySurface,TPoints);
723     FinTT++;
724     T2=FinTT;
725     NewTriangle(numP3,numP1,FinTP,TTriangles,MySurface,TPoints);
726     FinTT++;
727     
728     ///*RAFFINAGE DU TRIANGLE ADJACENT***
729
730     Standard_Integer numTA = GetNextTriangle2(NumTri,2,TEdges);
731
732     if (numTA>=0) {
733       Standard_Integer numP1b=-1;
734       Standard_Integer P1bIndex = -1;
735
736       Standard_Integer Edge1b = -1;
737       Standard_Integer Edge3b = -1;
738
739       GetInfoTA(numP2,numP3,numTA,TTriangles,numP1b,P1bIndex,Edge3b,Edge1b);     
740
741       T3=FinTT;
742       NewTriangle(numP2,numP1b,FinTP,TTriangles,MySurface,TPoints);
743       FinTT++;
744       T4=FinTT;
745       NewTriangle(numP1b,numP3,FinTP,TTriangles,MySurface,TPoints);
746
747       ///Nouveaux Edges
748       Standard_Integer E1,E2,E3,E4;
749
750       E1=FinTE;
751       NewEdge(numP2,FinTP,T1,T3,TEdges);
752       FinTE++;
753       E2=FinTE;
754       NewEdge(FinTP,numP3,T2,T4,TEdges);
755       FinTE++;
756       E3=FinTE;
757       NewEdge(FinTP,numP1,T1,T2,TEdges);
758       FinTE++;
759       E4=FinTE;
760       NewEdge(FinTP,numP1b,T3,T4,TEdges);
761
762       ///On met a jour les anciens edges
763       OldEdge(e1,NumTri,T1,TEdges);
764       OldEdge(e3,NumTri,T2,TEdges);
765       OldEdge(Edge1b,numTA,T3,TEdges);
766       OldEdge(Edge3b,numTA,T4,TEdges);
767       
768       /// On remplit les nouveaux triangles avec les edges
769       TTriangles[T1].LinkEdges2Triangle(TEdges,e1,E1,E3);
770       TTriangles[T2].LinkEdges2Triangle(TEdges,e3,E3,E2);
771       TTriangles[T3].LinkEdges2Triangle(TEdges,Edge1b,E4,E1);
772       TTriangles[T4].LinkEdges2Triangle(TEdges,Edge3b,E2,E4);
773
774       ///On tue le triangle adjacent
775       TTriangles[numTA].Fleche=-1.0;
776       TTriangles[numTA].IP=0;
777     }
778     else { ///seulement deux nouveaux triangles
779       ///Nouveaux Edges
780       Standard_Integer E1,E2,E3;
781
782       E1=FinTE;
783       NewEdge(numP2,FinTP,T1,-1,TEdges);
784       FinTE++;
785       E2=FinTE;
786       NewEdge(FinTP,numP3,T2,-1,TEdges);
787       FinTE++;
788       E3=FinTE;
789       NewEdge(FinTP,numP1,T1,T2,TEdges);
790
791       ///On met a jour les anciens edges
792       OldEdge(e1,NumTri,T1,TEdges);
793       OldEdge(e3,NumTri,T2,TEdges);
794       
795       /// On remplit les nouveaux triangles avec les edges
796       TTriangles[T1].LinkEdges2Triangle(TEdges,e1,E1,E3);
797       TTriangles[T2].LinkEdges2Triangle(TEdges,e3,E3,E2);
798     }
799   }
800     else {
801     const Standard_Integer FinTP = TPoints.NbItems();
802     (TPoints[FinTP]).Middle(MySurface, P3,P1);
803
804     Standard_Integer T1,T2,T3,T4;
805     
806     T1=FinTT;
807     NewTriangle(numP1,numP2,FinTP,TTriangles,MySurface,TPoints);
808     FinTT++;
809     T2=FinTT;
810     NewTriangle(numP2,numP3,FinTP,TTriangles,MySurface,TPoints);
811     FinTT++;
812     
813     ///*RAFFINAGE DU TRIANGLE ADJACENT***
814
815     Standard_Integer numTA = GetNextTriangle2(NumTri,3,TEdges);
816
817     if (numTA>=0) {
818
819       Standard_Integer numP2b = -1;
820       Standard_Integer P2bIndex = -1;
821       
822       Standard_Integer Edge1b = -1;
823       Standard_Integer Edge2b = -1;
824      
825       GetInfoTA(numP3,numP1,numTA,TTriangles,numP2b,P2bIndex,Edge1b,Edge2b);
826
827       T3=FinTT;
828       NewTriangle(numP1,numP2b,FinTP,TTriangles,MySurface,TPoints);
829       FinTT++;
830       T4=FinTT;
831       NewTriangle(numP2b,numP3,FinTP,TTriangles,MySurface,TPoints);
832
833       ///Nouveaux Edges
834       Standard_Integer E1,E2,E3,E4;
835
836       E1=FinTE;
837       NewEdge(numP2,FinTP,T1,T2,TEdges);
838       FinTE++;
839       E2=FinTE;
840       NewEdge(FinTP,numP3,T2,T4,TEdges);
841       FinTE++;
842       E3=FinTE;
843       NewEdge(FinTP,numP2b,T4,T3,TEdges);
844       FinTE++;
845       E4=FinTE;
846       NewEdge(FinTP,numP1,T1,T3,TEdges);
847
848       ///On met a jour les anciens edges
849       OldEdge(e1,NumTri,T1,TEdges);
850       OldEdge(e2,NumTri,T2,TEdges);
851       OldEdge(Edge1b,numTA,T3,TEdges);
852       OldEdge(Edge2b,numTA,T4,TEdges);
853       
854       /// On remplit les nouveaux triangles avec les edges
855       TTriangles[T1].LinkEdges2Triangle(TEdges,e1,E1,E4);
856       TTriangles[T2].LinkEdges2Triangle(TEdges,e2,E2,E1);
857       TTriangles[T3].LinkEdges2Triangle(TEdges,Edge1b,E3,E4);
858       TTriangles[T4].LinkEdges2Triangle(TEdges,Edge2b,E2,E3);
859
860       ///On tue le triangle adjacent
861       TTriangles[numTA].Fleche=-1.0;
862       TTriangles[numTA].IP=0;
863     }
864     else { ///seulement deux nouveaux triangles
865       ///Nouveaux Edges
866       Standard_Integer E1,E2,E4;
867
868       E1=FinTE;
869       NewEdge(numP2,FinTP,T1,T2,TEdges);
870       FinTE++;
871       E2=FinTE;
872       NewEdge(FinTP,numP3,T2,-1,TEdges);
873       FinTE++;
874       E4=FinTE;
875       NewEdge(FinTP,numP1,T1,-1,TEdges);
876
877       ///On met a jour les anciens edges
878       OldEdge(e1,NumTri,T1,TEdges);
879       OldEdge(e2,NumTri,T2,TEdges);
880
881       /// On remplit les nouveaux triangles avec les edges
882       TTriangles[T1].LinkEdges2Triangle(TEdges,e1,E1,E4);
883       TTriangles[T2].LinkEdges2Triangle(TEdges,e2,E2,E1);
884     }
885   }
886   /// Le triangle traite est maintenant obsolete 
887   ///***On tue le triangle***
888   Fleche=-1.0;
889   IP=0;
890
891   TPoints.IncrementNbItems();
892 }
893
894 //=======================================================================
895 //function : MultipleMiddleRefinement
896 //purpose  : 
897 //=======================================================================
898 void IntPolyh_Triangle::MultipleMiddleRefinement(const Standard_Integer NbAffinages,
899                                                  const Standard_Integer NumTri,
900                                                  const Handle(Adaptor3d_HSurface)& MySurface,
901                                                  IntPolyh_ArrayOfPoints &TPoints,
902                                                  IntPolyh_ArrayOfTriangles &TTriangles,
903                                                  IntPolyh_ArrayOfEdges & TEdges) {
904
905   const Standard_Integer FinTTInit = TTriangles.NbItems();
906
907   //On sait qu'il faut affiner au moins une fois
908   TTriangles[NumTri].MiddleRefinement(NumTri,MySurface,TPoints,
909                                       TTriangles,TEdges);
910
911   if (NbAffinages>1) {
912     Standard_Integer MyNbAffinages=0;
913     if (NbAffinages > 5)
914       MyNbAffinages = 4;//5 est le maximum et on a deja affine une fois
915     //On a decide d'arreter a 5 car avec un triangle on peut en obtenir 1024
916     else MyNbAffinages = NbAffinages-1;//dans tous les cas MyNbAffinages>0
917     
918
919     //Un affinage peut donner deux ou quatre nouveaux triangles
920     // ils seront ajoute a la fin du tableau de triangles, et auront comme indice
921     // FinTTInit, FinTTInit+1,... 
922
923
924     Standard_Integer NombreReelsAffinages = 4;
925     for(Standard_Integer iii=1; iii<MyNbAffinages; iii++) 
926       NombreReelsAffinages*=4;
927     //Avec ce calcul on fait l'hypothese que chaque triangle affine donne quatre nouveaux triangles
928     //ce qui peut etre faux si on n'affine pas le triangle adjacent
929     //dans quel cas on n'obtient que deux nouveaux triangles
930     
931     Standard_Integer FinTTAffinage = FinTTInit + NombreReelsAffinages;
932     
933     for(Standard_Integer NumTriangle=FinTTInit; NumTriangle < FinTTAffinage; NumTriangle++)
934       TTriangles[NumTriangle].MiddleRefinement(NumTriangle,MySurface,TPoints,
935                                                TTriangles,TEdges);
936   }
937 }
938
939 //=======================================================================
940 //function : CompareBoxTriangle
941 //purpose  : 
942 //=======================================================================
943 Standard_Integer IntPolyh_Triangle::CompareBoxTriangle(const Bnd_Box &b,
944                                                        const IntPolyh_ArrayOfPoints &TPoints) const{
945   Standard_Integer Test=0;
946   Bnd_Box maboite;
947   const IntPolyh_Point&    PA=TPoints[p1]; 
948   const IntPolyh_Point&    PB=TPoints[p2]; 
949   const IntPolyh_Point&    PC=TPoints[p3]; 
950   gp_Pnt pntA(PA.X(),PA.Y(),PA.Z());
951   gp_Pnt pntB(PB.X(),PB.Y(),PB.Z());
952   gp_Pnt pntC(PC.X(),PC.Y(),PC.Z());
953   maboite.Add(pntA);
954   maboite.Add(pntB);
955   maboite.Add(pntC);
956   maboite.Enlarge(Fleche+MyTolerance);
957   if (maboite.IsOut(b))
958     Test=0;
959   else  
960     Test=1;
961   return(Test);
962   //Pour gagner du temps on pourrait envisager de garder la boite englobante dans la structure du triangle
963 }
964
965 //=======================================================================
966 //function : MultipleMiddleRefinement2
967 //purpose  : 
968 //=======================================================================
969 void IntPolyh_Triangle::MultipleMiddleRefinement2(const Standard_Real CritereAffinage,
970                                                   const Bnd_Box &b,//boite englobante de l'autre surface
971                                                   const Standard_Integer NumTri,
972                                                   const Handle(Adaptor3d_HSurface)& MySurface,
973                                                   IntPolyh_ArrayOfPoints &TPoints,
974                                                   IntPolyh_ArrayOfTriangles &TTriangles,
975                                                   IntPolyh_ArrayOfEdges & TEdges) {
976
977   const Standard_Integer FinTTInit = TTriangles.NbItems();
978   Standard_Integer CritereArret=FinTTInit+250;
979
980   //On sait qu'il faut affiner une fois au moins
981   MiddleRefinement(NumTri,MySurface,TPoints,
982                    TTriangles,TEdges);
983
984   Standard_Integer FinTT = TTriangles.NbItems();// FinTT n'est pas une constante, elle augmente avec l'affinage
985
986   for(Standard_Integer iii=FinTTInit; iii<(FinTT=TTriangles.NbItems()); iii++) {
987     IntPolyh_Triangle& TriangleCourant = TTriangles[iii];
988     if(TriangleCourant.CompareBoxTriangle(b,TPoints)==0)
989       //On n'affine pas le triangle
990       TriangleCourant.IP=0;
991     else if (TriangleCourant.Fleche > CritereAffinage)
992       TriangleCourant.MiddleRefinement(iii,MySurface,TPoints,
993                                        TTriangles,TEdges);
994       
995     if ( FinTT > CritereArret )//critere d'arret 250 nouveaux triangles
996       iii = FinTT;
997   }
998 }
999
1000 //=======================================================================
1001 //function : SetEdgeandOrientation
1002 //purpose  : 
1003 //=======================================================================
1004 void IntPolyh_Triangle::SetEdgeandOrientation(const Standard_Integer EdgeIndex,
1005                                               const IntPolyh_ArrayOfEdges &TEdges) {
1006   const Standard_Integer FinTE = TEdges.NbItems();
1007
1008   Standard_Integer PE1 =0,PE2 =0;
1009
1010   Standard_Integer Test=1;
1011
1012   if (EdgeIndex==1) { PE1=p1; PE2=p2; }
1013   else if (EdgeIndex==2) { PE1=p2; PE2=p3; }
1014   else if (EdgeIndex==3) { PE1=p3; PE2=p1; }
1015   else { 
1016     Test=0;
1017   }
1018   if (Test!=0) {
1019     for(Standard_Integer iioo=0; iioo<FinTE; iioo++) {
1020       Standard_Integer EFP=TEdges[iioo].FirstPoint();
1021       if (EFP==PE1) {
1022         Standard_Integer ESP=TEdges[iioo].SecondPoint();
1023         if (ESP!=EFP) {
1024           if (ESP==PE2) {
1025             SetEdgeOrientation(EdgeIndex,1);
1026             SetEdge(EdgeIndex,iioo);
1027             iioo=FinTE;
1028           }
1029         }
1030         else {
1031
1032           Test=0;
1033         }
1034       }
1035       else if (EFP==PE2) {
1036         Standard_Integer ESP=TEdges[iioo].SecondPoint();
1037         if (ESP!=EFP) {
1038           if (ESP==PE1) {
1039             SetEdgeOrientation(EdgeIndex,-1);
1040             SetEdge(EdgeIndex,iioo);
1041             iioo=FinTE;
1042           }
1043         }
1044         else {
1045
1046         }   
1047       }
1048     }
1049   }
1050 }
1051
1052
1053 //=======================================================================
1054 //function : Dump
1055 //purpose  : 
1056 //=======================================================================
1057 void IntPolyh_Triangle::Dump (const Standard_Integer i) const
1058
1059   printf("\nTriangle(%3d) : Points %5d %5d %5d Edges %5d %5d %5d fleche: %8f  intersection possible %8d  intersection: %5d\n"
1060          ,i,p1,p2,p3,e1,e2,e3,Fleche,IP,II);
1061 }
1062
1063
1064 //=======================================================================
1065 //function : DumpFleche
1066 //purpose  : 
1067 //=======================================================================
1068 void IntPolyh_Triangle::DumpFleche (const Standard_Integer i) const { 
1069   printf("\nTriangle(%3d) fleche: %5f\n",i,Fleche);
1070 }
1071