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