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