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