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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Geom2dHatch_Hatcher.ixx>
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>
28 #include <TopTrans_CurveTransition.hxx>
30 #include <Geom2dAdaptor_Curve.hxx>
31 #include <Geom2dHatch_Intersector.hxx>
32 #include <Geom2dHatch_Classifier.hxx>
34 #define RAISE_IF_NOSUCHOBJECT 0
35 #define TRACE_HATCHER 0
37 //=======================================================================
38 //=======================================================================
39 // Category : General use.
40 //=======================================================================
41 //=======================================================================
43 //=======================================================================
44 // Function : Geom2dHatch_Hatcher
45 // Purpose : Constructor.
46 //=======================================================================
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) ,
63 //=======================================================================
64 // Function : Intersector
65 // Purpose : Sets the associated intersector.
66 //=======================================================================
68 void Geom2dHatch_Hatcher::Intersector (const Geom2dHatch_Intersector& Intersector)
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() ;
80 //=======================================================================
81 // Function : Confusion2d
82 // Purpose : Sets the 2dconfusion tolerance.
83 //=======================================================================
85 void Geom2dHatch_Hatcher::Confusion2d (const Standard_Real Confusion)
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() ;
97 //=======================================================================
98 // Function : Confusion3d
99 // Purpose : Sets the 3d confusion tolerance.
100 //=======================================================================
102 void Geom2dHatch_Hatcher::Confusion3d (const Standard_Real Confusion)
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() ;
113 //=======================================================================
114 // Function : KeepPoints
115 // Purpose : Sets the above flag.
116 //=======================================================================
118 void Geom2dHatch_Hatcher::KeepPoints (const Standard_Boolean Keep)
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() ;
130 //=======================================================================
131 // Function : KeepSegments
132 // Purpose : Sets the above flag.
133 //=======================================================================
135 void Geom2dHatch_Hatcher::KeepSegments (const Standard_Boolean Keep)
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() ;
148 //=======================================================================
149 //=======================================================================
150 // Category : Element.
151 //=======================================================================
152 //=======================================================================
155 //=======================================================================
156 // Function : AddElement
157 // Purpose : Adds an element to the Hatcher and returns its index.
158 //=======================================================================
160 Standard_Integer Geom2dHatch_Hatcher::AddElement (const Geom2dAdaptor_Curve& Curve,
161 const TopAbs_Orientation Orientation)
163 Standard_Integer IndE ;
164 for (IndE = 1 ; IndE <= myNbElements && myElements.IsBound(IndE) ; IndE++) ;
165 if (IndE > myNbElements) {
167 IndE = myNbElements ;
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 () ;
180 //=======================================================================
181 // Function : RemElement
182 // Purpose : Removes the IndE-th element from the hatcher.
183 //=======================================================================
185 void Geom2dHatch_Hatcher::RemElement (const Standard_Integer IndE)
187 #if RAISE_IF_NOSUCHOBJECT
188 Standard_NoSuchObject_Raise_if (!myElements.IsBound (IndE), "") ;
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 ;
202 if (PntH.NbPoints() == 0) Hatching.RemPoint (IPntH) ;
204 if (DomainsToClear) Hatching.ClrDomains() ;
207 myElements.UnBind (IndE) ;
208 if (IndE == myNbElements) myNbElements-- ;
211 //=======================================================================
212 // Function : ClrElements
213 // Purpose : Removes all the elements from the hatcher.
214 //=======================================================================
216 void Geom2dHatch_Hatcher::ClrElements ()
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() ;
232 //=======================================================================
233 //=======================================================================
234 // Category : Hatching.
235 //=======================================================================
236 //=======================================================================
239 //=======================================================================
240 // Function : AddHatching
241 // Purpose : Adds a hatching to the hatcher and returns its index.
242 //=======================================================================
244 Standard_Integer Geom2dHatch_Hatcher::AddHatching (const Geom2dAdaptor_Curve& Curve)
246 Standard_Integer IndH ;
247 for (IndH = 1 ; IndH <= myNbHatchings && myHatchings.IsBound(IndH) ; IndH++) ;
248 if (IndH > myNbHatchings) {
250 IndH = myNbHatchings ;
252 Geom2dHatch_Hatching Hatching (Curve) ;
253 myHatchings.Bind (IndH, Hatching) ;
257 //=======================================================================
258 // Function : RemHatching
259 // Purpose : Removes the IndH-th hatching from the hatcher.
260 //=======================================================================
262 void Geom2dHatch_Hatcher::RemHatching (const Standard_Integer IndH)
264 #if RAISE_IF_NOSUCHOBJECT
265 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
267 Geom2dHatch_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
268 Hatching.ClrPoints() ;
269 myHatchings.UnBind (IndH) ;
270 if (IndH == myNbHatchings) myNbHatchings-- ;
273 //=======================================================================
274 // Function : ClrHatchings
275 // Purpose : Removes all the hatchings from the hatcher.
276 //=======================================================================
278 void Geom2dHatch_Hatcher::ClrHatchings ()
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() ;
287 myHatchings.Clear() ;
294 //=======================================================================
295 //=======================================================================
296 // Category : Computation - Trimming
297 //=======================================================================
298 //=======================================================================
300 //=======================================================================
302 // Purpose : Trims all the hatchings of the hatcher by all the elements
304 //=======================================================================
306 void Geom2dHatch_Hatcher::Trim ()
308 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++)
309 if (myHatchings.IsBound (IndH))
313 //=======================================================================
315 // Purpose : Adds a hatching to the hatcher and trims it by the elements
316 // already given and returns its index.
317 //=======================================================================
319 Standard_Integer Geom2dHatch_Hatcher::Trim (const Geom2dAdaptor_Curve& Curve)
321 Standard_Integer IndH = AddHatching (Curve) ;
326 //=======================================================================
328 // Purpose : Trims the IndH-th hatching by the elements already given.
329 //=======================================================================
331 void Geom2dHatch_Hatcher::Trim (const Standard_Integer IndH)
333 #if RAISE_IF_NOSUCHOBJECT
334 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
337 Geom2dHatch_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
339 Hatching.ClrPoints() ;
341 Standard_Boolean OK, AllOK ;
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 ;
350 Hatching.TrimDone (Standard_True) ;
351 Hatching.TrimFailed (!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 ;
359 Hatching.Status (AllOK ? HatchGen_NoProblem : HatchGen_TransitionFailure) ;
365 //=======================================================================
366 // Function : IntersectionPointDump
367 // Purpose : Dump of the intersection point.
368 //=======================================================================
370 static void IntersectionPointDump (const IntRes2d_IntersectionPoint& Pnt,
371 const Standard_Integer Index)
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 ;
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 ;
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 ;
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 ;
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 ;
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 ;
428 cout << "--------------------------------------------" << endl ;
429 cout.precision (SavedPrecision) ;
434 //=======================================================================
436 // Purpose : Trims the IndH-th hatching of the hatcher by the IndE th
438 //=======================================================================
440 Standard_Boolean Geom2dHatch_Hatcher::Trim (const Standard_Integer IndH,
441 const Standard_Integer IndE)
443 #if RAISE_IF_NOSUCHOBJECT
444 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
445 Standard_NoSuchObject_Raise_if (!myElements.IsBound (IndE), "") ;
448 Geom2dHatch_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
449 Geom2dHatch_Element& Element = myElements.ChangeFind (IndE) ;
451 Geom2dAdaptor_Curve hatching = Hatching.ChangeCurve() ;
452 Geom2dAdaptor_Curve element = Element.ChangeCurve() ;
454 myIntersector.Intersect (hatching, element) ;
457 cout << "--- Hatcher - Trim:: Hatching # " << setw(3);
458 cout << IndH << " with Element # " << setw(3);
459 cout << IndE << " ----------" << endl ;
462 if (!myIntersector.IsDone()) {
463 cout<<" Intersector -> Done = False ";
464 return Standard_False ;
468 if (myIntersector.IsEmpty()) {
469 cout << "No intersection" << endl ;
470 cout << "--------------------------------------------------------------------" << endl ;
474 if (myIntersector.IsEmpty()) return Standard_True ;
477 cout << "Number of intersection points : " << setw(3) << (myIntersector.NbPoints()) << endl ;
478 cout << "Number of intersection segments : " << setw(3) << (myIntersector.NbSegments()) << endl ;
481 //-----------------------------------------------------------------------
482 // Traitement des points d intersection.
483 //-----------------------------------------------------------------------
485 for (Standard_Integer IPntI = 1 ; IPntI <= myIntersector.NbPoints() ; IPntI++) {
486 const IntRes2d_IntersectionPoint& PntI = myIntersector.Point (IPntI) ;
489 IntersectionPointDump (PntI, IPntI) ;
492 HatchGen_PointOnElement PntE (PntI) ;
493 PntE.SetIndex (IndE) ;
495 HatchGen_PointOnHatching PntH (PntI) ;
496 PntH.SetIndex (IndH) ;
497 PntH.AddPoint (PntE, myConfusion2d) ;
499 Hatching.AddPoint (PntH, myConfusion2d) ;
502 //-----------------------------------------------------------------------
503 // Traitement des segments d intersection.
504 //-----------------------------------------------------------------------
506 for (Standard_Integer ISeg = 1 ; ISeg <= myIntersector.NbSegments() ; ISeg++) {
508 const IntRes2d_IntersectionSegment& Seg = myIntersector.Segment (ISeg) ;
511 cout << "----- Segment # " << setw(3) << ISeg << " -------------" << endl ;
514 Standard_Boolean FirstPoint = Seg.HasFirstPoint() ;
515 Standard_Boolean LastPoint = Seg.HasLastPoint() ;
517 //-----------------------------------------------------------------------
518 // Les deux points peuvent etre confondus.
519 //-----------------------------------------------------------------------
521 if (FirstPoint && LastPoint) {
523 const IntRes2d_IntersectionPoint& Pnt1 = Seg.FirstPoint() ;
524 const IntRes2d_IntersectionPoint& Pnt2 = Seg.LastPoint() ;
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() ;
531 IntRes2d_TypeTrans TypePnt1H = TrsPnt1H.TransitionType() ;
532 IntRes2d_TypeTrans TypePnt1E = TrsPnt1E.TransitionType() ;
533 IntRes2d_TypeTrans TypePnt2H = TrsPnt2H.TransitionType() ;
534 IntRes2d_TypeTrans TypePnt2E = TrsPnt2E.TransitionType() ;
536 //-----------------------------------------------------------------------
537 // Les deux points peuvent etre confondus au regard de la precision du
539 //-----------------------------------------------------------------------
541 Standard_Boolean Conf2d = Abs (Pnt1.ParamOnFirst() - Pnt2.ParamOnFirst()) <= myConfusion2d ;
543 //-----------------------------------------------------------------------
544 // Les deux points peuvent etre `confondus' au regard des intersections.
545 //-----------------------------------------------------------------------
547 Standard_Boolean Conf3d = Standard_False ;
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 ;
559 if (Conf2d || Conf3d) {
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) ;
569 case IntRes2d_Middle: {
570 switch (TrsPnt2E.PositionOnCurve()) {
571 case IntRes2d_Head: {
572 PntE.SetPosition (TopAbs_FORWARD);
575 case IntRes2d_Middle: {
576 PntE.SetPosition (TopAbs_INTERNAL) ;
580 PntE.SetPosition (TopAbs_REVERSED) ;
590 PntE.SetPosition(TopAbs_REVERSED) ;
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) ;
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) ;
610 case IntRes2d_Middle: {
611 switch (TrsPnt2H.PositionOnCurve()) {
612 case IntRes2d_Head: {
613 PntH.SetPosition (TopAbs_FORWARD) ;
616 case IntRes2d_Middle: {
617 PntH.SetPosition (TopAbs_INTERNAL) ;
621 PntH.SetPosition (TopAbs_REVERSED) ;
631 PntH.SetPosition (TopAbs_REVERSED) ;
639 PntH.AddPoint (PntE, myConfusion2d) ;
640 Hatching.AddPoint (PntH, myConfusion2d) ;
643 IntersectionPointDump (Pnt1, 1) ;
644 IntersectionPointDump (Pnt2, 2) ;
645 cout << "THESE TWO POINTS ARE "
646 << (Conf2d ? "2D" : "3D")
647 << " CONFUSED INTO THE FOLLOWING" << endl ;
654 //-----------------------------------------------------------------------
655 // Traitement du premier point du segment.
656 //-----------------------------------------------------------------------
660 const IntRes2d_IntersectionPoint& PntI = Seg.FirstPoint() ;
663 IntersectionPointDump (PntI, 1) ;
666 HatchGen_PointOnElement PntE (PntI) ;
667 PntE.SetIndex (IndE) ;
668 PntE.SetSegmentBeginning (Standard_True) ;
669 PntE.SetSegmentEnd (Standard_False) ;
671 HatchGen_PointOnHatching PntH (PntI) ;
672 PntH.SetIndex (IndH) ;
673 PntH.AddPoint (PntE, myConfusion2d) ;
675 Hatching.AddPoint (PntH, myConfusion2d) ;
680 cout << "----- Has no first point --------" << endl ;
681 cout << "---------------------------------" << endl ;
686 //-----------------------------------------------------------------------
687 // Traitement du deuxieme point du segment.
688 //-----------------------------------------------------------------------
692 const IntRes2d_IntersectionPoint& PntI = Seg.LastPoint() ;
695 IntersectionPointDump (PntI, 2) ;
698 HatchGen_PointOnElement PntE (PntI) ;
699 PntE.SetIndex (IndE) ;
700 PntE.SetSegmentBeginning (Standard_False) ;
701 PntE.SetSegmentEnd (Standard_True) ;
703 HatchGen_PointOnHatching PntH (PntI) ;
704 PntH.SetIndex (IndH) ;
705 PntH.AddPoint (PntE, myConfusion2d) ;
707 Hatching.AddPoint (PntH, myConfusion2d) ;
712 cout << "----- Has no last point ---------" << endl ;
713 cout << "---------------------------------" << endl ;
718 cout << "--------------------------------------------------------------------" << endl ;
722 return Standard_True;
724 //=======================================================================
725 //=======================================================================
726 // Category : Computation - Domains
727 //=======================================================================
728 //=======================================================================
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
735 //=======================================================================
737 Standard_Boolean Geom2dHatch_Hatcher::GlobalTransition (HatchGen_PointOnHatching& Point)
739 TopAbs_State StateBefore = TopAbs_UNKNOWN ;
740 TopAbs_State StateAfter = TopAbs_UNKNOWN ;
741 Standard_Boolean SegmentBegin = Standard_False ;
742 Standard_Boolean SegmentEnd = Standard_False ;
744 gp_Dir2d Tangente2d, Normale2d ;
745 gp_Dir Tangente, Normale ;
746 Standard_Real Courbure ;
748 const Geom2dAdaptor_Curve& CurveH = HatchingCurve (Point.Index()) ;
750 myIntersector.LocalGeometry(CurveH.Curve(), Point.Parameter(), Tangente2d, Normale2d, Courbure);
752 Tangente.SetCoord (Tangente2d.X(), Tangente2d.Y(), 0.0) ;
753 if (Courbure < Precision::Confusion()) {
754 Normale.SetCoord (-Tangente2d.Y(), Tangente2d.X(), 0.0) ;
756 Normale.SetCoord (Normale2d.X(), Normale2d.Y(), 0.0) ;
759 TopTrans_CurveTransition ComplexTransition ;
760 ComplexTransition.Reset (Tangente, Normale, Courbure) ;
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);
767 for (Standard_Integer IPntE = 1 ; IPntE <= Point.NbPoints() ; IPntE++)
769 const HatchGen_PointOnElement& PntE = Point.Point (IPntE) ;
771 SegmentBegin = SegmentBegin || PntE.SegmentBeginning() ;
772 SegmentEnd = SegmentEnd || PntE.SegmentEnd() ;
774 const Geom2dHatch_Element& Element = myElements.Find (PntE.Index()) ;
775 const Geom2dAdaptor_Curve& CurveE = Element.Curve() ;
777 TopAbs_Orientation ElementOrientation = Element.Orientation() ;
778 Standard_Boolean ToReverse = (ElementOrientation == TopAbs_REVERSED);
779 Standard_Real Param ;
780 switch (PntE.Position())
782 case TopAbs_FORWARD :
783 Param = ToReverse ? CurveE.LastParameter() : CurveE.FirstParameter() ;
786 case TopAbs_INTERNAL :
787 Param = PntE.Parameter() ;
790 case TopAbs_REVERSED :
791 Param = ToReverse ? CurveE.FirstParameter() : CurveE.LastParameter() ;
800 printf("\n ******** ToReverse: %d Param : %g ANParam : %g \n",ToReverse,Param,PntE.Parameter());
802 Param = PntE.Parameter();
804 myIntersector.LocalGeometry(CurveE.Curve(), Param, Tangente2d, Normale2d, Courbure);
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;
816 if (ElementOrientation == TopAbs_INTERNAL)
817 LocalTransition = TopAbs_INTERNAL ;
819 else if (ElementOrientation == TopAbs_EXTERNAL)
820 LocalTransition = TopAbs_EXTERNAL ;
822 else if (PntE.IntersectionType() == HatchGen_TANGENT)
824 if (PntE.Position() == TopAbs_INTERNAL)
826 switch (PntE.StateBefore())
828 case TopAbs_IN : LocalTransition = ToReverse ? TopAbs_EXTERNAL : TopAbs_INTERNAL ; break ;
829 case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_INTERNAL : TopAbs_EXTERNAL ; break ;
835 switch (PntE.StateBefore())
837 case TopAbs_IN : LocalTransition = ToReverse ? TopAbs_FORWARD : TopAbs_REVERSED ; break ;
838 case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD ; break ;
845 switch (PntE.StateBefore())
847 case TopAbs_IN : LocalTransition = ToReverse ? TopAbs_FORWARD : TopAbs_REVERSED ; break ;
848 case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD ; break ;
853 //-----------------------------------------------------------------------
854 // Orientation de la tangente au point d interference.
855 //-----------------------------------------------------------------------
856 TopAbs_Orientation TangenteOrientation = TopAbs_FORWARD;
857 switch (PntE.Position())
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 ;
867 //-----------------------------------------------------------------------
868 // Proprietes geometriques.
869 //-----------------------------------------------------------------------
872 Tangente.SetCoord (-Tangente2d.X(), -Tangente2d.Y(), 0.0) ;
874 Tangente.SetCoord ( Tangente2d.X(), Tangente2d.Y(), 0.0) ;
876 Normale.SetCoord ( Normale2d.X(), Normale2d.Y(), 0.0) ;
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 ";
886 if(TangenteOrientation == TopAbs_INTERNAL) str2=" INTERNAL ";
887 if(TangenteOrientation == TopAbs_REVERSED) str2=" REVERSED ";
888 if(TangenteOrientation == TopAbs_FORWARD) str2=" FORWARD ";
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);
894 ComplexTransition.Compare (Precision::Angular(),
895 Tangente, Normale, Courbure,
896 LocalTransition, TangenteOrientation) ;
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 ;
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 ;
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");
920 Point.SetStateBefore (StateBefore) ;
921 Point.SetStateAfter (StateAfter) ;
922 Point.SetSegmentBeginning (SegmentBegin) ;
923 Point.SetSegmentEnd (SegmentEnd) ;
924 return Standard_True ;
927 //=======================================================================
928 // Function : ComputeDomains
929 // Purpose : Computes the domains of all the hatchings.
930 //=======================================================================
932 void Geom2dHatch_Hatcher::ComputeDomains ()
934 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++)
935 if (myHatchings.IsBound (IndH)) ComputeDomains (IndH) ;
938 //=======================================================================
939 // Function : ComputeDomains
940 // Purpose : Computes the domains of the IndH-th hatching.
941 //=======================================================================
943 void Geom2dHatch_Hatcher::ComputeDomains (const Standard_Integer IndH)
945 #if RAISE_IF_NOSUCHOBJECT
946 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
949 Geom2dHatch_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
950 Hatching.ClrDomains() ;
952 Hatching.IsDone (Standard_False) ;
954 if (!Hatching.TrimDone()) Trim (IndH) ;
955 if (Hatching.Status() != HatchGen_NoProblem) return ;
957 Standard_Boolean Points = myKeepPoints ;
958 Standard_Boolean Segments = myKeepSegments ;
959 Standard_Integer ISav = 0 ;
960 Standard_Boolean SavPnt = Standard_False ;
961 Standard_Integer NbOpenedSegments = 0 ;
962 Standard_Integer NbPnt = Hatching.NbPoints() ;
963 Standard_Integer IPnt =1;
966 //-- cout << "The hatching # " << setw(3) << IndH << " has to be classified" << endl ;
967 Geom2dHatch_Classifier Classifier(myElements,Hatching.ClassificationPoint(),0.0000001);
968 if(Classifier.State() == TopAbs_IN) {
969 HatchGen_Domain domain ;
970 Hatching.AddDomain (domain) ;
972 Hatching.IsDone (Standard_True) ;
976 //for (Standard_Integer IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
977 for (IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
978 Standard_Boolean NoDomain = Hatching.NbDomains() == 0 ;
979 Standard_Boolean FirstPoint = IPnt == 1 ;
980 Standard_Boolean LastPoint = IPnt == NbPnt ;
982 const HatchGen_PointOnHatching& CurPnt = Hatching.Point (IPnt) ;
985 cout << "===== ComputeDomains:: Hatching # " << setw(3) << IndH << " =====" << endl ;
987 cout << "==========================================" << endl ;
991 //-----------------------------------------------------------------------
992 // Calcul des domaines.
993 //-----------------------------------------------------------------------
995 TopAbs_State StateBefore = CurPnt.StateBefore() ;
996 TopAbs_State StateAfter = CurPnt.StateAfter() ;
997 Standard_Boolean SegmentBegin = CurPnt.SegmentBeginning() ;
998 Standard_Boolean SegmentEnd = CurPnt.SegmentEnd() ;
1000 HatchGen_Domain domain ;
1002 //-----------------------------------------------------------------------
1003 // Initialisations dues au premier point.
1004 //-----------------------------------------------------------------------
1007 SavPnt = Standard_False ;
1009 NbOpenedSegments = 0 ;
1010 if (SegmentEnd && SegmentBegin) {
1011 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1012 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1014 SavPnt = Standard_True ;
1017 } else if (SegmentEnd) {
1018 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1020 SavPnt = Standard_True ;
1023 } else if (SegmentBegin) {
1024 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1025 if (StateBefore == TopAbs_IN) {
1026 SavPnt = Standard_True ;
1030 if (StateBefore == TopAbs_IN) {
1031 SavPnt = Standard_True ;
1037 //-----------------------------------------------------------------------
1038 // Initialisations dues au dernier point.
1039 //-----------------------------------------------------------------------
1042 if (SegmentEnd && SegmentBegin) {
1043 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1044 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1045 } else if (SegmentEnd) {
1046 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1047 } else if (SegmentBegin) {
1048 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1053 //-----------------------------------------------------------------------
1055 //-----------------------------------------------------------------------
1057 Standard_Boolean ToAppend = Standard_False ;
1059 if (SegmentEnd && SegmentBegin) {
1061 if (StateBefore != TopAbs_IN && StateAfter != TopAbs_IN) {
1062 Hatching.Status (HatchGen_IncompatibleStates) ;
1069 Hatching.Status (HatchGen_IncoherentParity) ;
1072 Hatching.IsDone(Standard_True);
1076 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1077 domain.SetSecondPoint (CurPnt) ;
1078 ToAppend = Standard_True ;
1079 SavPnt = Standard_True ;
1082 Standard_Boolean isININ = (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN);
1083 if (SavPnt && !isININ) {
1085 Hatching.Status (HatchGen_IncoherentParity) ;
1088 Hatching.IsDone(Standard_True);
1092 domain.SetPoints (CurPnt, CurPnt) ;
1093 ToAppend = Standard_True ;
1094 SavPnt = Standard_False ;
1099 } else if (SegmentEnd) {
1102 if (StateAfter == TopAbs_OUT) {
1105 Hatching.Status (HatchGen_IncoherentParity) ;
1108 Hatching.IsDone(Standard_True);
1112 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1113 domain.SetSecondPoint (CurPnt) ;
1114 ToAppend = Standard_True ;
1117 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1118 domain.SetSecondPoint (CurPnt) ;
1119 ToAppend = Standard_True ;
1120 SavPnt = Standard_True ;
1125 if (StateAfter == TopAbs_IN) {
1126 SavPnt = Standard_True ;
1130 NbOpenedSegments-- ;
1132 } else if (SegmentBegin) {
1135 if (StateBefore == TopAbs_OUT) {
1136 SavPnt = Standard_True ;
1142 Hatching.Status (HatchGen_IncoherentParity) ;
1145 Hatching.IsDone(Standard_True);
1150 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1151 domain.SetSecondPoint (CurPnt) ;
1152 ToAppend = Standard_True ;
1153 SavPnt = Standard_True ;
1158 if (StateBefore == TopAbs_IN) {
1161 Hatching.Status (HatchGen_IncoherentParity) ;
1164 Hatching.IsDone(Standard_True);
1169 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1170 domain.SetSecondPoint (CurPnt) ;
1171 ToAppend = Standard_True ;
1172 // Modified by Sergey KHROMOV - Fri Jan 5 12:05:30 2001
1173 // SavPnt = Standard_False ;
1175 SavPnt = Standard_True ;
1177 // Modified by Sergey KHROMOV - Fri Jan 5 12:05:31 2001
1180 NbOpenedSegments++ ;
1183 //-- ???????????????????????????????????????????????????????????????????????????
1184 //-- Solution provisoire (lbr le 11 Aout 97 )
1185 //-- si On a 2 points dont des points OUT OUT ou IN IN qui delimitent une isos
1186 //-- on transforme les transitions
1187 if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
1190 StateAfter = TopAbs_IN;
1192 StateBefore = TopAbs_IN;
1195 //-- ???????????????????????????????????????????????????????????????????????????
1196 if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
1200 Hatching.Status (HatchGen_IncoherentParity) ;
1203 Hatching.IsDone(Standard_True);
1209 domain.SetPoints (CurPnt, CurPnt) ;
1210 ToAppend = Standard_True ;
1211 SavPnt = Standard_True ;
1215 } else if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_IN ) {
1217 SavPnt = Standard_True ;
1220 } else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_OUT) {
1224 Hatching.Status (HatchGen_IncoherentParity) ;
1227 Hatching.IsDone(Standard_True);
1232 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1233 domain.SetSecondPoint (CurPnt) ;
1234 ToAppend = Standard_True ;
1235 SavPnt = Standard_False ;
1238 } else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN ) {
1241 if (NbOpenedSegments == 0) {
1244 Hatching.Status (HatchGen_IncoherentParity) ;
1247 Hatching.IsDone(Standard_True);
1252 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1253 domain.SetSecondPoint (CurPnt) ;
1254 ToAppend = Standard_True ;
1255 SavPnt = Standard_True ;
1261 Hatching.Status (HatchGen_IncoherentParity) ;
1264 Hatching.IsDone(Standard_True);
1269 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1270 domain.SetSecondPoint (CurPnt) ;
1271 ToAppend = Standard_True ;
1272 SavPnt = Standard_True ;
1277 Hatching.Status (HatchGen_IncoherentParity) ;
1280 Hatching.IsDone(Standard_True);
1285 domain.SetPoints (CurPnt, CurPnt) ;
1286 ToAppend = Standard_True ;
1287 SavPnt = Standard_False ;
1295 Hatching.Status (HatchGen_IncompatibleStates) ;
1302 //-----------------------------------------------------------------------
1303 // Ajout du domaine.
1304 //-----------------------------------------------------------------------
1306 if (ToAppend) Hatching.AddDomain (domain) ;
1308 //-----------------------------------------------------------------------
1309 // Traitement lie au dernier point.
1310 //-----------------------------------------------------------------------
1314 domain.SetPoints () ;
1315 ToAppend = Standard_False ;
1317 if (SegmentEnd && SegmentBegin) {
1322 Hatching.Status (HatchGen_IncoherentParity) ;
1325 Hatching.IsDone(Standard_True);
1330 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1331 ToAppend = Standard_True ;
1334 } else if (SegmentEnd) {
1336 if (StateAfter == TopAbs_IN) {
1339 Hatching.Status (HatchGen_IncoherentParity) ;
1342 Hatching.IsDone(Standard_True);
1347 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1348 ToAppend = Standard_True ;
1351 } else if (SegmentBegin) {
1356 Hatching.Status (HatchGen_IncoherentParity) ;
1359 Hatching.IsDone(Standard_True);
1364 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1365 ToAppend = Standard_True ;
1370 if (StateAfter == TopAbs_IN) {
1373 Hatching.Status (HatchGen_IncoherentParity) ;
1376 Hatching.IsDone(Standard_True);
1381 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1382 ToAppend = Standard_True ;
1386 if (ToAppend) Hatching.AddDomain (domain) ;
1390 Hatching.IsDone(Standard_True) ;
1393 //=======================================================================
1394 //=======================================================================
1395 // Category : Results.
1396 //=======================================================================
1397 //=======================================================================
1400 //=======================================================================
1401 // Function : Domain
1402 // Purpose : Returns the IDom-th domain of the IndH-th hatching.
1403 //=======================================================================
1405 const HatchGen_Domain& Geom2dHatch_Hatcher::Domain (const Standard_Integer IndH,
1406 const Standard_Integer IDom) const
1408 #if RAISE_IF_NOSUCHOBJECT
1409 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
1411 const Geom2dHatch_Hatching& Hatching = myHatchings.Find (IndH) ;
1412 StdFail_NotDone_Raise_if (!Hatching.IsDone(), "Geom2dHatch_Hatcher::Domain") ;
1413 #if RAISE_IF_NOSUCHOBJECT
1414 Standard_OutOfRange_Raise_if (IDom < 1 || IDom > Hatching.NbDomains(), "") ;
1416 const HatchGen_Domain& Domain = Hatching.Domain (IDom) ;
1420 //=======================================================================
1421 //=======================================================================
1423 //=======================================================================
1424 //=======================================================================
1426 //=======================================================================
1428 // Purpose : Dumps the hatcher.
1429 //=======================================================================
1431 void Geom2dHatch_Hatcher::Dump () const
1434 cout << "========================================================" << endl ;
1435 cout << "=== Dump of the hatcher ================================" << endl ;
1436 cout << "========================================================" << endl ;
1439 cout << "The points are "
1440 << (myKeepPoints ? " " : "not ")
1443 cout << "The segments are "
1444 << (myKeepSegments ? " " : "not ")
1447 cout << "2D Confusion tolerance : " << myConfusion2d << endl ;
1448 cout << "3D Confusion tolerance : " << myConfusion3d << endl ;
1450 cout << myNbHatchings
1452 << ((myNbHatchings == 1) ? "" : "s")
1454 cout << myNbElements
1456 << ((myNbElements == 1) ? "" : "s")
1460 cout << "========================================================" << endl ;
1461 cout << "=== Hatchings ==========================================" << endl ;
1462 cout << "========================================================" << endl ;
1465 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
1466 cout << "Hatching # " << IndH ;
1467 if (!myHatchings.IsBound (IndH)) {
1468 cout << " is not bound" << endl ;
1470 const Geom2dHatch_Hatching& Hatching = myHatchings.Find (IndH) ;
1471 Standard_Integer NbPnt = Hatching.NbPoints() ;
1472 cout << " contains " << NbPnt << " restriction points :" << endl ;
1473 for (Standard_Integer IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
1474 const HatchGen_PointOnHatching& PntH = Hatching.Point (IPnt) ;
1477 cout << "----------------------------------------------" << endl ;
1482 cout << "========================================================" << endl ;
1483 cout << "=== Elements ===========================================" << endl ;
1484 cout << "========================================================" << endl ;
1487 for (Standard_Integer IndE = 1 ; IndE <= myNbElements ; IndE++) {
1488 cout << "Element # " << IndE ;
1489 if (!myElements.IsBound (IndE)) {
1490 cout << " is not bound" << endl ;
1492 const Geom2dHatch_Element& Element = myElements.Find (IndE) ;
1493 switch (Element.Orientation()) {
1494 case TopAbs_FORWARD : cout << " is FORWARD" << endl ; break ;
1495 case TopAbs_REVERSED : cout << " is REVERSED" << endl ; break ;
1496 case TopAbs_INTERNAL : cout << " is INTERNAL" << endl ; break ;
1497 case TopAbs_EXTERNAL : cout << " is EXTERNAL" << endl ; break ;