0024624: Lost word in license statement in source files
[occt.git] / src / HatchGen / HatchGen_Hatcher.gxx
1 // Created on: 1993-11-04
2 // Created by: Jean Marc LACHAUME
3 // Copyright (c) 1993-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 <HatchGen_Domain.hxx>
18 #include <HatchGen_Domains.hxx>
19 #include <HatchGen_PointOnElement.hxx>
20 #include <HatchGen_PointOnHatching.hxx>
21 #include <IntRes2d_IntersectionPoint.hxx>
22 #include <IntRes2d_IntersectionSegment.hxx>
23 #include <IntRes2d_Transition.hxx>
24 #include <Precision.hxx>
25 #include <TopAbs.hxx>
26 #include <TopTrans_CurveTransition.hxx>
27
28 #define RAISE_IF_NOSUCHOBJECT 0
29 #define TRACE_HATCHER 0
30
31 //=======================================================================
32 //=======================================================================
33 //  Category : General use.
34 //=======================================================================
35 //=======================================================================
36
37 //=======================================================================
38 // Function : HatchGen_Hatcher
39 // Purpose  : Constructor.
40 //=======================================================================
41
42 HatchGen_Hatcher::HatchGen_Hatcher (const TheIntersector&  Intersector,
43                                     const Standard_Real    Confusion2d,
44                                     const Standard_Real    Confusion3d,
45                                     const Standard_Boolean KeepPnt,
46                                     const Standard_Boolean KeepSeg) :
47        myIntersector  (Intersector) ,
48        myConfusion2d  (Confusion2d) ,
49        myConfusion3d  (Confusion3d) ,
50        myKeepPoints   (KeepPnt) ,
51        myKeepSegments (KeepSeg) ,
52        myNbElements   (0) ,
53        myNbHatchings  (0) 
54 {
55 }
56
57 //=======================================================================
58 // Function : Intersector
59 // Purpose  : Sets the associated intersector.
60 //=======================================================================
61
62 void HatchGen_Hatcher::Intersector (const TheIntersector& Intersector)
63 {
64   myIntersector = Intersector ;
65   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
66     if (myHatchings.IsBound (IndH)) {
67       HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
68       Hatching.ClrPoints() ;
69     }
70   }
71 }
72
73
74 //=======================================================================
75 // Function : Confusion2d
76 // Purpose  : Sets the 2dconfusion tolerance.
77 //=======================================================================
78
79 void HatchGen_Hatcher::Confusion2d (const Standard_Real Confusion)
80 {
81   myConfusion2d = Confusion ;
82   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
83     if (myHatchings.IsBound (IndH)) {
84       HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
85       Hatching.ClrPoints() ;
86     }
87   }
88 }
89
90
91 //=======================================================================
92 // Function : Confusion3d
93 // Purpose  : Sets the 3d confusion tolerance.
94 //=======================================================================
95
96 void HatchGen_Hatcher::Confusion3d (const Standard_Real Confusion)
97 {
98   myConfusion3d = Confusion ;
99   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
100     if (myHatchings.IsBound (IndH)) {
101       HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
102       Hatching.ClrPoints() ;
103     }
104   }
105 }
106
107 //=======================================================================
108 // Function : KeepPoints
109 // Purpose  : Sets the above flag.
110 //=======================================================================
111
112 void HatchGen_Hatcher::KeepPoints (const Standard_Boolean Keep)
113 {
114   myKeepPoints = Keep ;
115   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
116     if (myHatchings.IsBound (IndH)) {
117       HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
118       Hatching.ClrDomains() ;
119     }
120   }
121 }
122
123
124 //=======================================================================
125 // Function : KeepSegments
126 // Purpose  : Sets the above flag.
127 //=======================================================================
128
129 void HatchGen_Hatcher::KeepSegments (const Standard_Boolean Keep)
130 {
131   myKeepSegments = Keep ;
132   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
133     if (myHatchings.IsBound (IndH)) {
134       HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
135       Hatching.ClrDomains() ;
136     }
137   }
138 }
139
140
141
142 //=======================================================================
143 //=======================================================================
144 //  Category : Element.
145 //=======================================================================
146 //=======================================================================
147
148
149 //=======================================================================
150 // Function : AddElement
151 // Purpose  : Adds an element to the Hatcher and returns its index.
152 //=======================================================================
153
154 Standard_Integer HatchGen_Hatcher::AddElement (const TheCurveE& Curve,
155                                                const TopAbs_Orientation Orientation)
156 {
157   Standard_Integer IndE ;
158   for (IndE = 1 ; IndE <= myNbElements && myElements.IsBound(IndE) ; IndE++) ;
159   if (IndE > myNbElements) {
160     myNbElements++ ;
161     IndE = myNbElements ;
162   }
163   HatchGen_Element Element (Curve, Orientation) ;
164   myElements.Bind (IndE, Element) ;
165   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings; IndH++) {
166     if (myHatchings.IsBound(IndH)) {
167       HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
168       Hatching.ClrPoints () ;
169     }
170   }
171   return IndE ;
172 }
173
174 //=======================================================================
175 // Function : RemElement
176 // Purpose  : Removes the IndE-th element from the hatcher.
177 //=======================================================================
178
179 void HatchGen_Hatcher::RemElement (const Standard_Integer IndE)
180 {
181 #if RAISE_IF_NOSUCHOBJECT
182   Standard_NoSuchObject_Raise_if (!myElements.IsBound (IndE), "") ;
183 #endif
184   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
185     if (myHatchings.IsBound (IndH)) {
186       HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
187       Standard_Boolean DomainsToClear = Standard_False ;
188       for (Standard_Integer IPntH = Hatching.NbPoints() ; IPntH > 0 ; IPntH--) {
189         HatchGen_PointOnHatching PntH = Hatching.ChangePoint (IPntH) ;
190         for (Standard_Integer IPntE = PntH.NbPoints() ; IPntE > 0 ; IPntE--) {
191           if (PntH.Point(IPntE).Index() == IndE) {
192             PntH.RemPoint (IPntE) ;
193             DomainsToClear = Standard_True ;
194           }
195         }
196         if (PntH.NbPoints() == 0) Hatching.RemPoint (IPntH) ;
197       }
198       if (DomainsToClear) Hatching.ClrDomains() ;
199     }
200   }
201   myElements.UnBind (IndE) ;
202   if (IndE == myNbElements) myNbElements-- ;
203 }
204
205 //=======================================================================
206 // Function : ClrElements
207 // Purpose  : Removes all the elements from the hatcher.
208 //=======================================================================
209
210 void HatchGen_Hatcher::ClrElements ()
211 {
212   if (myNbElements != 0) {
213     if (myNbHatchings != 0) {
214       for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
215         if (myHatchings.IsBound(IndH)) {
216           HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
217           Hatching.ClrPoints() ;
218         }
219       }
220     }
221     myElements.Clear() ;
222     myNbElements = 0 ;
223   }
224 }
225
226 //=======================================================================
227 //=======================================================================
228 //  Category : Hatching.
229 //=======================================================================
230 //=======================================================================
231
232
233 //=======================================================================
234 // Function : AddHatching
235 // Purpose  : Adds a hatching to the hatcher and returns its index.
236 //=======================================================================
237
238 Standard_Integer HatchGen_Hatcher::AddHatching (const TheCurveH& Curve)
239 {
240   Standard_Integer IndH ;
241   for (IndH = 1 ; IndH <= myNbHatchings && myHatchings.IsBound(IndH) ; IndH++) ;
242   if (IndH > myNbHatchings) {
243     myNbHatchings++ ;
244     IndH = myNbHatchings ;
245   }
246   HatchGen_Hatching Hatching (Curve) ;
247   myHatchings.Bind (IndH, Hatching) ;
248   return IndH ;
249 }
250
251 //=======================================================================
252 // Function : RemHatching
253 // Purpose  : Removes the IndH-th hatching from the hatcher.
254 //=======================================================================
255
256 void HatchGen_Hatcher::RemHatching (const Standard_Integer IndH)
257 {
258 #if RAISE_IF_NOSUCHOBJECT
259   Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
260 #endif
261   HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
262   Hatching.ClrPoints() ;
263   myHatchings.UnBind (IndH) ;
264   if (IndH == myNbHatchings) myNbHatchings-- ;
265 }
266   
267 //=======================================================================
268 // Function : ClrHatchings
269 // Purpose  : Removes all the hatchings from the hatcher.
270 //=======================================================================
271
272 void HatchGen_Hatcher::ClrHatchings ()
273 {
274   if (myNbHatchings != 0) {
275     for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
276       if (myHatchings.IsBound(IndH)) {
277         HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
278         Hatching.ClrPoints() ;
279       }
280     }
281     myHatchings.Clear() ;
282     myNbHatchings = 0 ;
283   }
284 }
285
286
287
288 //=======================================================================
289 //=======================================================================
290 //  Category : Computation - Trimming
291 //=======================================================================
292 //=======================================================================
293
294 //=======================================================================
295 // Function : Trim
296 // Purpose  : Trims all the hatchings of the hatcher by all the elements
297 //            of the hatcher.
298 //=======================================================================
299
300 void HatchGen_Hatcher::Trim ()
301 {
302   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++)
303     if (myHatchings.IsBound (IndH)) 
304       Trim (IndH) ;
305 }
306
307 //=======================================================================
308 // Function : Trim
309 // Purpose  : Adds a hatching to the hatcher and trims it by the elements
310 //            already given and returns its index.
311 //=======================================================================
312
313 Standard_Integer HatchGen_Hatcher::Trim (const TheCurveH& Curve)
314 {
315   Standard_Integer IndH = AddHatching (Curve) ;
316   Trim (IndH) ;
317   return IndH ;
318 }
319
320 //=======================================================================
321 // Function : Trim
322 // Purpose  : Trims the IndH-th hatching by the elements already given.
323 //=======================================================================
324
325 void HatchGen_Hatcher::Trim (const Standard_Integer IndH)
326 {
327 #if RAISE_IF_NOSUCHOBJECT
328   Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
329 #endif
330
331   HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
332
333   Hatching.ClrPoints() ;
334
335   Standard_Boolean OK, AllOK ;
336
337   AllOK = Standard_True ;
338   for (Standard_Integer IndE = 1 ; IndE <= myNbElements ; IndE++) {
339     if (myElements.IsBound (IndE)) {
340       OK = Trim (IndH, IndE) ;
341       AllOK = AllOK && OK ;
342     }
343   }
344   Hatching.TrimDone (Standard_True) ;
345   Hatching.TrimFailed (!AllOK) ;
346
347   if (AllOK) {
348     for (Standard_Integer IPnt = 1 ; IPnt <= Hatching.NbPoints() ; IPnt++) {
349       HatchGen_PointOnHatching& PntH = Hatching.ChangePoint(IPnt) ;
350       OK = GlobalTransition (PntH) ;
351       AllOK = AllOK && OK ;
352     }
353     Hatching.Status (AllOK ? HatchGen_NoProblem : HatchGen_TransitionFailure) ;
354   }
355 }
356
357 #if TRACE_HATCHER
358
359 //=======================================================================
360 // Function : IntersectionPointDump
361 // Purpose  : Dump of the intersection point.
362 //=======================================================================
363
364 static void IntersectionPointDump (const IntRes2d_IntersectionPoint& Pnt,
365                                    const Standard_Integer Index)
366 {
367   Standard_Integer SavedPrecision = cout.precision() ;
368   cout.precision (15) ;
369   cout << "----- IntRes2d:: Point # " << setw(3) << Index << " ---------------" << endl ;
370   cout << "-- U: "<<Pnt.Value().X()<<"    V: "<<Pnt.Value().Y()<<endl;
371   cout << "-- Parameter on first   : " << Pnt.ParamOnFirst()  << endl ;
372   cout << "-- Position  on first   : " ;
373   switch (Pnt.TransitionOfFirst().PositionOnCurve()) {
374       case IntRes2d_Head   : cout << "HEAD"   ; break ;
375       case IntRes2d_Middle : cout << "MIDDLE" ; break ;
376       case IntRes2d_End    : cout << "END"    ; break ;
377   }
378   cout << endl ;
379   cout << "-- IntRes2d:: Transition on first  : " ;
380   switch (Pnt.TransitionOfFirst().TransitionType()) {
381       case IntRes2d_In        : cout << "IN"        ; break ;
382       case IntRes2d_Out       : cout << "OUT"       ; break ;
383       case IntRes2d_Touch     : cout << "TOUCH"     ; break ;
384       case IntRes2d_Undecided : cout << "UNDECIDED" ; break ;
385   }
386   cout << endl ;
387   if (Pnt.TransitionOfFirst().TransitionType() == IntRes2d_Touch) {
388     cout << "-- IntRes2d:: Situation on first   : " ;
389     switch (Pnt.TransitionOfFirst().Situation()) {
390         case IntRes2d_Inside  : cout << "INSIDE"  ; break ;
391         case IntRes2d_Outside : cout << "OUTSIDE" ; break ;
392         case IntRes2d_Unknown : cout << "UNKNOWN" ; break ;
393     }
394     cout << endl ;
395   }
396   cout << "--------------------------------------------" << endl ;
397   cout << "-- Parameter on second  : " << Pnt.ParamOnSecond() << endl ;
398   cout << "-- Position  on second  : " ;
399   switch (Pnt.TransitionOfSecond().PositionOnCurve()) {
400       case IntRes2d_Head   : cout << "HEAD"   ; break ;
401       case IntRes2d_Middle : cout << "MIDDLE" ; break ;
402       case IntRes2d_End    : cout << "END"    ; break ;
403   }
404   cout << endl ;
405   cout << "-- IntRes2d:: Transition on second : " ;
406   switch (Pnt.TransitionOfSecond().TransitionType()) {
407       case IntRes2d_In        : cout << "IN"        ; break ;
408       case IntRes2d_Out       : cout << "OUT"       ; break ;
409       case IntRes2d_Touch     : cout << "TOUCH"     ; break ;
410       case IntRes2d_Undecided : cout << "UNDECIDED" ; break ;
411   }
412   cout << endl ;
413   if (Pnt.TransitionOfSecond().TransitionType() == IntRes2d_Touch) {
414     cout << "-- IntRes2d:: Situation on second  : " ;
415     switch (Pnt.TransitionOfSecond().Situation()) {
416         case IntRes2d_Inside  : cout << "INSIDE"  ; break ;
417         case IntRes2d_Outside : cout << "OUTSIDE" ; break ;
418         case IntRes2d_Unknown : cout << "UNKNOWN" ; break ;
419     }
420     cout << endl ;
421   }
422   cout << "--------------------------------------------" << endl ;
423   cout.precision (SavedPrecision) ;
424 }
425
426 #endif
427
428 //=======================================================================
429 // Function : Trim
430 // Purpose  : Trims the IndH-th hatching of the hatcher by the IndE th
431 //            element.
432 //=======================================================================
433
434 Standard_Boolean HatchGen_Hatcher::Trim (const Standard_Integer IndH,
435                                          const Standard_Integer IndE)
436 {
437 #if RAISE_IF_NOSUCHOBJECT
438   Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
439   Standard_NoSuchObject_Raise_if (!myElements.IsBound (IndE), "") ;
440 #endif
441
442   HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
443   HatchGen_Element& Element   = myElements.ChangeFind  (IndE) ;
444
445   TheCurveH hatching = Hatching.ChangeCurve() ;
446   TheCurveE element  = Element.ChangeCurve() ;
447
448   myIntersector.Intersect (hatching, element) ;
449   
450 #if TRACE_HATCHER
451   cout << "--- Hatcher - Trim:: Hatching # " << setw(3);
452   cout << IndH << " with Element # " << setw(3);
453   cout << IndE << " ----------" << endl ;
454 #endif    
455   
456   if (!myIntersector.IsDone())  { 
457     cout<<" Intersector -> Done = False ";
458     return Standard_False ;
459   }
460   
461 #if TRACE_HATCHER
462   if (myIntersector.IsEmpty()) {
463     cout << "No intersection" << endl ;
464     cout << "--------------------------------------------------------------------" << endl ;
465   }
466 #endif    
467   
468   if (myIntersector.IsEmpty()) return Standard_True ;
469   
470 #if TRACE_HATCHER
471   cout << "Number of intersection points   : " << setw(3) << (myIntersector.NbPoints())   << endl ;
472   cout << "Number of intersection segments : " << setw(3) << (myIntersector.NbSegments()) << endl ;
473 #endif    
474   
475   //-----------------------------------------------------------------------
476   // Traitement des points d intersection.
477   //-----------------------------------------------------------------------
478   
479   for (Standard_Integer IPntI = 1 ; IPntI <= myIntersector.NbPoints() ; IPntI++) {
480     const IntRes2d_IntersectionPoint& PntI = myIntersector.Point (IPntI) ;
481     
482 #if TRACE_HATCHER
483     IntersectionPointDump (PntI, IPntI) ;
484 #endif
485     
486     HatchGen_PointOnElement PntE (PntI) ;
487     PntE.SetIndex (IndE) ;
488     
489     HatchGen_PointOnHatching PntH (PntI) ;
490     PntH.SetIndex (IndH) ;
491     PntH.AddPoint (PntE, myConfusion2d) ;
492     
493     Hatching.AddPoint (PntH, myConfusion2d) ;
494   }
495   
496   //-----------------------------------------------------------------------
497   // Traitement des segments d intersection.
498   //-----------------------------------------------------------------------
499   
500   for (Standard_Integer ISeg = 1 ; ISeg <= myIntersector.NbSegments() ; ISeg++) {
501     
502     const IntRes2d_IntersectionSegment& Seg = myIntersector.Segment (ISeg) ;
503     
504 #if TRACE_HATCHER
505     cout << "----- Segment # " << setw(3) << ISeg << " -------------" << endl ;
506 #endif
507     
508     Standard_Boolean FirstPoint = Seg.HasFirstPoint() ;
509     Standard_Boolean LastPoint  = Seg.HasLastPoint() ;
510     
511     //-----------------------------------------------------------------------
512     // Les deux points peuvent etre confondus.
513     //-----------------------------------------------------------------------
514     
515     if (FirstPoint && LastPoint) {
516       
517       const IntRes2d_IntersectionPoint& Pnt1 = Seg.FirstPoint() ;
518       const IntRes2d_IntersectionPoint& Pnt2 = Seg.LastPoint()  ;
519       
520       const IntRes2d_Transition& TrsPnt1H = Pnt1.TransitionOfFirst() ;
521       const IntRes2d_Transition& TrsPnt1E = Pnt1.TransitionOfSecond() ;
522       const IntRes2d_Transition& TrsPnt2H = Pnt2.TransitionOfFirst() ;
523       const IntRes2d_Transition& TrsPnt2E = Pnt2.TransitionOfSecond() ;
524       
525       IntRes2d_TypeTrans TypePnt1H = TrsPnt1H.TransitionType() ;
526       IntRes2d_TypeTrans TypePnt1E = TrsPnt1E.TransitionType() ;
527       IntRes2d_TypeTrans TypePnt2H = TrsPnt2H.TransitionType() ;
528       IntRes2d_TypeTrans TypePnt2E = TrsPnt2E.TransitionType() ;
529       
530       //-----------------------------------------------------------------------
531       // Les deux points peuvent etre confondus au regard de la precision du
532       // `hatcher'.
533       //-----------------------------------------------------------------------
534       
535       Standard_Boolean Conf2d = Abs (Pnt1.ParamOnFirst() - Pnt2.ParamOnFirst()) <= myConfusion2d ;
536
537       //-----------------------------------------------------------------------
538       // Les deux points peuvent etre `confondus' au regard des intersections.
539       //-----------------------------------------------------------------------
540
541       Standard_Boolean Conf3d = Standard_False ;
542
543       if (!Conf2d) {
544         Conf3d = Standard_True ;
545         if (Conf3d) Conf3d = TypePnt1H != IntRes2d_Touch && TypePnt1H != IntRes2d_Undecided ;
546         if (Conf3d) Conf3d = TypePnt1E != IntRes2d_Touch && TypePnt1E != IntRes2d_Undecided ;
547         if (Conf3d) Conf3d = TypePnt2H != IntRes2d_Touch && TypePnt2H != IntRes2d_Undecided ;
548         if (Conf3d) Conf3d = TypePnt2E != IntRes2d_Touch && TypePnt2E != IntRes2d_Undecided ;
549         if (Conf3d) Conf3d = TypePnt1H == TypePnt2H      && TypePnt1E == TypePnt2E ;
550         if (Conf3d) Conf3d = Pnt1.Value().Distance (Pnt2.Value()) <= myConfusion3d ;
551       }
552
553       if (Conf2d || Conf3d) {
554         
555         HatchGen_PointOnElement PntE ;
556         PntE.SetIndex (IndE) ;
557         PntE.SetParameter ((Pnt1.ParamOnSecond() + Pnt2.ParamOnSecond()) / 2.) ;
558         switch (TrsPnt1E.PositionOnCurve()) {
559           case IntRes2d_Head: { 
560             PntE.SetPosition(TopAbs_FORWARD) ;
561             break ;
562           }
563           case IntRes2d_Middle: {
564             switch (TrsPnt2E.PositionOnCurve()) {
565                case IntRes2d_Head: {
566                  PntE.SetPosition (TopAbs_FORWARD);
567                  break;
568                }
569                case IntRes2d_Middle: { 
570                  PntE.SetPosition (TopAbs_INTERNAL) ;
571                  break ;
572                }
573                case IntRes2d_End: {
574                  PntE.SetPosition (TopAbs_REVERSED) ;
575                  break ;
576                }
577                default: {
578                  break;
579                }
580             }
581             break;
582           }
583           case IntRes2d_End:  { 
584             PntE.SetPosition(TopAbs_REVERSED) ;
585             break ;
586           }
587           default: {
588             break;
589           }
590         }
591         PntE.SetIntersectionType 
592           ((PntE.Position() == TopAbs_INTERNAL) ? HatchGen_TRUE : HatchGen_TOUCH) ;
593         PntE.SetStateBefore ((TypePnt1H == IntRes2d_In) ? TopAbs_OUT : TopAbs_IN) ;
594         PntE.SetStateAfter  ((TypePnt2H == IntRes2d_In) ? TopAbs_OUT : TopAbs_IN) ;
595         
596         HatchGen_PointOnHatching PntH ;
597         PntH.SetIndex (IndH) ;
598         PntH.SetParameter ((Pnt1.ParamOnFirst() + Pnt2.ParamOnFirst()) / 2.) ;
599         switch (TrsPnt1H.PositionOnCurve()) {
600            case IntRes2d_Head: {
601              PntH.SetPosition (TopAbs_FORWARD) ;
602              break ;
603            }
604            case IntRes2d_Middle: {
605              switch (TrsPnt2H.PositionOnCurve()) {
606                 case IntRes2d_Head: {
607                   PntH.SetPosition (TopAbs_FORWARD) ;
608                   break ;
609                 }
610                 case IntRes2d_Middle: {
611                   PntH.SetPosition (TopAbs_INTERNAL) ;
612                   break ;
613                 }
614                 case IntRes2d_End: {
615                   PntH.SetPosition (TopAbs_REVERSED) ;
616                   break ;
617                 }
618                 default : {
619                   break ;
620                 }
621              }
622              break ;
623            }
624            case IntRes2d_End: {
625              PntH.SetPosition (TopAbs_REVERSED) ;
626              break ;
627            }
628            default : {
629              break ;
630            }
631         }
632
633         PntH.AddPoint (PntE, myConfusion2d) ;
634         Hatching.AddPoint (PntH, myConfusion2d) ;
635         
636 #if TRACE_HATCHER
637         IntersectionPointDump (Pnt1, 1) ;
638         IntersectionPointDump (Pnt2, 2) ;
639         cout << "THESE TWO POINTS ARE "
640              << (Conf2d ? "2D" : "3D")
641              << " CONFUSED INTO THE FOLLOWING" << endl ;
642         PntH.Dump() ;
643 #endif
644         continue ;
645         
646       }
647       
648       //-----------------------------------------------------------------------
649       // Traitement du premier point du segment.
650       //-----------------------------------------------------------------------
651       
652       if (FirstPoint) {
653         
654         const IntRes2d_IntersectionPoint& PntI = Seg.FirstPoint() ;
655         
656 #if TRACE_HATCHER
657         IntersectionPointDump (PntI, 1) ;
658 #endif
659         
660         HatchGen_PointOnElement PntE (PntI) ;
661         PntE.SetIndex (IndE) ;
662         PntE.SetSegmentBeginning (Standard_True)  ;
663         PntE.SetSegmentEnd       (Standard_False) ;
664         
665         HatchGen_PointOnHatching PntH (PntI) ;
666         PntH.SetIndex (IndH) ;
667         PntH.AddPoint (PntE, myConfusion2d) ;
668         
669         Hatching.AddPoint (PntH, myConfusion2d) ;
670         
671 #if TRACE_HATCHER
672       } 
673       else {
674         cout << "----- Has no first point --------" << endl ;
675         cout << "---------------------------------" << endl ;
676 #endif
677         
678       }
679       
680       //-----------------------------------------------------------------------
681       // Traitement du deuxieme point du segment.
682       //-----------------------------------------------------------------------
683       
684       if (LastPoint) {
685         
686         const IntRes2d_IntersectionPoint& PntI = Seg.LastPoint() ;
687         
688 #if TRACE_HATCHER
689         IntersectionPointDump (PntI, 2) ;
690 #endif
691         
692         HatchGen_PointOnElement PntE (PntI) ;
693         PntE.SetIndex (IndE) ;
694         PntE.SetSegmentBeginning (Standard_False) ;
695         PntE.SetSegmentEnd       (Standard_True)  ;
696         
697         HatchGen_PointOnHatching PntH (PntI) ;
698         PntH.SetIndex (IndH) ;
699         PntH.AddPoint (PntE, myConfusion2d) ;
700         
701         Hatching.AddPoint (PntH, myConfusion2d) ;
702         
703 #if TRACE_HATCHER
704       } 
705       else {
706         cout << "----- Has no last point ---------" << endl ;
707         cout << "---------------------------------" << endl ;
708 #endif
709       }
710     }
711 #if TRACE_HATCHER
712     cout << "--------------------------------------------------------------------" << endl ;
713 #endif    
714     
715   }
716   return Standard_True;
717 }
718 //=======================================================================
719 //=======================================================================
720 //  Category : Computation - Domains
721 //=======================================================================
722 //=======================================================================
723
724 //=======================================================================
725 // Function : GlobalTransition
726 // Purpose  : Returns the before and after states of the complex
727 //            transition of the IndP-th intersection point of the
728 //            IndH-th hatching.
729 //=======================================================================
730
731 Standard_Boolean HatchGen_Hatcher::GlobalTransition (HatchGen_PointOnHatching& Point)
732 {
733   TopAbs_State StateBefore = TopAbs_UNKNOWN ;
734   TopAbs_State StateAfter  = TopAbs_UNKNOWN ;
735   Standard_Boolean SegmentBegin = Standard_False ;
736   Standard_Boolean SegmentEnd   = Standard_False ;
737
738   gp_Dir2d Tangente2d, Normale2d ;
739   gp_Dir   Tangente,   Normale ;
740   Standard_Real Courbure ;
741
742   const TheCurveH& CurveH = HatchingCurve (Point.Index()) ;
743
744   myIntersector.LocalGeometry(CurveH.Curve(), Point.Parameter(), Tangente2d, Normale2d, Courbure);
745
746   Tangente.SetCoord (Tangente2d.X(), Tangente2d.Y(), 0.0) ;
747   if (Courbure < Precision::Confusion()) {
748     Normale.SetCoord (-Tangente2d.Y(), Tangente2d.X(), 0.0) ;
749   } else {
750     Normale.SetCoord (Normale2d.X(), Normale2d.Y(), 0.0) ;
751   }
752
753   TopTrans_CurveTransition ComplexTransition ;
754   ComplexTransition.Reset (Tangente, Normale, Courbure) ;
755
756 #if TRACE_HATCHER
757   printf("\n ----- Global Transition Complex Transition Reset \n");
758   printf("\n       P:%+10.5g  Tg2d:%+10.5g , %+10.5g  N2d:%+10.5g , %+10.5g  Crv:%+10.5g\n\n",
759   Point.Parameter(),Tangente.X(),Tangente.Y(),Normale.X(),Normale.Y(),Courbure);
760 #endif
761   for (Standard_Integer IPntE = 1 ; IPntE <= Point.NbPoints() ; IPntE++) 
762   {
763     const HatchGen_PointOnElement& PntE = Point.Point (IPntE) ;
764     
765     SegmentBegin = SegmentBegin || PntE.SegmentBeginning() ;
766     SegmentEnd   = SegmentEnd   || PntE.SegmentEnd() ;
767     
768     const HatchGen_Element& Element = myElements.Find (PntE.Index()) ;
769     const TheCurveE& CurveE = Element.Curve() ;
770     
771     TopAbs_Orientation ElementOrientation = Element.Orientation() ;
772     Standard_Boolean ToReverse = (ElementOrientation == TopAbs_REVERSED);
773     Standard_Real Param ;
774     switch (PntE.Position()) 
775     {
776       case TopAbs_FORWARD  : 
777         Param = ToReverse ? CurveE.LastParameter() : CurveE.FirstParameter() ;
778         break ;
779
780       case TopAbs_INTERNAL : 
781         Param = PntE.Parameter() ;
782         break ;
783
784       case TopAbs_REVERSED : 
785         Param = ToReverse ? CurveE.FirstParameter() : CurveE.LastParameter() ;
786         break ;
787
788       default:
789         break;
790     }
791     
792 //-- 
793 #if TRACE_HATCHER
794     printf("\n ******** ToReverse: %d Param : %g   ANParam : %g \n",ToReverse,Param,PntE.Parameter());
795 #endif
796     Param = PntE.Parameter();
797
798     myIntersector.LocalGeometry(CurveE.Curve(), Param, Tangente2d, Normale2d, Courbure);
799
800 //-----------------------------------------------------------------------
801 // Calcul de la transition locale. On suppose les relations suivantes :
802 //  - Si l orientation de l element est INTERNAL ==> INTERNAL
803 //  - Si l orientation de l element est EXTERNAL ==> EXTERNAL
804 //  - Si tangence, on a IN-IN  ou OUT-OUT ==> INTERNAL/EXTERNAL
805 //  - Sinon,       on a IN-OUT ou OUT-IN  ==> REVERSED/FORWARD 
806 // Les deux dernieres conditions avec l element vu en FORWARD.    
807 //-----------------------------------------------------------------------
808     TopAbs_Orientation LocalTransition = TopAbs_EXTERNAL;
809
810     if (ElementOrientation == TopAbs_INTERNAL) 
811       LocalTransition = TopAbs_INTERNAL ;
812
813     else if (ElementOrientation == TopAbs_EXTERNAL) 
814       LocalTransition = TopAbs_EXTERNAL ;
815
816     else if (PntE.IntersectionType() == HatchGen_TANGENT) 
817     {
818       if (PntE.Position() == TopAbs_INTERNAL) 
819       {
820         switch (PntE.StateBefore()) 
821         {
822         case TopAbs_IN  : LocalTransition = ToReverse ? TopAbs_EXTERNAL : TopAbs_INTERNAL ; break ;
823         case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_INTERNAL : TopAbs_EXTERNAL ; break ;
824         default: break;
825         }
826       } 
827       else 
828       {
829         switch (PntE.StateBefore()) 
830         {
831         case TopAbs_IN  : LocalTransition = ToReverse ? TopAbs_FORWARD  : TopAbs_REVERSED ; break ;
832         case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD  ; break ;
833         default: break;
834         }
835       }
836     } 
837     else 
838     {
839       switch (PntE.StateBefore()) 
840       {
841       case TopAbs_IN  : LocalTransition = ToReverse ? TopAbs_FORWARD  : TopAbs_REVERSED ; break ;
842       case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD  ; break ;
843       default: break;
844       }
845     }
846
847 //-----------------------------------------------------------------------
848 // Orientation de la tangente au point d interference.
849 //-----------------------------------------------------------------------
850     TopAbs_Orientation TangenteOrientation = TopAbs_FORWARD;
851     switch (PntE.Position()) 
852     {
853     case TopAbs_FORWARD  : TangenteOrientation = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD  ; break ;
854     case TopAbs_INTERNAL : TangenteOrientation = TopAbs_INTERNAL ; break ;
855     case TopAbs_REVERSED : TangenteOrientation = ToReverse ? TopAbs_FORWARD  : TopAbs_REVERSED ; break ;
856     
857     default: 
858       break;
859     }
860
861 //-----------------------------------------------------------------------
862 // Proprietes geometriques.
863 //-----------------------------------------------------------------------
864
865     if (ToReverse) {
866       Tangente.SetCoord (-Tangente2d.X(), -Tangente2d.Y(), 0.0) ;
867     } else {
868       Tangente.SetCoord ( Tangente2d.X(),  Tangente2d.Y(), 0.0) ;
869     }
870     Normale.SetCoord ( Normale2d.X(),  Normale2d.Y(), 0.0) ;
871
872 #if TRACE_HATCHER
873     printf("\n \n----- Global Transition Complex Transition Compare" );
874     char *str1 = " ??? ";
875     char *str2 = " ??? ";
876     if(LocalTransition == TopAbs_INTERNAL) str1=" INTERNAL ";
877     if(LocalTransition == TopAbs_REVERSED) str1=" REVERSED ";
878     if(LocalTransition == TopAbs_FORWARD)  str1=" FORWARD  ";
879
880     if(TangenteOrientation == TopAbs_INTERNAL) str2=" INTERNAL ";
881     if(TangenteOrientation == TopAbs_REVERSED) str2=" REVERSED ";
882     if(TangenteOrientation == TopAbs_FORWARD)  str2=" FORWARD  ";
883
884     printf("\n       P:%+10.5g  Tg2d:%+10.5g , %+10.5g  N2d:%+10.5g , %+10.5g  Crv:%+10.5g LocalTr:%s TangOrie:%s\n",
885     Param,Tangente.X(),Tangente.Y(),Normale.X(),Normale.Y(),Courbure,str1,str2);
886 #endif
887
888     ComplexTransition.Compare (Precision::Angular(),
889                                Tangente, Normale, Courbure,
890                                LocalTransition, TangenteOrientation) ;
891   }
892
893   switch (ComplexTransition.StateBefore()) {
894       case TopAbs_IN      : StateBefore = TopAbs_IN  ; break ;
895       case TopAbs_OUT     : StateBefore = TopAbs_OUT ; break ;
896       case TopAbs_ON      : return Standard_False ;
897       case TopAbs_UNKNOWN : return Standard_False ;
898   }
899   switch (ComplexTransition.StateAfter()) {
900       case TopAbs_IN      : StateAfter = TopAbs_IN  ; break ;
901       case TopAbs_OUT     : StateAfter = TopAbs_OUT ; break ;
902       case TopAbs_ON      : return Standard_False ;
903       case TopAbs_UNKNOWN : return Standard_False ;
904   }
905
906
907 #if TRACE_HATCHER
908   printf("\n");
909   printf("\n --> StateBef :"); if(StateBefore==TopAbs_IN) printf(" IN "); else printf(" OUT ");
910   printf("\n --> StateAft :"); if(StateAfter==TopAbs_IN) printf(" IN "); else printf(" OUT ");
911   printf("\n------   Fin GlobalTransition\n");
912 #endif
913   
914   Point.SetStateBefore      (StateBefore) ;
915   Point.SetStateAfter       (StateAfter) ;
916   Point.SetSegmentBeginning (SegmentBegin) ;
917   Point.SetSegmentEnd       (SegmentEnd) ;
918   return Standard_True ;
919 }
920
921 //=======================================================================
922 // Function : ComputeDomains
923 // Purpose  : Computes the domains of all the hatchings.
924 //=======================================================================
925
926 void HatchGen_Hatcher::ComputeDomains ()
927 {
928   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++)
929     if (myHatchings.IsBound (IndH)) ComputeDomains (IndH) ;
930 }
931
932 //=======================================================================
933 // Function : ComputeDomains
934 // Purpose  : Computes the domains of the IndH-th hatching.
935 //=======================================================================
936
937 void HatchGen_Hatcher::ComputeDomains (const Standard_Integer IndH)
938 {
939 #if RAISE_IF_NOSUCHOBJECT
940   Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
941 #endif
942   
943   HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
944   Hatching.ClrDomains() ;
945
946   Hatching.IsDone (Standard_False) ;
947
948   if (!Hatching.TrimDone()) Trim (IndH) ;
949   if (Hatching.Status() != HatchGen_NoProblem) return ;
950   
951   Standard_Boolean Points   = myKeepPoints ;
952   Standard_Boolean Segments = myKeepSegments ;
953   Standard_Integer ISav = 0 ;
954   Standard_Boolean SavPnt  = Standard_False ;
955   Standard_Integer NbOpenedSegments = 0 ;
956   Standard_Integer NbPnt = Hatching.NbPoints() ;
957   Standard_Integer IPnt =1;
958
959   if (NbPnt == 0) {
960     //-- cout << "The hatching # " << setw(3) << IndH << " has to be classified" << endl ;
961     HatchGen_Classifier Classifier(myElements,Hatching.ClassificationPoint(),0.0000001); 
962     if(Classifier.State() == TopAbs_IN) { 
963       HatchGen_Domain domain ;
964       Hatching.AddDomain (domain) ;
965     }
966     Hatching.IsDone (Standard_True) ;
967     return ;
968   }
969   
970 //for (Standard_Integer IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
971   for (IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
972     Standard_Boolean NoDomain   = Hatching.NbDomains() == 0 ; 
973     Standard_Boolean FirstPoint = IPnt ==     1 ;
974     Standard_Boolean LastPoint  = IPnt == NbPnt ;
975
976     const HatchGen_PointOnHatching& CurPnt = Hatching.Point (IPnt) ;
977
978 #if TRACE_HATCHER
979     cout << "===== ComputeDomains:: Hatching # " << setw(3) << IndH << " =====" << endl ;
980     CurPnt.Dump (IPnt) ;
981     cout << "==========================================" << endl ;
982 #endif
983     
984     
985 //-----------------------------------------------------------------------
986 // Calcul des domaines.
987 //-----------------------------------------------------------------------
988
989     TopAbs_State     StateBefore  = CurPnt.StateBefore() ;
990     TopAbs_State     StateAfter   = CurPnt.StateAfter() ;
991     Standard_Boolean SegmentBegin = CurPnt.SegmentBeginning() ;
992     Standard_Boolean SegmentEnd   = CurPnt.SegmentEnd() ;
993
994     HatchGen_Domain domain ;
995
996 //-----------------------------------------------------------------------
997 // Initialisations dues au premier point.
998 //-----------------------------------------------------------------------
999
1000     if (FirstPoint) {
1001       SavPnt  = Standard_False ;
1002       ISav = 0 ;
1003       NbOpenedSegments = 0 ;
1004       if (SegmentEnd && SegmentBegin) {
1005         if (StateAfter  == TopAbs_UNKNOWN) StateAfter  = TopAbs_IN ;
1006         if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1007         if (Segments) {
1008           SavPnt  = Standard_True ;
1009           ISav = 0 ;
1010         }
1011       } else if (SegmentEnd) {
1012         if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1013         if (Segments) {
1014           SavPnt  = Standard_True ;
1015           ISav = 0 ;
1016         }
1017       } else if (SegmentBegin) {
1018         if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1019         if (StateBefore == TopAbs_IN) {
1020           SavPnt  = Standard_True ;
1021           ISav = 0 ;
1022         }
1023       } else {
1024         if (StateBefore == TopAbs_IN) {
1025           SavPnt  = Standard_True ;
1026           ISav = 0 ;
1027         }
1028       }
1029     }
1030
1031 //-----------------------------------------------------------------------
1032 // Initialisations dues au dernier point.
1033 //-----------------------------------------------------------------------
1034
1035     if (LastPoint) {
1036       if (SegmentEnd && SegmentBegin) {
1037         if (StateAfter  == TopAbs_UNKNOWN) StateAfter  = TopAbs_IN ;
1038         if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1039       } else if (SegmentEnd) {
1040         if (StateAfter  == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1041       } else if (SegmentBegin) {
1042         if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1043       } else {
1044       }
1045     }
1046     
1047 //-----------------------------------------------------------------------
1048 // Cas general.
1049 //-----------------------------------------------------------------------
1050
1051     Standard_Boolean ToAppend = Standard_False ;
1052
1053     if (SegmentEnd && SegmentBegin) {
1054
1055       if (StateBefore != TopAbs_IN && StateAfter != TopAbs_IN) {
1056         Hatching.Status (HatchGen_IncompatibleStates) ;
1057         return ;
1058       }
1059       if (Points) {
1060         if (Segments) {
1061           if (!SavPnt) {
1062             if(NoDomain) { 
1063               Hatching.Status (HatchGen_IncoherentParity) ;
1064             }
1065             else { 
1066               Hatching.IsDone(Standard_True);
1067             }
1068             return ;
1069           }
1070           if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1071           domain.SetSecondPoint (CurPnt) ;
1072           ToAppend = Standard_True ;
1073           SavPnt = Standard_True ;
1074           ISav = IPnt ;
1075         } else {
1076           Standard_Boolean isININ = (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN);
1077           if (SavPnt && !isININ) {
1078             if(NoDomain) { 
1079               Hatching.Status (HatchGen_IncoherentParity) ;
1080             }
1081             else { 
1082               Hatching.IsDone(Standard_True);
1083             }
1084             return ;
1085           }
1086           domain.SetPoints (CurPnt, CurPnt) ;
1087           ToAppend = Standard_True ;
1088           SavPnt = Standard_False ;
1089           ISav = 0 ;
1090         }
1091       }
1092           
1093     } else if (SegmentEnd) {
1094
1095       if (Segments) {
1096         if (StateAfter == TopAbs_OUT) {
1097           if (!SavPnt) {
1098             if(NoDomain) { 
1099               Hatching.Status (HatchGen_IncoherentParity) ;
1100             }
1101             else { 
1102               Hatching.IsDone(Standard_True);
1103             }
1104             return ;
1105           }
1106           if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1107           domain.SetSecondPoint (CurPnt) ;
1108           ToAppend = Standard_True ;
1109         } else {
1110           if (Points) {
1111             if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1112             domain.SetSecondPoint (CurPnt) ;
1113             ToAppend = Standard_True ;
1114             SavPnt = Standard_True ;
1115             ISav = IPnt ;
1116           }
1117         }
1118       } else {
1119         if (StateAfter == TopAbs_IN) {
1120           SavPnt = Standard_True ;
1121           ISav = IPnt ;
1122         }
1123       }
1124       NbOpenedSegments-- ;
1125       
1126     } else if (SegmentBegin) {
1127
1128       if (Segments) {
1129         if (StateBefore == TopAbs_OUT) {
1130           SavPnt = Standard_True ;
1131           ISav = IPnt ;
1132         } else {
1133           if (Points) {
1134             if (!SavPnt) {
1135               if(NoDomain) { 
1136                 Hatching.Status (HatchGen_IncoherentParity) ;
1137               }
1138               else { 
1139                 Hatching.IsDone(Standard_True);
1140               }
1141               
1142               return ;
1143             }
1144             if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1145             domain.SetSecondPoint (CurPnt) ;
1146             ToAppend = Standard_True ;
1147             SavPnt = Standard_True ;
1148             ISav = IPnt ;
1149           }
1150         }
1151       } else {
1152         if (StateBefore == TopAbs_IN) {
1153           if (!SavPnt) {
1154             if(NoDomain) { 
1155               Hatching.Status (HatchGen_IncoherentParity) ;
1156             }
1157             else { 
1158               Hatching.IsDone(Standard_True);
1159             }
1160             
1161             return ;
1162           }
1163           if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1164           domain.SetSecondPoint (CurPnt) ;
1165           ToAppend = Standard_True ;
1166 //  Modified by Sergey KHROMOV - Fri Jan  5 12:05:30 2001
1167 //        SavPnt = Standard_False ;
1168 //        ISav = 0 ;
1169           SavPnt = Standard_True ;
1170           ISav = IPnt ;
1171 //  Modified by Sergey KHROMOV - Fri Jan  5 12:05:31 2001
1172         }
1173       }
1174       NbOpenedSegments++ ;
1175       
1176     } else {
1177       //-- ???????????????????????????????????????????????????????????????????????????
1178       //-- Solution provisoire (lbr le 11 Aout 97 )
1179       //-- si On a 2 points dont des points OUT OUT ou IN IN qui delimitent une isos
1180       //-- on transforme les transitions 
1181       if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
1182         if(NbPnt == 2) { 
1183           if(FirstPoint) 
1184             StateAfter  = TopAbs_IN; 
1185           else
1186             StateBefore = TopAbs_IN; 
1187         }
1188       }
1189        //-- ???????????????????????????????????????????????????????????????????????????
1190       if        (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
1191
1192         if (SavPnt) {
1193           if(NoDomain) { 
1194             Hatching.Status (HatchGen_IncoherentParity) ;
1195           }
1196           else { 
1197             Hatching.IsDone(Standard_True);
1198           }
1199           
1200           return ;
1201         }
1202         if (Points) {
1203           domain.SetPoints (CurPnt, CurPnt) ;
1204           ToAppend = Standard_True ;
1205           SavPnt = Standard_True ;
1206           ISav = IPnt ;
1207         }
1208
1209       } else if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_IN ) {
1210
1211         SavPnt = Standard_True ;
1212         ISav = IPnt ;
1213
1214       } else if (StateBefore == TopAbs_IN  && StateAfter == TopAbs_OUT) {
1215
1216         if (!SavPnt) {
1217           if(NoDomain) { 
1218             Hatching.Status (HatchGen_IncoherentParity) ;
1219           }
1220           else { 
1221             Hatching.IsDone(Standard_True);
1222           }
1223           
1224           return ;
1225         }
1226         if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1227         domain.SetSecondPoint (CurPnt) ;
1228         ToAppend = Standard_True ;
1229         SavPnt = Standard_False ;
1230         ISav = 0 ;
1231
1232       } else if (StateBefore == TopAbs_IN  && StateAfter == TopAbs_IN ) {
1233
1234         if (Points) {
1235           if (NbOpenedSegments == 0) {
1236             if (!SavPnt) {
1237               if(NoDomain) { 
1238                 Hatching.Status (HatchGen_IncoherentParity) ;
1239               }
1240               else { 
1241                 Hatching.IsDone(Standard_True);
1242               }
1243               
1244               return ;
1245             }
1246             if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1247             domain.SetSecondPoint (CurPnt) ;
1248             ToAppend = Standard_True ;
1249             SavPnt = Standard_True ;
1250             ISav = IPnt ;
1251           } else {
1252             if (Segments) {
1253               if (!SavPnt) {
1254                 if(NoDomain) { 
1255                   Hatching.Status (HatchGen_IncoherentParity) ;
1256                 }
1257                 else { 
1258                   Hatching.IsDone(Standard_True);
1259                 }
1260
1261                 return ;
1262               }
1263               if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1264               domain.SetSecondPoint (CurPnt) ;
1265               ToAppend = Standard_True ;
1266               SavPnt = Standard_True ;
1267               ISav = IPnt ;
1268             } else {
1269               if (SavPnt) {
1270                 if(NoDomain) { 
1271                   Hatching.Status (HatchGen_IncoherentParity) ;
1272                 }
1273                 else { 
1274                   Hatching.IsDone(Standard_True);
1275                 }
1276                 
1277                 return ;
1278               }
1279               domain.SetPoints (CurPnt, CurPnt) ;
1280               ToAppend = Standard_True ;
1281               SavPnt = Standard_False ;
1282               ISav = 0 ;
1283             }
1284           }
1285         }
1286
1287       } else {
1288
1289         Hatching.Status (HatchGen_IncompatibleStates) ;
1290         return ;
1291
1292       }
1293         
1294     }
1295
1296 //-----------------------------------------------------------------------
1297 // Ajout du domaine.
1298 //-----------------------------------------------------------------------
1299
1300     if (ToAppend) Hatching.AddDomain (domain) ;
1301     
1302 //-----------------------------------------------------------------------
1303 // Traitement lie au dernier point.
1304 //-----------------------------------------------------------------------
1305
1306     if (LastPoint) {
1307       
1308       domain.SetPoints () ;
1309       ToAppend = Standard_False ;
1310       
1311       if (SegmentEnd && SegmentBegin) {
1312         
1313         if (Segments) {
1314           if (!SavPnt) {
1315             if(NoDomain) { 
1316               Hatching.Status (HatchGen_IncoherentParity) ;
1317             }
1318             else { 
1319               Hatching.IsDone(Standard_True);
1320             }
1321             
1322             return ;
1323           }
1324           if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1325           ToAppend = Standard_True ;
1326         }
1327         
1328       } else if (SegmentEnd) {
1329
1330         if (StateAfter == TopAbs_IN) {
1331           if (!SavPnt) {
1332             if(NoDomain) { 
1333               Hatching.Status (HatchGen_IncoherentParity) ;
1334             }
1335             else { 
1336               Hatching.IsDone(Standard_True);
1337             }
1338             
1339             return ;
1340           }
1341           if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1342           ToAppend = Standard_True ;
1343         }
1344         
1345       } else if (SegmentBegin) {
1346         
1347         if (Segments) {
1348           if (!SavPnt) {
1349             if(NoDomain) { 
1350               Hatching.Status (HatchGen_IncoherentParity) ;
1351             }
1352             else { 
1353               Hatching.IsDone(Standard_True);
1354             }
1355             
1356             return ;
1357           }
1358           if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1359           ToAppend = Standard_True ;
1360         }
1361
1362       } else {
1363         
1364         if (StateAfter == TopAbs_IN) {
1365           if (!SavPnt) {
1366             if(NoDomain) { 
1367               Hatching.Status (HatchGen_IncoherentParity) ;
1368             }
1369             else { 
1370               Hatching.IsDone(Standard_True);
1371             }
1372             
1373             return ;
1374           }
1375           if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1376           ToAppend = Standard_True ;
1377         }
1378
1379       }
1380       if (ToAppend) Hatching.AddDomain (domain) ;
1381     }
1382     
1383   }
1384   Hatching.IsDone(Standard_True) ;
1385 }
1386
1387 //=======================================================================
1388 //=======================================================================
1389 //  Category : Results.
1390 //=======================================================================
1391 //=======================================================================
1392
1393
1394 //=======================================================================
1395 // Function : Domain
1396 // Purpose  : Returns the IDom-th domain of the IndH-th hatching.
1397 //=======================================================================
1398
1399 const HatchGen_Domain& HatchGen_Hatcher::Domain (const Standard_Integer IndH,
1400                                                  const Standard_Integer IDom) const
1401 {
1402 #if RAISE_IF_NOSUCHOBJECT
1403   Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
1404 #endif
1405   const HatchGen_Hatching& Hatching = myHatchings.Find (IndH) ;
1406   StdFail_NotDone_Raise_if (!Hatching.IsDone(), "HatchGen_Hatcher::Domain") ;
1407 #if RAISE_IF_NOSUCHOBJECT
1408   Standard_OutOfRange_Raise_if (IDom < 1 || IDom > Hatching.NbDomains(), "") ;
1409 #endif
1410   const HatchGen_Domain& Domain = Hatching.Domain (IDom) ;
1411   return Domain ;
1412 }
1413
1414 //=======================================================================
1415 //=======================================================================
1416 //  Category : Dump.
1417 //=======================================================================
1418 //=======================================================================
1419
1420 //=======================================================================
1421 // Function : Dump
1422 // Purpose  : Dumps the hatcher.
1423 //=======================================================================
1424
1425 void HatchGen_Hatcher::Dump () const
1426 {
1427   cout << endl ;
1428   cout << "========================================================" << endl ;
1429   cout << "=== Dump of the hatcher ================================" << endl ;
1430   cout << "========================================================" << endl ;
1431   cout << endl ;
1432
1433   cout << "The points   are "
1434        << (myKeepPoints   ? "    " : "not ")
1435        << "considered."
1436        << endl ;
1437   cout << "The segments are "
1438        << (myKeepSegments ? "    " : "not ")
1439        << "considered."
1440        << endl ;
1441   cout << "2D Confusion tolerance : " << myConfusion2d << endl ;
1442   cout << "3D Confusion tolerance : " << myConfusion3d << endl ;
1443   
1444   cout << myNbHatchings
1445        << " hatching"
1446        << ((myNbHatchings == 1) ? "" : "s")
1447        << endl ;
1448   cout << myNbElements
1449        << " element"
1450        << ((myNbElements  == 1) ? "" : "s")
1451        << endl ;
1452   
1453   cout << endl ;
1454   cout << "========================================================" << endl ;
1455   cout << "=== Hatchings ==========================================" << endl ;
1456   cout << "========================================================" << endl ;
1457   cout << endl ;
1458   
1459   for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
1460     cout << "Hatching # " << IndH ;
1461     if (!myHatchings.IsBound (IndH)) {
1462       cout << " is not bound" << endl ;
1463     } else {
1464       const HatchGen_Hatching& Hatching = myHatchings.Find (IndH) ;
1465       Standard_Integer NbPnt = Hatching.NbPoints() ;
1466       cout << " contains " << NbPnt << " restriction points :"  << endl ;
1467       for (Standard_Integer IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
1468         const HatchGen_PointOnHatching& PntH = Hatching.Point (IPnt) ;
1469         PntH.Dump (IPnt) ;
1470       }
1471       cout << "----------------------------------------------" << endl ;
1472     }
1473   }
1474
1475   cout << endl ;
1476   cout << "========================================================" << endl ;
1477   cout << "=== Elements ===========================================" << endl ;
1478   cout << "========================================================" << endl ;
1479   cout << endl ;
1480   
1481   for (Standard_Integer IndE = 1 ; IndE <= myNbElements ; IndE++) {
1482     cout << "Element # " << IndE ;
1483     if (!myElements.IsBound (IndE)) {
1484       cout << " is not bound" << endl ;
1485     } else {
1486       const HatchGen_Element& Element = myElements.Find (IndE) ;
1487       switch (Element.Orientation()) {
1488         case TopAbs_FORWARD  : cout << " is FORWARD"  << endl ; break ;
1489         case TopAbs_REVERSED : cout << " is REVERSED" << endl ; break ;
1490         case TopAbs_INTERNAL : cout << " is INTERNAL" << endl ; break ;
1491         case TopAbs_EXTERNAL : cout << " is EXTERNAL" << endl ; break ;
1492       }
1493     }
1494   }
1495
1496   cout << endl ;
1497 }