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 <HatchGen_Domain.hxx>
18 #include <HatchGen_Domains.hxx>
19 #include <HatchGen_PointOnElement.hxx>
20 #include <HatchGen_PointOnHatching.hxx>
21 #include <IntRes2d_IntersectionPoint.hxx>
22 #include <IntRes2d_IntersectionSegment.hxx>
23 #include <IntRes2d_Transition.hxx>
24 #include <Precision.hxx>
26 #include <TopTrans_CurveTransition.hxx>
28 #define RAISE_IF_NOSUCHOBJECT 0
29 #define TRACE_HATCHER 0
31 //=======================================================================
32 //=======================================================================
33 // Category : General use.
34 //=======================================================================
35 //=======================================================================
37 //=======================================================================
38 // Function : HatchGen_Hatcher
39 // Purpose : Constructor.
40 //=======================================================================
42 HatchGen_Hatcher::HatchGen_Hatcher (const TheIntersector& Intersector,
43 const Standard_Real Confusion2d,
44 const Standard_Real Confusion3d,
45 const Standard_Boolean KeepPnt,
46 const Standard_Boolean KeepSeg) :
47 myIntersector (Intersector) ,
48 myConfusion2d (Confusion2d) ,
49 myConfusion3d (Confusion3d) ,
50 myKeepPoints (KeepPnt) ,
51 myKeepSegments (KeepSeg) ,
57 //=======================================================================
58 // Function : Intersector
59 // Purpose : Sets the associated intersector.
60 //=======================================================================
62 void HatchGen_Hatcher::Intersector (const TheIntersector& Intersector)
64 myIntersector = Intersector ;
65 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
66 if (myHatchings.IsBound (IndH)) {
67 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
68 Hatching.ClrPoints() ;
74 //=======================================================================
75 // Function : Confusion2d
76 // Purpose : Sets the 2dconfusion tolerance.
77 //=======================================================================
79 void HatchGen_Hatcher::Confusion2d (const Standard_Real Confusion)
81 myConfusion2d = Confusion ;
82 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
83 if (myHatchings.IsBound (IndH)) {
84 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
85 Hatching.ClrPoints() ;
91 //=======================================================================
92 // Function : Confusion3d
93 // Purpose : Sets the 3d confusion tolerance.
94 //=======================================================================
96 void HatchGen_Hatcher::Confusion3d (const Standard_Real Confusion)
98 myConfusion3d = Confusion ;
99 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
100 if (myHatchings.IsBound (IndH)) {
101 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
102 Hatching.ClrPoints() ;
107 //=======================================================================
108 // Function : KeepPoints
109 // Purpose : Sets the above flag.
110 //=======================================================================
112 void HatchGen_Hatcher::KeepPoints (const Standard_Boolean Keep)
114 myKeepPoints = Keep ;
115 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
116 if (myHatchings.IsBound (IndH)) {
117 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
118 Hatching.ClrDomains() ;
124 //=======================================================================
125 // Function : KeepSegments
126 // Purpose : Sets the above flag.
127 //=======================================================================
129 void HatchGen_Hatcher::KeepSegments (const Standard_Boolean Keep)
131 myKeepSegments = Keep ;
132 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
133 if (myHatchings.IsBound (IndH)) {
134 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
135 Hatching.ClrDomains() ;
142 //=======================================================================
143 //=======================================================================
144 // Category : Element.
145 //=======================================================================
146 //=======================================================================
149 //=======================================================================
150 // Function : AddElement
151 // Purpose : Adds an element to the Hatcher and returns its index.
152 //=======================================================================
154 Standard_Integer HatchGen_Hatcher::AddElement (const TheCurveE& Curve,
155 const TopAbs_Orientation Orientation)
157 Standard_Integer IndE ;
158 for (IndE = 1 ; IndE <= myNbElements && myElements.IsBound(IndE) ; IndE++) ;
159 if (IndE > myNbElements) {
161 IndE = myNbElements ;
163 HatchGen_Element Element (Curve, Orientation) ;
164 myElements.Bind (IndE, Element) ;
165 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings; IndH++) {
166 if (myHatchings.IsBound(IndH)) {
167 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
168 Hatching.ClrPoints () ;
174 //=======================================================================
175 // Function : RemElement
176 // Purpose : Removes the IndE-th element from the hatcher.
177 //=======================================================================
179 void HatchGen_Hatcher::RemElement (const Standard_Integer IndE)
181 #if RAISE_IF_NOSUCHOBJECT
182 Standard_NoSuchObject_Raise_if (!myElements.IsBound (IndE), "") ;
184 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
185 if (myHatchings.IsBound (IndH)) {
186 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
187 Standard_Boolean DomainsToClear = Standard_False ;
188 for (Standard_Integer IPntH = Hatching.NbPoints() ; IPntH > 0 ; IPntH--) {
189 HatchGen_PointOnHatching PntH = Hatching.ChangePoint (IPntH) ;
190 for (Standard_Integer IPntE = PntH.NbPoints() ; IPntE > 0 ; IPntE--) {
191 if (PntH.Point(IPntE).Index() == IndE) {
192 PntH.RemPoint (IPntE) ;
193 DomainsToClear = Standard_True ;
196 if (PntH.NbPoints() == 0) Hatching.RemPoint (IPntH) ;
198 if (DomainsToClear) Hatching.ClrDomains() ;
201 myElements.UnBind (IndE) ;
202 if (IndE == myNbElements) myNbElements-- ;
205 //=======================================================================
206 // Function : ClrElements
207 // Purpose : Removes all the elements from the hatcher.
208 //=======================================================================
210 void HatchGen_Hatcher::ClrElements ()
212 if (myNbElements != 0) {
213 if (myNbHatchings != 0) {
214 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
215 if (myHatchings.IsBound(IndH)) {
216 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
217 Hatching.ClrPoints() ;
226 //=======================================================================
227 //=======================================================================
228 // Category : Hatching.
229 //=======================================================================
230 //=======================================================================
233 //=======================================================================
234 // Function : AddHatching
235 // Purpose : Adds a hatching to the hatcher and returns its index.
236 //=======================================================================
238 Standard_Integer HatchGen_Hatcher::AddHatching (const TheCurveH& Curve)
240 Standard_Integer IndH ;
241 for (IndH = 1 ; IndH <= myNbHatchings && myHatchings.IsBound(IndH) ; IndH++) ;
242 if (IndH > myNbHatchings) {
244 IndH = myNbHatchings ;
246 HatchGen_Hatching Hatching (Curve) ;
247 myHatchings.Bind (IndH, Hatching) ;
251 //=======================================================================
252 // Function : RemHatching
253 // Purpose : Removes the IndH-th hatching from the hatcher.
254 //=======================================================================
256 void HatchGen_Hatcher::RemHatching (const Standard_Integer IndH)
258 #if RAISE_IF_NOSUCHOBJECT
259 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
261 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
262 Hatching.ClrPoints() ;
263 myHatchings.UnBind (IndH) ;
264 if (IndH == myNbHatchings) myNbHatchings-- ;
267 //=======================================================================
268 // Function : ClrHatchings
269 // Purpose : Removes all the hatchings from the hatcher.
270 //=======================================================================
272 void HatchGen_Hatcher::ClrHatchings ()
274 if (myNbHatchings != 0) {
275 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
276 if (myHatchings.IsBound(IndH)) {
277 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
278 Hatching.ClrPoints() ;
281 myHatchings.Clear() ;
288 //=======================================================================
289 //=======================================================================
290 // Category : Computation - Trimming
291 //=======================================================================
292 //=======================================================================
294 //=======================================================================
296 // Purpose : Trims all the hatchings of the hatcher by all the elements
298 //=======================================================================
300 void HatchGen_Hatcher::Trim ()
302 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++)
303 if (myHatchings.IsBound (IndH))
307 //=======================================================================
309 // Purpose : Adds a hatching to the hatcher and trims it by the elements
310 // already given and returns its index.
311 //=======================================================================
313 Standard_Integer HatchGen_Hatcher::Trim (const TheCurveH& Curve)
315 Standard_Integer IndH = AddHatching (Curve) ;
320 //=======================================================================
322 // Purpose : Trims the IndH-th hatching by the elements already given.
323 //=======================================================================
325 void HatchGen_Hatcher::Trim (const Standard_Integer IndH)
327 #if RAISE_IF_NOSUCHOBJECT
328 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
331 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
333 Hatching.ClrPoints() ;
335 Standard_Boolean OK, AllOK ;
337 AllOK = Standard_True ;
338 for (Standard_Integer IndE = 1 ; IndE <= myNbElements ; IndE++) {
339 if (myElements.IsBound (IndE)) {
340 OK = Trim (IndH, IndE) ;
341 AllOK = AllOK && OK ;
344 Hatching.TrimDone (Standard_True) ;
345 Hatching.TrimFailed (!AllOK) ;
348 for (Standard_Integer IPnt = 1 ; IPnt <= Hatching.NbPoints() ; IPnt++) {
349 HatchGen_PointOnHatching& PntH = Hatching.ChangePoint(IPnt) ;
350 OK = GlobalTransition (PntH) ;
351 AllOK = AllOK && OK ;
353 Hatching.Status (AllOK ? HatchGen_NoProblem : HatchGen_TransitionFailure) ;
359 //=======================================================================
360 // Function : IntersectionPointDump
361 // Purpose : Dump of the intersection point.
362 //=======================================================================
364 static void IntersectionPointDump (const IntRes2d_IntersectionPoint& Pnt,
365 const Standard_Integer Index)
367 Standard_Integer SavedPrecision = cout.precision() ;
368 cout.precision (15) ;
369 cout << "----- IntRes2d:: Point # " << setw(3) << Index << " ---------------" << endl ;
370 cout << "-- U: "<<Pnt.Value().X()<<" V: "<<Pnt.Value().Y()<<endl;
371 cout << "-- Parameter on first : " << Pnt.ParamOnFirst() << endl ;
372 cout << "-- Position on first : " ;
373 switch (Pnt.TransitionOfFirst().PositionOnCurve()) {
374 case IntRes2d_Head : cout << "HEAD" ; break ;
375 case IntRes2d_Middle : cout << "MIDDLE" ; break ;
376 case IntRes2d_End : cout << "END" ; break ;
379 cout << "-- IntRes2d:: Transition on first : " ;
380 switch (Pnt.TransitionOfFirst().TransitionType()) {
381 case IntRes2d_In : cout << "IN" ; break ;
382 case IntRes2d_Out : cout << "OUT" ; break ;
383 case IntRes2d_Touch : cout << "TOUCH" ; break ;
384 case IntRes2d_Undecided : cout << "UNDECIDED" ; break ;
387 if (Pnt.TransitionOfFirst().TransitionType() == IntRes2d_Touch) {
388 cout << "-- IntRes2d:: Situation on first : " ;
389 switch (Pnt.TransitionOfFirst().Situation()) {
390 case IntRes2d_Inside : cout << "INSIDE" ; break ;
391 case IntRes2d_Outside : cout << "OUTSIDE" ; break ;
392 case IntRes2d_Unknown : cout << "UNKNOWN" ; break ;
396 cout << "--------------------------------------------" << endl ;
397 cout << "-- Parameter on second : " << Pnt.ParamOnSecond() << endl ;
398 cout << "-- Position on second : " ;
399 switch (Pnt.TransitionOfSecond().PositionOnCurve()) {
400 case IntRes2d_Head : cout << "HEAD" ; break ;
401 case IntRes2d_Middle : cout << "MIDDLE" ; break ;
402 case IntRes2d_End : cout << "END" ; break ;
405 cout << "-- IntRes2d:: Transition on second : " ;
406 switch (Pnt.TransitionOfSecond().TransitionType()) {
407 case IntRes2d_In : cout << "IN" ; break ;
408 case IntRes2d_Out : cout << "OUT" ; break ;
409 case IntRes2d_Touch : cout << "TOUCH" ; break ;
410 case IntRes2d_Undecided : cout << "UNDECIDED" ; break ;
413 if (Pnt.TransitionOfSecond().TransitionType() == IntRes2d_Touch) {
414 cout << "-- IntRes2d:: Situation on second : " ;
415 switch (Pnt.TransitionOfSecond().Situation()) {
416 case IntRes2d_Inside : cout << "INSIDE" ; break ;
417 case IntRes2d_Outside : cout << "OUTSIDE" ; break ;
418 case IntRes2d_Unknown : cout << "UNKNOWN" ; break ;
422 cout << "--------------------------------------------" << endl ;
423 cout.precision (SavedPrecision) ;
428 //=======================================================================
430 // Purpose : Trims the IndH-th hatching of the hatcher by the IndE th
432 //=======================================================================
434 Standard_Boolean HatchGen_Hatcher::Trim (const Standard_Integer IndH,
435 const Standard_Integer IndE)
437 #if RAISE_IF_NOSUCHOBJECT
438 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
439 Standard_NoSuchObject_Raise_if (!myElements.IsBound (IndE), "") ;
442 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
443 HatchGen_Element& Element = myElements.ChangeFind (IndE) ;
445 TheCurveH hatching = Hatching.ChangeCurve() ;
446 TheCurveE element = Element.ChangeCurve() ;
448 myIntersector.Intersect (hatching, element) ;
451 cout << "--- Hatcher - Trim:: Hatching # " << setw(3);
452 cout << IndH << " with Element # " << setw(3);
453 cout << IndE << " ----------" << endl ;
456 if (!myIntersector.IsDone()) {
457 cout<<" Intersector -> Done = False ";
458 return Standard_False ;
462 if (myIntersector.IsEmpty()) {
463 cout << "No intersection" << endl ;
464 cout << "--------------------------------------------------------------------" << endl ;
468 if (myIntersector.IsEmpty()) return Standard_True ;
471 cout << "Number of intersection points : " << setw(3) << (myIntersector.NbPoints()) << endl ;
472 cout << "Number of intersection segments : " << setw(3) << (myIntersector.NbSegments()) << endl ;
475 //-----------------------------------------------------------------------
476 // Traitement des points d intersection.
477 //-----------------------------------------------------------------------
479 for (Standard_Integer IPntI = 1 ; IPntI <= myIntersector.NbPoints() ; IPntI++) {
480 const IntRes2d_IntersectionPoint& PntI = myIntersector.Point (IPntI) ;
483 IntersectionPointDump (PntI, IPntI) ;
486 HatchGen_PointOnElement PntE (PntI) ;
487 PntE.SetIndex (IndE) ;
489 HatchGen_PointOnHatching PntH (PntI) ;
490 PntH.SetIndex (IndH) ;
491 PntH.AddPoint (PntE, myConfusion2d) ;
493 Hatching.AddPoint (PntH, myConfusion2d) ;
496 //-----------------------------------------------------------------------
497 // Traitement des segments d intersection.
498 //-----------------------------------------------------------------------
500 for (Standard_Integer ISeg = 1 ; ISeg <= myIntersector.NbSegments() ; ISeg++) {
502 const IntRes2d_IntersectionSegment& Seg = myIntersector.Segment (ISeg) ;
505 cout << "----- Segment # " << setw(3) << ISeg << " -------------" << endl ;
508 Standard_Boolean FirstPoint = Seg.HasFirstPoint() ;
509 Standard_Boolean LastPoint = Seg.HasLastPoint() ;
511 //-----------------------------------------------------------------------
512 // Les deux points peuvent etre confondus.
513 //-----------------------------------------------------------------------
515 if (FirstPoint && LastPoint) {
517 const IntRes2d_IntersectionPoint& Pnt1 = Seg.FirstPoint() ;
518 const IntRes2d_IntersectionPoint& Pnt2 = Seg.LastPoint() ;
520 const IntRes2d_Transition& TrsPnt1H = Pnt1.TransitionOfFirst() ;
521 const IntRes2d_Transition& TrsPnt1E = Pnt1.TransitionOfSecond() ;
522 const IntRes2d_Transition& TrsPnt2H = Pnt2.TransitionOfFirst() ;
523 const IntRes2d_Transition& TrsPnt2E = Pnt2.TransitionOfSecond() ;
525 IntRes2d_TypeTrans TypePnt1H = TrsPnt1H.TransitionType() ;
526 IntRes2d_TypeTrans TypePnt1E = TrsPnt1E.TransitionType() ;
527 IntRes2d_TypeTrans TypePnt2H = TrsPnt2H.TransitionType() ;
528 IntRes2d_TypeTrans TypePnt2E = TrsPnt2E.TransitionType() ;
530 //-----------------------------------------------------------------------
531 // Les deux points peuvent etre confondus au regard de la precision du
533 //-----------------------------------------------------------------------
535 Standard_Boolean Conf2d = Abs (Pnt1.ParamOnFirst() - Pnt2.ParamOnFirst()) <= myConfusion2d ;
537 //-----------------------------------------------------------------------
538 // Les deux points peuvent etre `confondus' au regard des intersections.
539 //-----------------------------------------------------------------------
541 Standard_Boolean Conf3d = Standard_False ;
544 Conf3d = Standard_True ;
545 if (Conf3d) Conf3d = TypePnt1H != IntRes2d_Touch && TypePnt1H != IntRes2d_Undecided ;
546 if (Conf3d) Conf3d = TypePnt1E != IntRes2d_Touch && TypePnt1E != IntRes2d_Undecided ;
547 if (Conf3d) Conf3d = TypePnt2H != IntRes2d_Touch && TypePnt2H != IntRes2d_Undecided ;
548 if (Conf3d) Conf3d = TypePnt2E != IntRes2d_Touch && TypePnt2E != IntRes2d_Undecided ;
549 if (Conf3d) Conf3d = TypePnt1H == TypePnt2H && TypePnt1E == TypePnt2E ;
550 if (Conf3d) Conf3d = Pnt1.Value().Distance (Pnt2.Value()) <= myConfusion3d ;
553 if (Conf2d || Conf3d) {
555 HatchGen_PointOnElement PntE ;
556 PntE.SetIndex (IndE) ;
557 PntE.SetParameter ((Pnt1.ParamOnSecond() + Pnt2.ParamOnSecond()) / 2.) ;
558 switch (TrsPnt1E.PositionOnCurve()) {
559 case IntRes2d_Head: {
560 PntE.SetPosition(TopAbs_FORWARD) ;
563 case IntRes2d_Middle: {
564 switch (TrsPnt2E.PositionOnCurve()) {
565 case IntRes2d_Head: {
566 PntE.SetPosition (TopAbs_FORWARD);
569 case IntRes2d_Middle: {
570 PntE.SetPosition (TopAbs_INTERNAL) ;
574 PntE.SetPosition (TopAbs_REVERSED) ;
584 PntE.SetPosition(TopAbs_REVERSED) ;
591 PntE.SetIntersectionType
592 ((PntE.Position() == TopAbs_INTERNAL) ? HatchGen_TRUE : HatchGen_TOUCH) ;
593 PntE.SetStateBefore ((TypePnt1H == IntRes2d_In) ? TopAbs_OUT : TopAbs_IN) ;
594 PntE.SetStateAfter ((TypePnt2H == IntRes2d_In) ? TopAbs_OUT : TopAbs_IN) ;
596 HatchGen_PointOnHatching PntH ;
597 PntH.SetIndex (IndH) ;
598 PntH.SetParameter ((Pnt1.ParamOnFirst() + Pnt2.ParamOnFirst()) / 2.) ;
599 switch (TrsPnt1H.PositionOnCurve()) {
600 case IntRes2d_Head: {
601 PntH.SetPosition (TopAbs_FORWARD) ;
604 case IntRes2d_Middle: {
605 switch (TrsPnt2H.PositionOnCurve()) {
606 case IntRes2d_Head: {
607 PntH.SetPosition (TopAbs_FORWARD) ;
610 case IntRes2d_Middle: {
611 PntH.SetPosition (TopAbs_INTERNAL) ;
615 PntH.SetPosition (TopAbs_REVERSED) ;
625 PntH.SetPosition (TopAbs_REVERSED) ;
633 PntH.AddPoint (PntE, myConfusion2d) ;
634 Hatching.AddPoint (PntH, myConfusion2d) ;
637 IntersectionPointDump (Pnt1, 1) ;
638 IntersectionPointDump (Pnt2, 2) ;
639 cout << "THESE TWO POINTS ARE "
640 << (Conf2d ? "2D" : "3D")
641 << " CONFUSED INTO THE FOLLOWING" << endl ;
648 //-----------------------------------------------------------------------
649 // Traitement du premier point du segment.
650 //-----------------------------------------------------------------------
654 const IntRes2d_IntersectionPoint& PntI = Seg.FirstPoint() ;
657 IntersectionPointDump (PntI, 1) ;
660 HatchGen_PointOnElement PntE (PntI) ;
661 PntE.SetIndex (IndE) ;
662 PntE.SetSegmentBeginning (Standard_True) ;
663 PntE.SetSegmentEnd (Standard_False) ;
665 HatchGen_PointOnHatching PntH (PntI) ;
666 PntH.SetIndex (IndH) ;
667 PntH.AddPoint (PntE, myConfusion2d) ;
669 Hatching.AddPoint (PntH, myConfusion2d) ;
674 cout << "----- Has no first point --------" << endl ;
675 cout << "---------------------------------" << endl ;
680 //-----------------------------------------------------------------------
681 // Traitement du deuxieme point du segment.
682 //-----------------------------------------------------------------------
686 const IntRes2d_IntersectionPoint& PntI = Seg.LastPoint() ;
689 IntersectionPointDump (PntI, 2) ;
692 HatchGen_PointOnElement PntE (PntI) ;
693 PntE.SetIndex (IndE) ;
694 PntE.SetSegmentBeginning (Standard_False) ;
695 PntE.SetSegmentEnd (Standard_True) ;
697 HatchGen_PointOnHatching PntH (PntI) ;
698 PntH.SetIndex (IndH) ;
699 PntH.AddPoint (PntE, myConfusion2d) ;
701 Hatching.AddPoint (PntH, myConfusion2d) ;
706 cout << "----- Has no last point ---------" << endl ;
707 cout << "---------------------------------" << endl ;
712 cout << "--------------------------------------------------------------------" << endl ;
716 return Standard_True;
718 //=======================================================================
719 //=======================================================================
720 // Category : Computation - Domains
721 //=======================================================================
722 //=======================================================================
724 //=======================================================================
725 // Function : GlobalTransition
726 // Purpose : Returns the before and after states of the complex
727 // transition of the IndP-th intersection point of the
729 //=======================================================================
731 Standard_Boolean HatchGen_Hatcher::GlobalTransition (HatchGen_PointOnHatching& Point)
733 TopAbs_State StateBefore = TopAbs_UNKNOWN ;
734 TopAbs_State StateAfter = TopAbs_UNKNOWN ;
735 Standard_Boolean SegmentBegin = Standard_False ;
736 Standard_Boolean SegmentEnd = Standard_False ;
738 gp_Dir2d Tangente2d, Normale2d ;
739 gp_Dir Tangente, Normale ;
740 Standard_Real Courbure ;
742 const TheCurveH& CurveH = HatchingCurve (Point.Index()) ;
744 myIntersector.LocalGeometry(CurveH.Curve(), Point.Parameter(), Tangente2d, Normale2d, Courbure);
746 Tangente.SetCoord (Tangente2d.X(), Tangente2d.Y(), 0.0) ;
747 if (Courbure < Precision::Confusion()) {
748 Normale.SetCoord (-Tangente2d.Y(), Tangente2d.X(), 0.0) ;
750 Normale.SetCoord (Normale2d.X(), Normale2d.Y(), 0.0) ;
753 TopTrans_CurveTransition ComplexTransition ;
754 ComplexTransition.Reset (Tangente, Normale, Courbure) ;
757 printf("\n ----- Global Transition Complex Transition Reset \n");
758 printf("\n P:%+10.5g Tg2d:%+10.5g , %+10.5g N2d:%+10.5g , %+10.5g Crv:%+10.5g\n\n",
759 Point.Parameter(),Tangente.X(),Tangente.Y(),Normale.X(),Normale.Y(),Courbure);
761 for (Standard_Integer IPntE = 1 ; IPntE <= Point.NbPoints() ; IPntE++)
763 const HatchGen_PointOnElement& PntE = Point.Point (IPntE) ;
765 SegmentBegin = SegmentBegin || PntE.SegmentBeginning() ;
766 SegmentEnd = SegmentEnd || PntE.SegmentEnd() ;
768 const HatchGen_Element& Element = myElements.Find (PntE.Index()) ;
769 const TheCurveE& CurveE = Element.Curve() ;
771 TopAbs_Orientation ElementOrientation = Element.Orientation() ;
772 Standard_Boolean ToReverse = (ElementOrientation == TopAbs_REVERSED);
773 Standard_Real Param ;
774 switch (PntE.Position())
776 case TopAbs_FORWARD :
777 Param = ToReverse ? CurveE.LastParameter() : CurveE.FirstParameter() ;
780 case TopAbs_INTERNAL :
781 Param = PntE.Parameter() ;
784 case TopAbs_REVERSED :
785 Param = ToReverse ? CurveE.FirstParameter() : CurveE.LastParameter() ;
794 printf("\n ******** ToReverse: %d Param : %g ANParam : %g \n",ToReverse,Param,PntE.Parameter());
796 Param = PntE.Parameter();
798 myIntersector.LocalGeometry(CurveE.Curve(), Param, Tangente2d, Normale2d, Courbure);
800 //-----------------------------------------------------------------------
801 // Calcul de la transition locale. On suppose les relations suivantes :
802 // - Si l orientation de l element est INTERNAL ==> INTERNAL
803 // - Si l orientation de l element est EXTERNAL ==> EXTERNAL
804 // - Si tangence, on a IN-IN ou OUT-OUT ==> INTERNAL/EXTERNAL
805 // - Sinon, on a IN-OUT ou OUT-IN ==> REVERSED/FORWARD
806 // Les deux dernieres conditions avec l element vu en FORWARD.
807 //-----------------------------------------------------------------------
808 TopAbs_Orientation LocalTransition = TopAbs_EXTERNAL;
810 if (ElementOrientation == TopAbs_INTERNAL)
811 LocalTransition = TopAbs_INTERNAL ;
813 else if (ElementOrientation == TopAbs_EXTERNAL)
814 LocalTransition = TopAbs_EXTERNAL ;
816 else if (PntE.IntersectionType() == HatchGen_TANGENT)
818 if (PntE.Position() == TopAbs_INTERNAL)
820 switch (PntE.StateBefore())
822 case TopAbs_IN : LocalTransition = ToReverse ? TopAbs_EXTERNAL : TopAbs_INTERNAL ; break ;
823 case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_INTERNAL : TopAbs_EXTERNAL ; break ;
829 switch (PntE.StateBefore())
831 case TopAbs_IN : LocalTransition = ToReverse ? TopAbs_FORWARD : TopAbs_REVERSED ; break ;
832 case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD ; break ;
839 switch (PntE.StateBefore())
841 case TopAbs_IN : LocalTransition = ToReverse ? TopAbs_FORWARD : TopAbs_REVERSED ; break ;
842 case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD ; break ;
847 //-----------------------------------------------------------------------
848 // Orientation de la tangente au point d interference.
849 //-----------------------------------------------------------------------
850 TopAbs_Orientation TangenteOrientation = TopAbs_FORWARD;
851 switch (PntE.Position())
853 case TopAbs_FORWARD : TangenteOrientation = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD ; break ;
854 case TopAbs_INTERNAL : TangenteOrientation = TopAbs_INTERNAL ; break ;
855 case TopAbs_REVERSED : TangenteOrientation = ToReverse ? TopAbs_FORWARD : TopAbs_REVERSED ; break ;
861 //-----------------------------------------------------------------------
862 // Proprietes geometriques.
863 //-----------------------------------------------------------------------
866 Tangente.SetCoord (-Tangente2d.X(), -Tangente2d.Y(), 0.0) ;
868 Tangente.SetCoord ( Tangente2d.X(), Tangente2d.Y(), 0.0) ;
870 Normale.SetCoord ( Normale2d.X(), Normale2d.Y(), 0.0) ;
873 printf("\n \n----- Global Transition Complex Transition Compare" );
874 char *str1 = " ??? ";
875 char *str2 = " ??? ";
876 if(LocalTransition == TopAbs_INTERNAL) str1=" INTERNAL ";
877 if(LocalTransition == TopAbs_REVERSED) str1=" REVERSED ";
878 if(LocalTransition == TopAbs_FORWARD) str1=" FORWARD ";
880 if(TangenteOrientation == TopAbs_INTERNAL) str2=" INTERNAL ";
881 if(TangenteOrientation == TopAbs_REVERSED) str2=" REVERSED ";
882 if(TangenteOrientation == TopAbs_FORWARD) str2=" FORWARD ";
884 printf("\n P:%+10.5g Tg2d:%+10.5g , %+10.5g N2d:%+10.5g , %+10.5g Crv:%+10.5g LocalTr:%s TangOrie:%s\n",
885 Param,Tangente.X(),Tangente.Y(),Normale.X(),Normale.Y(),Courbure,str1,str2);
888 ComplexTransition.Compare (Precision::Angular(),
889 Tangente, Normale, Courbure,
890 LocalTransition, TangenteOrientation) ;
893 switch (ComplexTransition.StateBefore()) {
894 case TopAbs_IN : StateBefore = TopAbs_IN ; break ;
895 case TopAbs_OUT : StateBefore = TopAbs_OUT ; break ;
896 case TopAbs_ON : return Standard_False ;
897 case TopAbs_UNKNOWN : return Standard_False ;
899 switch (ComplexTransition.StateAfter()) {
900 case TopAbs_IN : StateAfter = TopAbs_IN ; break ;
901 case TopAbs_OUT : StateAfter = TopAbs_OUT ; break ;
902 case TopAbs_ON : return Standard_False ;
903 case TopAbs_UNKNOWN : return Standard_False ;
909 printf("\n --> StateBef :"); if(StateBefore==TopAbs_IN) printf(" IN "); else printf(" OUT ");
910 printf("\n --> StateAft :"); if(StateAfter==TopAbs_IN) printf(" IN "); else printf(" OUT ");
911 printf("\n------ Fin GlobalTransition\n");
914 Point.SetStateBefore (StateBefore) ;
915 Point.SetStateAfter (StateAfter) ;
916 Point.SetSegmentBeginning (SegmentBegin) ;
917 Point.SetSegmentEnd (SegmentEnd) ;
918 return Standard_True ;
921 //=======================================================================
922 // Function : ComputeDomains
923 // Purpose : Computes the domains of all the hatchings.
924 //=======================================================================
926 void HatchGen_Hatcher::ComputeDomains ()
928 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++)
929 if (myHatchings.IsBound (IndH)) ComputeDomains (IndH) ;
932 //=======================================================================
933 // Function : ComputeDomains
934 // Purpose : Computes the domains of the IndH-th hatching.
935 //=======================================================================
937 void HatchGen_Hatcher::ComputeDomains (const Standard_Integer IndH)
939 #if RAISE_IF_NOSUCHOBJECT
940 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
943 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
944 Hatching.ClrDomains() ;
946 Hatching.IsDone (Standard_False) ;
948 if (!Hatching.TrimDone()) Trim (IndH) ;
949 if (Hatching.Status() != HatchGen_NoProblem) return ;
951 Standard_Boolean Points = myKeepPoints ;
952 Standard_Boolean Segments = myKeepSegments ;
953 Standard_Integer ISav = 0 ;
954 Standard_Boolean SavPnt = Standard_False ;
955 Standard_Integer NbOpenedSegments = 0 ;
956 Standard_Integer NbPnt = Hatching.NbPoints() ;
957 Standard_Integer IPnt =1;
960 //-- cout << "The hatching # " << setw(3) << IndH << " has to be classified" << endl ;
961 HatchGen_Classifier Classifier(myElements,Hatching.ClassificationPoint(),0.0000001);
962 if(Classifier.State() == TopAbs_IN) {
963 HatchGen_Domain domain ;
964 Hatching.AddDomain (domain) ;
966 Hatching.IsDone (Standard_True) ;
970 //for (Standard_Integer IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
971 for (IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
972 Standard_Boolean NoDomain = Hatching.NbDomains() == 0 ;
973 Standard_Boolean FirstPoint = IPnt == 1 ;
974 Standard_Boolean LastPoint = IPnt == NbPnt ;
976 const HatchGen_PointOnHatching& CurPnt = Hatching.Point (IPnt) ;
979 cout << "===== ComputeDomains:: Hatching # " << setw(3) << IndH << " =====" << endl ;
981 cout << "==========================================" << endl ;
985 //-----------------------------------------------------------------------
986 // Calcul des domaines.
987 //-----------------------------------------------------------------------
989 TopAbs_State StateBefore = CurPnt.StateBefore() ;
990 TopAbs_State StateAfter = CurPnt.StateAfter() ;
991 Standard_Boolean SegmentBegin = CurPnt.SegmentBeginning() ;
992 Standard_Boolean SegmentEnd = CurPnt.SegmentEnd() ;
994 HatchGen_Domain domain ;
996 //-----------------------------------------------------------------------
997 // Initialisations dues au premier point.
998 //-----------------------------------------------------------------------
1001 SavPnt = Standard_False ;
1003 NbOpenedSegments = 0 ;
1004 if (SegmentEnd && SegmentBegin) {
1005 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1006 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1008 SavPnt = Standard_True ;
1011 } else if (SegmentEnd) {
1012 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1014 SavPnt = Standard_True ;
1017 } else if (SegmentBegin) {
1018 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1019 if (StateBefore == TopAbs_IN) {
1020 SavPnt = Standard_True ;
1024 if (StateBefore == TopAbs_IN) {
1025 SavPnt = Standard_True ;
1031 //-----------------------------------------------------------------------
1032 // Initialisations dues au dernier point.
1033 //-----------------------------------------------------------------------
1036 if (SegmentEnd && SegmentBegin) {
1037 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1038 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1039 } else if (SegmentEnd) {
1040 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1041 } else if (SegmentBegin) {
1042 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1047 //-----------------------------------------------------------------------
1049 //-----------------------------------------------------------------------
1051 Standard_Boolean ToAppend = Standard_False ;
1053 if (SegmentEnd && SegmentBegin) {
1055 if (StateBefore != TopAbs_IN && StateAfter != TopAbs_IN) {
1056 Hatching.Status (HatchGen_IncompatibleStates) ;
1063 Hatching.Status (HatchGen_IncoherentParity) ;
1066 Hatching.IsDone(Standard_True);
1070 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1071 domain.SetSecondPoint (CurPnt) ;
1072 ToAppend = Standard_True ;
1073 SavPnt = Standard_True ;
1076 Standard_Boolean isININ = (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN);
1077 if (SavPnt && !isININ) {
1079 Hatching.Status (HatchGen_IncoherentParity) ;
1082 Hatching.IsDone(Standard_True);
1086 domain.SetPoints (CurPnt, CurPnt) ;
1087 ToAppend = Standard_True ;
1088 SavPnt = Standard_False ;
1093 } else if (SegmentEnd) {
1096 if (StateAfter == TopAbs_OUT) {
1099 Hatching.Status (HatchGen_IncoherentParity) ;
1102 Hatching.IsDone(Standard_True);
1106 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1107 domain.SetSecondPoint (CurPnt) ;
1108 ToAppend = Standard_True ;
1111 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1112 domain.SetSecondPoint (CurPnt) ;
1113 ToAppend = Standard_True ;
1114 SavPnt = Standard_True ;
1119 if (StateAfter == TopAbs_IN) {
1120 SavPnt = Standard_True ;
1124 NbOpenedSegments-- ;
1126 } else if (SegmentBegin) {
1129 if (StateBefore == TopAbs_OUT) {
1130 SavPnt = Standard_True ;
1136 Hatching.Status (HatchGen_IncoherentParity) ;
1139 Hatching.IsDone(Standard_True);
1144 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1145 domain.SetSecondPoint (CurPnt) ;
1146 ToAppend = Standard_True ;
1147 SavPnt = Standard_True ;
1152 if (StateBefore == TopAbs_IN) {
1155 Hatching.Status (HatchGen_IncoherentParity) ;
1158 Hatching.IsDone(Standard_True);
1163 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1164 domain.SetSecondPoint (CurPnt) ;
1165 ToAppend = Standard_True ;
1166 // Modified by Sergey KHROMOV - Fri Jan 5 12:05:30 2001
1167 // SavPnt = Standard_False ;
1169 SavPnt = Standard_True ;
1171 // Modified by Sergey KHROMOV - Fri Jan 5 12:05:31 2001
1174 NbOpenedSegments++ ;
1177 //-- ???????????????????????????????????????????????????????????????????????????
1178 //-- Solution provisoire (lbr le 11 Aout 97 )
1179 //-- si On a 2 points dont des points OUT OUT ou IN IN qui delimitent une isos
1180 //-- on transforme les transitions
1181 if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
1184 StateAfter = TopAbs_IN;
1186 StateBefore = TopAbs_IN;
1189 //-- ???????????????????????????????????????????????????????????????????????????
1190 if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
1194 Hatching.Status (HatchGen_IncoherentParity) ;
1197 Hatching.IsDone(Standard_True);
1203 domain.SetPoints (CurPnt, CurPnt) ;
1204 ToAppend = Standard_True ;
1205 SavPnt = Standard_True ;
1209 } else if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_IN ) {
1211 SavPnt = Standard_True ;
1214 } else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_OUT) {
1218 Hatching.Status (HatchGen_IncoherentParity) ;
1221 Hatching.IsDone(Standard_True);
1226 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1227 domain.SetSecondPoint (CurPnt) ;
1228 ToAppend = Standard_True ;
1229 SavPnt = Standard_False ;
1232 } else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN ) {
1235 if (NbOpenedSegments == 0) {
1238 Hatching.Status (HatchGen_IncoherentParity) ;
1241 Hatching.IsDone(Standard_True);
1246 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1247 domain.SetSecondPoint (CurPnt) ;
1248 ToAppend = Standard_True ;
1249 SavPnt = Standard_True ;
1255 Hatching.Status (HatchGen_IncoherentParity) ;
1258 Hatching.IsDone(Standard_True);
1263 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1264 domain.SetSecondPoint (CurPnt) ;
1265 ToAppend = Standard_True ;
1266 SavPnt = Standard_True ;
1271 Hatching.Status (HatchGen_IncoherentParity) ;
1274 Hatching.IsDone(Standard_True);
1279 domain.SetPoints (CurPnt, CurPnt) ;
1280 ToAppend = Standard_True ;
1281 SavPnt = Standard_False ;
1289 Hatching.Status (HatchGen_IncompatibleStates) ;
1296 //-----------------------------------------------------------------------
1297 // Ajout du domaine.
1298 //-----------------------------------------------------------------------
1300 if (ToAppend) Hatching.AddDomain (domain) ;
1302 //-----------------------------------------------------------------------
1303 // Traitement lie au dernier point.
1304 //-----------------------------------------------------------------------
1308 domain.SetPoints () ;
1309 ToAppend = Standard_False ;
1311 if (SegmentEnd && SegmentBegin) {
1316 Hatching.Status (HatchGen_IncoherentParity) ;
1319 Hatching.IsDone(Standard_True);
1324 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1325 ToAppend = Standard_True ;
1328 } else if (SegmentEnd) {
1330 if (StateAfter == TopAbs_IN) {
1333 Hatching.Status (HatchGen_IncoherentParity) ;
1336 Hatching.IsDone(Standard_True);
1341 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1342 ToAppend = Standard_True ;
1345 } else if (SegmentBegin) {
1350 Hatching.Status (HatchGen_IncoherentParity) ;
1353 Hatching.IsDone(Standard_True);
1358 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1359 ToAppend = Standard_True ;
1364 if (StateAfter == TopAbs_IN) {
1367 Hatching.Status (HatchGen_IncoherentParity) ;
1370 Hatching.IsDone(Standard_True);
1375 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1376 ToAppend = Standard_True ;
1380 if (ToAppend) Hatching.AddDomain (domain) ;
1384 Hatching.IsDone(Standard_True) ;
1387 //=======================================================================
1388 //=======================================================================
1389 // Category : Results.
1390 //=======================================================================
1391 //=======================================================================
1394 //=======================================================================
1395 // Function : Domain
1396 // Purpose : Returns the IDom-th domain of the IndH-th hatching.
1397 //=======================================================================
1399 const HatchGen_Domain& HatchGen_Hatcher::Domain (const Standard_Integer IndH,
1400 const Standard_Integer IDom) const
1402 #if RAISE_IF_NOSUCHOBJECT
1403 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
1405 const HatchGen_Hatching& Hatching = myHatchings.Find (IndH) ;
1406 StdFail_NotDone_Raise_if (!Hatching.IsDone(), "HatchGen_Hatcher::Domain") ;
1407 #if RAISE_IF_NOSUCHOBJECT
1408 Standard_OutOfRange_Raise_if (IDom < 1 || IDom > Hatching.NbDomains(), "") ;
1410 const HatchGen_Domain& Domain = Hatching.Domain (IDom) ;
1414 //=======================================================================
1415 //=======================================================================
1417 //=======================================================================
1418 //=======================================================================
1420 //=======================================================================
1422 // Purpose : Dumps the hatcher.
1423 //=======================================================================
1425 void HatchGen_Hatcher::Dump () const
1428 cout << "========================================================" << endl ;
1429 cout << "=== Dump of the hatcher ================================" << endl ;
1430 cout << "========================================================" << endl ;
1433 cout << "The points are "
1434 << (myKeepPoints ? " " : "not ")
1437 cout << "The segments are "
1438 << (myKeepSegments ? " " : "not ")
1441 cout << "2D Confusion tolerance : " << myConfusion2d << endl ;
1442 cout << "3D Confusion tolerance : " << myConfusion3d << endl ;
1444 cout << myNbHatchings
1446 << ((myNbHatchings == 1) ? "" : "s")
1448 cout << myNbElements
1450 << ((myNbElements == 1) ? "" : "s")
1454 cout << "========================================================" << endl ;
1455 cout << "=== Hatchings ==========================================" << endl ;
1456 cout << "========================================================" << endl ;
1459 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
1460 cout << "Hatching # " << IndH ;
1461 if (!myHatchings.IsBound (IndH)) {
1462 cout << " is not bound" << endl ;
1464 const HatchGen_Hatching& Hatching = myHatchings.Find (IndH) ;
1465 Standard_Integer NbPnt = Hatching.NbPoints() ;
1466 cout << " contains " << NbPnt << " restriction points :" << endl ;
1467 for (Standard_Integer IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
1468 const HatchGen_PointOnHatching& PntH = Hatching.Point (IPnt) ;
1471 cout << "----------------------------------------------" << endl ;
1476 cout << "========================================================" << endl ;
1477 cout << "=== Elements ===========================================" << endl ;
1478 cout << "========================================================" << endl ;
1481 for (Standard_Integer IndE = 1 ; IndE <= myNbElements ; IndE++) {
1482 cout << "Element # " << IndE ;
1483 if (!myElements.IsBound (IndE)) {
1484 cout << " is not bound" << endl ;
1486 const HatchGen_Element& Element = myElements.Find (IndE) ;
1487 switch (Element.Orientation()) {
1488 case TopAbs_FORWARD : cout << " is FORWARD" << endl ; break ;
1489 case TopAbs_REVERSED : cout << " is REVERSED" << endl ; break ;
1490 case TopAbs_INTERNAL : cout << " is INTERNAL" << endl ; break ;
1491 case TopAbs_EXTERNAL : cout << " is EXTERNAL" << endl ; break ;