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