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