0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / HLRTopoBRep / HLRTopoBRep_FaceIsoLiner.cxx
1 // Created on: 1995-01-05
2 // Created by: Christophe MARION
3 // Copyright (c) 1995-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 #include <HLRTopoBRep_FaceIsoLiner.ixx>
18 #include <TopAbs.hxx>
19 #include <TopExp.hxx>
20 #include <TopExp_Explorer.hxx>
21 #include <TopoDS.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <TopTools_Array1OfShape.hxx>
24 #include <TColStd_Array1OfBoolean.hxx>
25 #include <TopTools_ListIteratorOfListOfShape.hxx>
26 //#include <BRepAdaptor_Curve2d.hxx>
27 #include <BRepAdaptor_Surface.hxx>
28 #include <BRepTools.hxx>
29 #include <BRep_Tool.hxx>
30 #include <BRep_Builder.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom2d_TrimmedCurve.hxx>
33 #include <Geom2d_Line.hxx>
34 #include <Geom2dHatch_Hatcher.hxx>
35 #include <Geom2dHatch_Intersector.hxx>
36 #include <HatchGen_ErrorStatus.hxx>
37 #include <HatchGen_Domain.hxx>
38 #include <HatchGen_PointOnHatching.hxx>
39 #include <HatchGen_PointOnElement.hxx>
40 #include <Precision.hxx>
41
42 const Standard_Real IntersectorConfusion = 1.e-10;
43 const Standard_Real IntersectorTangency  = 1.e-10;
44 const Standard_Real HatcherConfusion2d   = 1.e-8;
45 const Standard_Real HatcherConfusion3d   = 1.e-8;
46 const Standard_Real Infinite = 100.;
47
48 //=======================================================================
49 // Function : Perform
50 // Purpose  : Builds isoparametric curves with a hatcher.
51 //=======================================================================
52
53 void HLRTopoBRep_FaceIsoLiner::Perform (const Standard_Integer FI,
54                                         const TopoDS_Face& F,
55                                         HLRTopoBRep_Data& DS,
56                                         const Standard_Integer nbIsos)
57 {
58   (void)FI; // avoid compiler warning
59
60   Standard_Real UMin, UMax, VMin, VMax, U1, U2;
61   Standard_Integer ne = 0;
62   //BRep_Builder Builder;
63   TopoDS_Edge Edge;
64   TopExp_Explorer ExpEdges;
65   TopoDS_Face TF = F;
66   TF.Orientation (TopAbs_FORWARD);
67   gp_Pnt2d P;
68   gp_Pnt P1, P2;
69   TopoDS_Vertex V1U, V2U, V1V, V2V;
70
71   Geom2dHatch_Intersector Intersector
72     (IntersectorConfusion,IntersectorTangency);
73   Geom2dHatch_Hatcher Hatcher 
74     (Intersector,HatcherConfusion2d,HatcherConfusion3d,Standard_True);
75
76   BRepTools::UVBounds (TF, UMin, UMax, VMin, VMax);
77   Standard_Boolean InfiniteUMin = Precision::IsNegativeInfinite (UMin);
78   Standard_Boolean InfiniteUMax = Precision::IsPositiveInfinite (UMax);
79   Standard_Boolean InfiniteVMin = Precision::IsNegativeInfinite (VMin);
80   Standard_Boolean InfiniteVMax = Precision::IsPositiveInfinite (VMax);
81
82   if (InfiniteUMin && InfiniteUMax) {
83     UMin = - Infinite;
84     UMax =   Infinite;
85   }
86   else if (InfiniteUMin)
87     UMin = UMax - Infinite;
88   else if (InfiniteUMax)
89     UMax = UMin + Infinite;
90
91   if (InfiniteVMin && InfiniteVMax) {
92     VMin = - Infinite;
93     VMax =   Infinite;
94   }
95   else if (InfiniteVMin)
96     VMin = VMax - Infinite;
97   else if (InfiniteVMax)
98     VMax = VMin + Infinite;
99   
100   for (ExpEdges.Init (TF, TopAbs_EDGE); // Edges of the face TF
101        ExpEdges.More();
102        ExpEdges.Next()) ne++;
103
104   if (DS.FaceHasIntL(TF)) {             // OutLines built on face TF.
105     
106     TopTools_ListIteratorOfListOfShape itE;
107     for(itE.Initialize(DS.FaceIntL(TF));
108         itE.More();
109         itE.Next()) 
110       ne++;
111   }
112
113   TopTools_Array1OfShape SH(1,ne);
114   TColStd_Array1OfBoolean IL(1,ne); // internal OutLine
115
116   for (ExpEdges.Init (TF, TopAbs_EDGE);
117        ExpEdges.More();
118        ExpEdges.Next()) {
119     Standard_Integer IndE;
120     const TopoDS_Edge& newE = TopoDS::Edge(ExpEdges.Current());
121     const Handle(Geom2d_Curve) PC =
122       BRep_Tool::CurveOnSurface (newE, TF, U1, U2);
123     if(   Abs(PC->FirstParameter() - U1) <= Precision::PConfusion() 
124        && Abs(PC->LastParameter()  - U2) <= Precision::PConfusion()) { 
125       IndE = Hatcher.AddElement (PC,  newE.Orientation());      
126     }
127     else { 
128       Handle (Geom2d_TrimmedCurve) TPC =
129         new Geom2d_TrimmedCurve (PC, U1, U2);
130       IndE = Hatcher.AddElement (TPC, newE.Orientation());
131     }
132     SH(IndE) = newE;
133     if (DS.IsOutLFaceEdge(TF,newE)) IL(IndE) = Standard_True;
134     else                            IL(IndE) = Standard_False;
135   }
136   
137   if (DS.FaceHasIntL(TF)) { // get the internal OutLines built on face F.
138     TopTools_ListIteratorOfListOfShape itE;
139     for(itE.Initialize(DS.FaceIntL(TF));
140         itE.More();
141         itE.Next()) {
142       Standard_Integer IndE;
143       const TopoDS_Edge& newE = TopoDS::Edge(itE.Value());
144       const Handle(Geom2d_Curve) PC =
145         BRep_Tool::CurveOnSurface (newE, TF, U1, U2);
146       if(   Abs(PC->FirstParameter() - U1) <= Precision::PConfusion() 
147          && Abs(PC->LastParameter()  - U2) <= Precision::PConfusion()) { 
148         IndE = Hatcher.AddElement (PC,  TopAbs_INTERNAL);      
149       }
150       else { 
151         Handle (Geom2d_TrimmedCurve) TPC =
152           new Geom2d_TrimmedCurve (PC, U1, U2);
153         IndE = Hatcher.AddElement (TPC, TopAbs_INTERNAL);
154       }
155       SH(IndE) = newE;
156       IL(IndE) = Standard_True;
157     }
158   }
159
160   //-----------------------------------------------------------------------
161   // Creation des hachures.
162   //-----------------------------------------------------------------------
163   
164   BRepAdaptor_Surface Surface (TF);
165   Standard_Real Tolerance = BRep_Tool::Tolerance (TF);
166   
167   Standard_Integer IIso;
168   Standard_Real DeltaU = Abs (UMax - UMin);
169   Standard_Real DeltaV = Abs (VMax - VMin);
170   Standard_Real Confusion = Min (DeltaU, DeltaV) * HatcherConfusion3d;
171   Hatcher.Confusion3d (Confusion);
172   
173   //-----------------------------------------------------------------------
174   // Courbes Iso U.
175   //-----------------------------------------------------------------------
176   
177   Standard_Real StepU = DeltaU / (Standard_Real) nbIsos;
178   if (StepU > Confusion) {
179     Standard_Real UPrm = UMin + StepU / 2.;
180     gp_Dir2d Dir (0., 1.);
181
182     for (IIso = 1; IIso <= nbIsos; IIso++) {
183       gp_Pnt2d Ori (UPrm, 0.);
184       Handle (Geom2d_Line) IsoLine = new Geom2d_Line (Ori, Dir);
185       
186       Standard_Integer IndH = Hatcher.AddHatching (IsoLine);
187       Hatcher.Trim (IndH);
188       if (Hatcher.TrimDone (IndH) && !Hatcher.TrimFailed (IndH))
189         Hatcher.ComputeDomains (IndH);
190       if (!Hatcher.IsDone (IndH)) {
191 #ifdef HLRTOBREP_DEB
192         cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
193         cout << "U iso of parameter: " << UPrm;
194         switch (Hatcher.Status (IndH)) {
195         case HatchGen_NoProblem          :
196           cout << " No Problem"          << endl;
197           break;
198         case HatchGen_TrimFailure        :
199           cout << " Trim Failure"        << endl;
200           break;
201         case HatchGen_TransitionFailure  :
202           cout << " Transition Failure"  << endl;
203           break;
204         case HatchGen_IncoherentParity   :
205           cout << " Incoherent Parity"   << endl;
206           break;
207         case HatchGen_IncompatibleStates :
208           cout << " Incompatible States" << endl;
209           break;
210         }
211 #endif
212         Hatcher.RemHatching (IndH);
213         continue;
214       }
215       
216       Standard_Integer NbDom = Hatcher.NbDomains (IndH);
217       if (NbDom > 0) {
218
219         for (Standard_Integer IDom = 1; IDom <= NbDom; IDom++) {
220           const HatchGen_Domain& Dom = Hatcher.Domain (IndH, IDom);
221           Standard_Real U1 = Dom.HasFirstPoint()  ? 
222             Dom.FirstPoint().Parameter()  : VMin - Infinite;
223           Standard_Real U2 = Dom.HasSecondPoint() ? 
224             Dom.SecondPoint().Parameter() : VMax + Infinite;
225           IsoLine->D0 (U1, P);
226           Surface.D0 (P.X(), P.Y(), P1);
227           IsoLine->D0 (U2, P);
228           Surface.D0 (P.X(), P.Y(), P2);
229           if (Dom.HasFirstPoint()) { // Iso U - Premier point
230             const HatchGen_PointOnHatching& PntH = Dom.FirstPoint();
231
232             for (Standard_Integer IPntE = 1;
233                  IPntE <= PntH.NbPoints();
234                  IPntE++) {
235               const HatchGen_PointOnElement& PntE = PntH.Point(IPntE);
236               V1U = HLRTopoBRep_FaceIsoLiner::MakeVertex
237                 (TopoDS::Edge(SH(PntE.Index())),
238                  P1,PntE.Parameter(),Tolerance,DS);
239               if (IL(PntE.Index())) DS.AddOutV(V1U);
240             }
241           }
242           if (Dom.HasSecondPoint()) { // Iso U - Deuxieme point
243             const HatchGen_PointOnHatching& PntH = Dom.SecondPoint();
244             
245             for (Standard_Integer IPntE = 1;
246                  IPntE <= PntH.NbPoints();
247                  IPntE++) {
248               const HatchGen_PointOnElement& PntE = PntH.Point(IPntE);
249               V2U = HLRTopoBRep_FaceIsoLiner::MakeVertex
250                 (TopoDS::Edge(SH(PntE.Index())),
251                  P2,PntE.Parameter(),Tolerance,DS);
252               if (IL(PntE.Index())) DS.AddOutV(V2U);
253             }
254           }
255           if(!V1U.IsNull() && !V2U.IsNull())
256             HLRTopoBRep_FaceIsoLiner::MakeIsoLine
257               (F,IsoLine,V1U,V2U,U1,U2,Tolerance,DS);
258         }
259       }
260       
261       Hatcher.RemHatching (IndH);
262       UPrm += StepU;
263     }
264   }
265   
266   //-----------------------------------------------------------------------
267   // Courbes Iso V.
268   //-----------------------------------------------------------------------
269   
270   Standard_Real StepV = DeltaV / (Standard_Real) nbIsos;
271   if (StepV > Confusion) {
272     Standard_Real VPrm = VMin + StepV / 2.;
273     gp_Dir2d Dir (1., 0.);
274
275     for (IIso = 1; IIso <= nbIsos; IIso++) {
276       gp_Pnt2d Ori (0., VPrm);
277       Handle (Geom2d_Line) IsoLine = new Geom2d_Line (Ori, Dir);
278       
279       Standard_Integer IndH = Hatcher.AddHatching (IsoLine);
280       Hatcher.Trim (IndH);
281       if (Hatcher.TrimDone (IndH) && !Hatcher.TrimFailed (IndH))
282         Hatcher.ComputeDomains (IndH);
283       if (!Hatcher.IsDone (IndH)) {
284 #ifdef HLRTOBREP_DEB
285         cout << "HLRTopoBRep::MakeIsoLines : Face " << FI << endl;
286         cout << "V iso of parameter: " << VPrm;
287         switch (Hatcher.Status (IndH)) {
288         case HatchGen_NoProblem          :
289           cout << " No Problem"          << endl;
290           break;
291         case HatchGen_TrimFailure        :
292           cout << " Trim Failure"        << endl;
293           break;
294         case HatchGen_TransitionFailure  :
295           cout << " Transition Failure"  << endl;
296           break;
297         case HatchGen_IncoherentParity   :
298           cout << " Incoherent Parity"   << endl;
299           break;
300         case HatchGen_IncompatibleStates :
301           cout << " Incompatible States" << endl;
302           break;
303         }
304 #endif
305         Hatcher.RemHatching (IndH);
306         continue;
307       }
308       
309       Standard_Integer NbDom = Hatcher.NbDomains (IndH);
310       if (NbDom > 0) {
311
312         for (Standard_Integer IDom = 1; IDom <= NbDom; IDom++) {
313           const HatchGen_Domain& Dom = Hatcher.Domain (IndH, IDom);
314           Standard_Real U1 = Dom.HasFirstPoint()  ? 
315             Dom.FirstPoint().Parameter()  : VMin - Infinite;
316           Standard_Real U2 = Dom.HasSecondPoint() ? 
317             Dom.SecondPoint().Parameter() : VMax + Infinite;
318           IsoLine->D0 (U1, P);
319           Surface.D0 (P.X(), P.Y(), P1);
320           IsoLine->D0 (U2, P);
321           Surface.D0 (P.X(), P.Y(), P2);
322           if (Dom.HasFirstPoint()) { // Iso V - Premier point
323             const HatchGen_PointOnHatching& PntH = Dom.FirstPoint();
324
325             for (Standard_Integer IPntE = 1; 
326                  IPntE <= PntH.NbPoints();
327                  IPntE++) {
328               const HatchGen_PointOnElement& PntE = PntH.Point(IPntE);
329               V1V = HLRTopoBRep_FaceIsoLiner::MakeVertex
330                 (TopoDS::Edge(SH(PntE.Index())),
331                  P1,PntE.Parameter(),Tolerance,DS);
332          
333      if (IL(PntE.Index())) DS.AddOutV(V1V);
334             }
335           }
336           if (Dom.HasSecondPoint()) { // Iso V - Deuxieme point
337             const HatchGen_PointOnHatching& PntH = Dom.SecondPoint();
338
339             for (Standard_Integer IPntE = 1;
340                  IPntE <= PntH.NbPoints();
341                  IPntE++) {
342               const HatchGen_PointOnElement& PntE = PntH.Point(IPntE);
343               V2V = HLRTopoBRep_FaceIsoLiner::MakeVertex
344                 (TopoDS::Edge(SH(PntE.Index())),
345                  P2,PntE.Parameter(),Tolerance,DS);
346               if (IL(PntE.Index())) DS.AddOutV(V2V);
347             }
348           }
349           if(!V1V.IsNull() && !V2V.IsNull())
350             HLRTopoBRep_FaceIsoLiner::MakeIsoLine
351               (F,IsoLine,V1V,V2V,U1,U2,Tolerance,DS);
352         }
353       }
354       
355       Hatcher.RemHatching (IndH);
356       VPrm += StepV;
357     }
358   }
359 }
360
361 //=======================================================================
362 //function : MakeVertex
363 //purpose  :
364 //=======================================================================
365
366 TopoDS_Vertex
367 HLRTopoBRep_FaceIsoLiner::MakeVertex (const TopoDS_Edge& E,
368                                       const gp_Pnt& P,
369                                       const Standard_Real Par,
370                                       const Standard_Real Tol,
371                                       HLRTopoBRep_Data& DS)
372 {
373   TopoDS_Vertex V, VF, VL;
374   BRep_Builder B;
375   TopExp::Vertices (E, VF, VL);
376   if (P.IsEqual(BRep_Tool::Pnt(VF),BRep_Tool::Tolerance(VF)))
377     return VF;
378   if (P.IsEqual(BRep_Tool::Pnt(VL),BRep_Tool::Tolerance(VL)))
379     return VL;
380
381   for (DS.InitVertex(E); DS.MoreVertex(); DS.NextVertex()) {
382     TopoDS_Vertex curV = DS.Vertex();
383     Standard_Real curP = DS.Parameter();
384     if (P.IsEqual(BRep_Tool::Pnt(curV),BRep_Tool::Tolerance(curV))) {
385       V = curV;
386       break;
387     }
388     else if (Par < curP) { 
389       B.MakeVertex(V,P,Tol);
390       V.Orientation(TopAbs_INTERNAL);
391       DS.InsertBefore(V,Par);
392       break;
393     }
394   }
395   
396   if (!DS.MoreVertex()) {
397     B.MakeVertex(V,P,Tol);
398     V.Orientation(TopAbs_INTERNAL);
399     DS.Append(V,Par);
400   }
401   
402   return V;
403 }
404
405 //=======================================================================
406 //function : MakeIsoLine
407 //purpose  :
408 //=======================================================================
409
410 void HLRTopoBRep_FaceIsoLiner::MakeIsoLine (const TopoDS_Face& F,
411                                             const Handle(Geom2d_Line)& Iso,
412                                             TopoDS_Vertex& V1,
413                                             TopoDS_Vertex& V2,
414                                             const Standard_Real U1,
415                                             const Standard_Real U2,
416                                             const Standard_Real Tol,
417                                             HLRTopoBRep_Data& DS)
418 {
419   BRep_Builder B;
420   TopoDS_Edge E;
421   E.Orientation (TopAbs_INTERNAL);
422   V1.Orientation (TopAbs_FORWARD);
423   V2.Orientation (TopAbs_REVERSED);
424   B.MakeEdge (E);
425   B.UpdateEdge (E, Iso, F, Tol);
426   B.Add (E, V1);
427   B.UpdateVertex (V1, U1, E, Tol);
428   B.Add (E, V2);
429   B.UpdateVertex (V2, U2, E, Tol);
430   DS.AddIsoL(F).Append(E);
431 }
432