1 // Created on: 1993-11-04
2 // Created by: Jean Marc LACHAUME
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
24 #include <HatchGen_Domain.hxx>
25 #include <HatchGen_Domains.hxx>
26 #include <HatchGen_PointOnElement.hxx>
27 #include <HatchGen_PointOnHatching.hxx>
28 #include <IntRes2d_IntersectionPoint.hxx>
29 #include <IntRes2d_IntersectionSegment.hxx>
30 #include <IntRes2d_Transition.hxx>
31 #include <Precision.hxx>
33 #include <TopTrans_CurveTransition.hxx>
35 #define RAISE_IF_NOSUCHOBJECT 0
36 #define TRACE_HATCHER 0
38 //=======================================================================
39 //=======================================================================
40 // Category : General use.
41 //=======================================================================
42 //=======================================================================
44 //=======================================================================
45 // Function : HatchGen_Hatcher
46 // Purpose : Constructor.
47 //=======================================================================
49 HatchGen_Hatcher::HatchGen_Hatcher (const TheIntersector& Intersector,
50 const Standard_Real Confusion2d,
51 const Standard_Real Confusion3d,
52 const Standard_Boolean KeepPnt,
53 const Standard_Boolean KeepSeg) :
54 myIntersector (Intersector) ,
55 myConfusion2d (Confusion2d) ,
56 myConfusion3d (Confusion3d) ,
57 myKeepPoints (KeepPnt) ,
58 myKeepSegments (KeepSeg) ,
64 //=======================================================================
65 // Function : Intersector
66 // Purpose : Sets the associated intersector.
67 //=======================================================================
69 void HatchGen_Hatcher::Intersector (const TheIntersector& Intersector)
71 myIntersector = Intersector ;
72 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
73 if (myHatchings.IsBound (IndH)) {
74 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
75 Hatching.ClrPoints() ;
81 //=======================================================================
82 // Function : Confusion2d
83 // Purpose : Sets the 2dconfusion tolerance.
84 //=======================================================================
86 void HatchGen_Hatcher::Confusion2d (const Standard_Real Confusion)
88 myConfusion2d = Confusion ;
89 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
90 if (myHatchings.IsBound (IndH)) {
91 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
92 Hatching.ClrPoints() ;
98 //=======================================================================
99 // Function : Confusion3d
100 // Purpose : Sets the 3d confusion tolerance.
101 //=======================================================================
103 void HatchGen_Hatcher::Confusion3d (const Standard_Real Confusion)
105 myConfusion3d = Confusion ;
106 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
107 if (myHatchings.IsBound (IndH)) {
108 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
109 Hatching.ClrPoints() ;
114 //=======================================================================
115 // Function : KeepPoints
116 // Purpose : Sets the above flag.
117 //=======================================================================
119 void HatchGen_Hatcher::KeepPoints (const Standard_Boolean Keep)
121 myKeepPoints = Keep ;
122 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
123 if (myHatchings.IsBound (IndH)) {
124 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
125 Hatching.ClrDomains() ;
131 //=======================================================================
132 // Function : KeepSegments
133 // Purpose : Sets the above flag.
134 //=======================================================================
136 void HatchGen_Hatcher::KeepSegments (const Standard_Boolean Keep)
138 myKeepSegments = Keep ;
139 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
140 if (myHatchings.IsBound (IndH)) {
141 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
142 Hatching.ClrDomains() ;
149 //=======================================================================
150 //=======================================================================
151 // Category : Element.
152 //=======================================================================
153 //=======================================================================
156 //=======================================================================
157 // Function : AddElement
158 // Purpose : Adds an element to the Hatcher and returns its index.
159 //=======================================================================
161 Standard_Integer HatchGen_Hatcher::AddElement (const TheCurveE& Curve,
162 const TopAbs_Orientation Orientation)
164 Standard_Integer IndE ;
165 for (IndE = 1 ; IndE <= myNbElements && myElements.IsBound(IndE) ; IndE++) ;
166 if (IndE > myNbElements) {
168 IndE = myNbElements ;
170 HatchGen_Element Element (Curve, Orientation) ;
171 myElements.Bind (IndE, Element) ;
172 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings; IndH++) {
173 if (myHatchings.IsBound(IndH)) {
174 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
175 Hatching.ClrPoints () ;
181 //=======================================================================
182 // Function : RemElement
183 // Purpose : Removes the IndE-th element from the hatcher.
184 //=======================================================================
186 void HatchGen_Hatcher::RemElement (const Standard_Integer IndE)
188 #if RAISE_IF_NOSUCHOBJECT
189 Standard_NoSuchObject_Raise_if (!myElements.IsBound (IndE), "") ;
191 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
192 if (myHatchings.IsBound (IndH)) {
193 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
194 Standard_Boolean DomainsToClear = Standard_False ;
195 for (Standard_Integer IPntH = Hatching.NbPoints() ; IPntH > 0 ; IPntH--) {
196 HatchGen_PointOnHatching PntH = Hatching.ChangePoint (IPntH) ;
197 for (Standard_Integer IPntE = PntH.NbPoints() ; IPntE > 0 ; IPntE--) {
198 if (PntH.Point(IPntE).Index() == IndE) {
199 PntH.RemPoint (IPntE) ;
200 DomainsToClear = Standard_True ;
203 if (PntH.NbPoints() == 0) Hatching.RemPoint (IPntH) ;
205 if (DomainsToClear) Hatching.ClrDomains() ;
208 myElements.UnBind (IndE) ;
209 if (IndE == myNbElements) myNbElements-- ;
212 //=======================================================================
213 // Function : ClrElements
214 // Purpose : Removes all the elements from the hatcher.
215 //=======================================================================
217 void HatchGen_Hatcher::ClrElements ()
219 if (myNbElements != 0) {
220 if (myNbHatchings != 0) {
221 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
222 if (myHatchings.IsBound(IndH)) {
223 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
224 Hatching.ClrPoints() ;
233 //=======================================================================
234 //=======================================================================
235 // Category : Hatching.
236 //=======================================================================
237 //=======================================================================
240 //=======================================================================
241 // Function : AddHatching
242 // Purpose : Adds a hatching to the hatcher and returns its index.
243 //=======================================================================
245 Standard_Integer HatchGen_Hatcher::AddHatching (const TheCurveH& Curve)
247 Standard_Integer IndH ;
248 for (IndH = 1 ; IndH <= myNbHatchings && myHatchings.IsBound(IndH) ; IndH++) ;
249 if (IndH > myNbHatchings) {
251 IndH = myNbHatchings ;
253 HatchGen_Hatching Hatching (Curve) ;
254 myHatchings.Bind (IndH, Hatching) ;
258 //=======================================================================
259 // Function : RemHatching
260 // Purpose : Removes the IndH-th hatching from the hatcher.
261 //=======================================================================
263 void HatchGen_Hatcher::RemHatching (const Standard_Integer IndH)
265 #if RAISE_IF_NOSUCHOBJECT
266 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
268 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
269 Hatching.ClrPoints() ;
270 myHatchings.UnBind (IndH) ;
271 if (IndH == myNbHatchings) myNbHatchings-- ;
274 //=======================================================================
275 // Function : ClrHatchings
276 // Purpose : Removes all the hatchings from the hatcher.
277 //=======================================================================
279 void HatchGen_Hatcher::ClrHatchings ()
281 if (myNbHatchings != 0) {
282 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
283 if (myHatchings.IsBound(IndH)) {
284 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
285 Hatching.ClrPoints() ;
288 myHatchings.Clear() ;
295 //=======================================================================
296 //=======================================================================
297 // Category : Computation - Trimming
298 //=======================================================================
299 //=======================================================================
301 //=======================================================================
303 // Purpose : Trims all the hatchings of the hatcher by all the elements
305 //=======================================================================
307 void HatchGen_Hatcher::Trim ()
309 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++)
310 if (myHatchings.IsBound (IndH))
314 //=======================================================================
316 // Purpose : Adds a hatching to the hatcher and trims it by the elements
317 // already given and returns its index.
318 //=======================================================================
320 Standard_Integer HatchGen_Hatcher::Trim (const TheCurveH& Curve)
322 Standard_Integer IndH = AddHatching (Curve) ;
327 //=======================================================================
329 // Purpose : Trims the IndH-th hatching by the elements already given.
330 //=======================================================================
332 void HatchGen_Hatcher::Trim (const Standard_Integer IndH)
334 #if RAISE_IF_NOSUCHOBJECT
335 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
338 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
340 Hatching.ClrPoints() ;
342 Standard_Boolean OK, AllOK ;
344 AllOK = Standard_True ;
345 for (Standard_Integer IndE = 1 ; IndE <= myNbElements ; IndE++) {
346 if (myElements.IsBound (IndE)) {
347 OK = Trim (IndH, IndE) ;
348 AllOK = AllOK && OK ;
351 Hatching.TrimDone (Standard_True) ;
352 Hatching.TrimFailed (!AllOK) ;
355 for (Standard_Integer IPnt = 1 ; IPnt <= Hatching.NbPoints() ; IPnt++) {
356 HatchGen_PointOnHatching& PntH = Hatching.ChangePoint(IPnt) ;
357 OK = GlobalTransition (PntH) ;
358 AllOK = AllOK && OK ;
360 Hatching.Status (AllOK ? HatchGen_NoProblem : HatchGen_TransitionFailure) ;
366 //=======================================================================
367 // Function : IntersectionPointDump
368 // Purpose : Dump of the intersection point.
369 //=======================================================================
371 static void IntersectionPointDump (const IntRes2d_IntersectionPoint& Pnt,
372 const Standard_Integer Index)
374 Standard_Integer SavedPrecision = cout.precision() ;
375 cout.precision (15) ;
376 cout << "----- IntRes2d:: Point # " << setw(3) << Index << " ---------------" << endl ;
377 cout << "-- U: "<<Pnt.Value().X()<<" V: "<<Pnt.Value().Y()<<endl;
378 cout << "-- Parameter on first : " << Pnt.ParamOnFirst() << endl ;
379 cout << "-- Position on first : " ;
380 switch (Pnt.TransitionOfFirst().PositionOnCurve()) {
381 case IntRes2d_Head : cout << "HEAD" ; break ;
382 case IntRes2d_Middle : cout << "MIDDLE" ; break ;
383 case IntRes2d_End : cout << "END" ; break ;
386 cout << "-- IntRes2d:: Transition on first : " ;
387 switch (Pnt.TransitionOfFirst().TransitionType()) {
388 case IntRes2d_In : cout << "IN" ; break ;
389 case IntRes2d_Out : cout << "OUT" ; break ;
390 case IntRes2d_Touch : cout << "TOUCH" ; break ;
391 case IntRes2d_Undecided : cout << "UNDECIDED" ; break ;
394 if (Pnt.TransitionOfFirst().TransitionType() == IntRes2d_Touch) {
395 cout << "-- IntRes2d:: Situation on first : " ;
396 switch (Pnt.TransitionOfFirst().Situation()) {
397 case IntRes2d_Inside : cout << "INSIDE" ; break ;
398 case IntRes2d_Outside : cout << "OUTSIDE" ; break ;
399 case IntRes2d_Unknown : cout << "UNKNOWN" ; break ;
403 cout << "--------------------------------------------" << endl ;
404 cout << "-- Parameter on second : " << Pnt.ParamOnSecond() << endl ;
405 cout << "-- Position on second : " ;
406 switch (Pnt.TransitionOfSecond().PositionOnCurve()) {
407 case IntRes2d_Head : cout << "HEAD" ; break ;
408 case IntRes2d_Middle : cout << "MIDDLE" ; break ;
409 case IntRes2d_End : cout << "END" ; break ;
412 cout << "-- IntRes2d:: Transition on second : " ;
413 switch (Pnt.TransitionOfSecond().TransitionType()) {
414 case IntRes2d_In : cout << "IN" ; break ;
415 case IntRes2d_Out : cout << "OUT" ; break ;
416 case IntRes2d_Touch : cout << "TOUCH" ; break ;
417 case IntRes2d_Undecided : cout << "UNDECIDED" ; break ;
420 if (Pnt.TransitionOfSecond().TransitionType() == IntRes2d_Touch) {
421 cout << "-- IntRes2d:: Situation on second : " ;
422 switch (Pnt.TransitionOfSecond().Situation()) {
423 case IntRes2d_Inside : cout << "INSIDE" ; break ;
424 case IntRes2d_Outside : cout << "OUTSIDE" ; break ;
425 case IntRes2d_Unknown : cout << "UNKNOWN" ; break ;
429 cout << "--------------------------------------------" << endl ;
430 cout.precision (SavedPrecision) ;
435 //=======================================================================
437 // Purpose : Trims the IndH-th hatching of the hatcher by the IndE th
439 //=======================================================================
441 Standard_Boolean HatchGen_Hatcher::Trim (const Standard_Integer IndH,
442 const Standard_Integer IndE)
444 #if RAISE_IF_NOSUCHOBJECT
445 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
446 Standard_NoSuchObject_Raise_if (!myElements.IsBound (IndE), "") ;
449 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
450 HatchGen_Element& Element = myElements.ChangeFind (IndE) ;
452 TheCurveH hatching = Hatching.ChangeCurve() ;
453 TheCurveE element = Element.ChangeCurve() ;
455 myIntersector.Intersect (hatching, element) ;
458 cout << "--- Hatcher - Trim:: Hatching # " << setw(3);
459 cout << IndH << " with Element # " << setw(3);
460 cout << IndE << " ----------" << endl ;
463 if (!myIntersector.IsDone()) {
464 cout<<" Intersector -> Done = False ";
465 return Standard_False ;
469 if (myIntersector.IsEmpty()) {
470 cout << "No intersection" << endl ;
471 cout << "--------------------------------------------------------------------" << endl ;
475 if (myIntersector.IsEmpty()) return Standard_True ;
478 cout << "Number of intersection points : " << setw(3) << (myIntersector.NbPoints()) << endl ;
479 cout << "Number of intersection segments : " << setw(3) << (myIntersector.NbSegments()) << endl ;
482 //-----------------------------------------------------------------------
483 // Traitement des points d intersection.
484 //-----------------------------------------------------------------------
486 for (Standard_Integer IPntI = 1 ; IPntI <= myIntersector.NbPoints() ; IPntI++) {
487 const IntRes2d_IntersectionPoint& PntI = myIntersector.Point (IPntI) ;
490 IntersectionPointDump (PntI, IPntI) ;
493 HatchGen_PointOnElement PntE (PntI) ;
494 PntE.SetIndex (IndE) ;
496 HatchGen_PointOnHatching PntH (PntI) ;
497 PntH.SetIndex (IndH) ;
498 PntH.AddPoint (PntE, myConfusion2d) ;
500 Hatching.AddPoint (PntH, myConfusion2d) ;
503 //-----------------------------------------------------------------------
504 // Traitement des segments d intersection.
505 //-----------------------------------------------------------------------
507 for (Standard_Integer ISeg = 1 ; ISeg <= myIntersector.NbSegments() ; ISeg++) {
509 const IntRes2d_IntersectionSegment& Seg = myIntersector.Segment (ISeg) ;
512 cout << "----- Segment # " << setw(3) << ISeg << " -------------" << endl ;
515 Standard_Boolean FirstPoint = Seg.HasFirstPoint() ;
516 Standard_Boolean LastPoint = Seg.HasLastPoint() ;
518 //-----------------------------------------------------------------------
519 // Les deux points peuvent etre confondus.
520 //-----------------------------------------------------------------------
522 if (FirstPoint && LastPoint) {
524 const IntRes2d_IntersectionPoint& Pnt1 = Seg.FirstPoint() ;
525 const IntRes2d_IntersectionPoint& Pnt2 = Seg.LastPoint() ;
527 const IntRes2d_Transition& TrsPnt1H = Pnt1.TransitionOfFirst() ;
528 const IntRes2d_Transition& TrsPnt1E = Pnt1.TransitionOfSecond() ;
529 const IntRes2d_Transition& TrsPnt2H = Pnt2.TransitionOfFirst() ;
530 const IntRes2d_Transition& TrsPnt2E = Pnt2.TransitionOfSecond() ;
532 IntRes2d_TypeTrans TypePnt1H = TrsPnt1H.TransitionType() ;
533 IntRes2d_TypeTrans TypePnt1E = TrsPnt1E.TransitionType() ;
534 IntRes2d_TypeTrans TypePnt2H = TrsPnt2H.TransitionType() ;
535 IntRes2d_TypeTrans TypePnt2E = TrsPnt2E.TransitionType() ;
537 //-----------------------------------------------------------------------
538 // Les deux points peuvent etre confondus au regard de la precision du
540 //-----------------------------------------------------------------------
542 Standard_Boolean Conf2d = Abs (Pnt1.ParamOnFirst() - Pnt2.ParamOnFirst()) <= myConfusion2d ;
544 //-----------------------------------------------------------------------
545 // Les deux points peuvent etre `confondus' au regard des intersections.
546 //-----------------------------------------------------------------------
548 Standard_Boolean Conf3d = Standard_False ;
551 Conf3d = Standard_True ;
552 if (Conf3d) Conf3d = TypePnt1H != IntRes2d_Touch && TypePnt1H != IntRes2d_Undecided ;
553 if (Conf3d) Conf3d = TypePnt1E != IntRes2d_Touch && TypePnt1E != IntRes2d_Undecided ;
554 if (Conf3d) Conf3d = TypePnt2H != IntRes2d_Touch && TypePnt2H != IntRes2d_Undecided ;
555 if (Conf3d) Conf3d = TypePnt2E != IntRes2d_Touch && TypePnt2E != IntRes2d_Undecided ;
556 if (Conf3d) Conf3d = TypePnt1H == TypePnt2H && TypePnt1E == TypePnt2E ;
557 if (Conf3d) Conf3d = Pnt1.Value().Distance (Pnt2.Value()) <= myConfusion3d ;
560 if (Conf2d || Conf3d) {
562 HatchGen_PointOnElement PntE ;
563 PntE.SetIndex (IndE) ;
564 PntE.SetParameter ((Pnt1.ParamOnSecond() + Pnt2.ParamOnSecond()) / 2.) ;
565 switch (TrsPnt1E.PositionOnCurve()) {
566 case IntRes2d_Head: {
567 PntE.SetPosition(TopAbs_FORWARD) ;
570 case IntRes2d_Middle: {
571 switch (TrsPnt2E.PositionOnCurve()) {
572 case IntRes2d_Head: {
573 PntE.SetPosition (TopAbs_FORWARD);
576 case IntRes2d_Middle: {
577 PntE.SetPosition (TopAbs_INTERNAL) ;
581 PntE.SetPosition (TopAbs_REVERSED) ;
591 PntE.SetPosition(TopAbs_REVERSED) ;
598 PntE.SetIntersectionType
599 ((PntE.Position() == TopAbs_INTERNAL) ? HatchGen_TRUE : HatchGen_TOUCH) ;
600 PntE.SetStateBefore ((TypePnt1H == IntRes2d_In) ? TopAbs_OUT : TopAbs_IN) ;
601 PntE.SetStateAfter ((TypePnt2H == IntRes2d_In) ? TopAbs_OUT : TopAbs_IN) ;
603 HatchGen_PointOnHatching PntH ;
604 PntH.SetIndex (IndH) ;
605 PntH.SetParameter ((Pnt1.ParamOnFirst() + Pnt2.ParamOnFirst()) / 2.) ;
606 switch (TrsPnt1H.PositionOnCurve()) {
607 case IntRes2d_Head: {
608 PntH.SetPosition (TopAbs_FORWARD) ;
611 case IntRes2d_Middle: {
612 switch (TrsPnt2H.PositionOnCurve()) {
613 case IntRes2d_Head: {
614 PntH.SetPosition (TopAbs_FORWARD) ;
617 case IntRes2d_Middle: {
618 PntH.SetPosition (TopAbs_INTERNAL) ;
622 PntH.SetPosition (TopAbs_REVERSED) ;
632 PntH.SetPosition (TopAbs_REVERSED) ;
640 PntH.AddPoint (PntE, myConfusion2d) ;
641 Hatching.AddPoint (PntH, myConfusion2d) ;
644 IntersectionPointDump (Pnt1, 1) ;
645 IntersectionPointDump (Pnt2, 2) ;
646 cout << "THESE TWO POINTS ARE "
647 << (Conf2d ? "2D" : "3D")
648 << " CONFUSED INTO THE FOLLOWING" << endl ;
655 //-----------------------------------------------------------------------
656 // Traitement du premier point du segment.
657 //-----------------------------------------------------------------------
661 const IntRes2d_IntersectionPoint& PntI = Seg.FirstPoint() ;
664 IntersectionPointDump (PntI, 1) ;
667 HatchGen_PointOnElement PntE (PntI) ;
668 PntE.SetIndex (IndE) ;
669 PntE.SetSegmentBeginning (Standard_True) ;
670 PntE.SetSegmentEnd (Standard_False) ;
672 HatchGen_PointOnHatching PntH (PntI) ;
673 PntH.SetIndex (IndH) ;
674 PntH.AddPoint (PntE, myConfusion2d) ;
676 Hatching.AddPoint (PntH, myConfusion2d) ;
681 cout << "----- Has no first point --------" << endl ;
682 cout << "---------------------------------" << endl ;
687 //-----------------------------------------------------------------------
688 // Traitement du deuxieme point du segment.
689 //-----------------------------------------------------------------------
693 const IntRes2d_IntersectionPoint& PntI = Seg.LastPoint() ;
696 IntersectionPointDump (PntI, 2) ;
699 HatchGen_PointOnElement PntE (PntI) ;
700 PntE.SetIndex (IndE) ;
701 PntE.SetSegmentBeginning (Standard_False) ;
702 PntE.SetSegmentEnd (Standard_True) ;
704 HatchGen_PointOnHatching PntH (PntI) ;
705 PntH.SetIndex (IndH) ;
706 PntH.AddPoint (PntE, myConfusion2d) ;
708 Hatching.AddPoint (PntH, myConfusion2d) ;
713 cout << "----- Has no last point ---------" << endl ;
714 cout << "---------------------------------" << endl ;
719 cout << "--------------------------------------------------------------------" << endl ;
723 return Standard_True;
725 //=======================================================================
726 //=======================================================================
727 // Category : Computation - Domains
728 //=======================================================================
729 //=======================================================================
731 //=======================================================================
732 // Function : GlobalTransition
733 // Purpose : Returns the before and after states of the complex
734 // transition of the IndP-th intersection point of the
736 //=======================================================================
738 Standard_Boolean HatchGen_Hatcher::GlobalTransition (HatchGen_PointOnHatching& Point)
740 TopAbs_State StateBefore = TopAbs_UNKNOWN ;
741 TopAbs_State StateAfter = TopAbs_UNKNOWN ;
742 Standard_Boolean SegmentBegin = Standard_False ;
743 Standard_Boolean SegmentEnd = Standard_False ;
745 gp_Dir2d Tangente2d, Normale2d ;
746 gp_Dir Tangente, Normale ;
747 Standard_Real Courbure ;
749 const TheCurveH& CurveH = HatchingCurve (Point.Index()) ;
751 myIntersector.LocalGeometry(CurveH.Curve(), Point.Parameter(), Tangente2d, Normale2d, Courbure);
753 Tangente.SetCoord (Tangente2d.X(), Tangente2d.Y(), 0.0) ;
754 if (Courbure < Precision::Confusion()) {
755 Normale.SetCoord (-Tangente2d.Y(), Tangente2d.X(), 0.0) ;
757 Normale.SetCoord (Normale2d.X(), Normale2d.Y(), 0.0) ;
760 TopTrans_CurveTransition ComplexTransition ;
761 ComplexTransition.Reset (Tangente, Normale, Courbure) ;
764 printf("\n ----- Global Transition Complex Transition Reset \n");
765 printf("\n P:%+10.5g Tg2d:%+10.5g , %+10.5g N2d:%+10.5g , %+10.5g Crv:%+10.5g\n\n",
766 Point.Parameter(),Tangente.X(),Tangente.Y(),Normale.X(),Normale.Y(),Courbure);
768 for (Standard_Integer IPntE = 1 ; IPntE <= Point.NbPoints() ; IPntE++)
770 const HatchGen_PointOnElement& PntE = Point.Point (IPntE) ;
772 SegmentBegin = SegmentBegin || PntE.SegmentBeginning() ;
773 SegmentEnd = SegmentEnd || PntE.SegmentEnd() ;
775 const HatchGen_Element& Element = myElements.Find (PntE.Index()) ;
776 const TheCurveE& CurveE = Element.Curve() ;
778 TopAbs_Orientation ElementOrientation = Element.Orientation() ;
779 Standard_Boolean ToReverse = (ElementOrientation == TopAbs_REVERSED);
780 Standard_Real Param ;
781 switch (PntE.Position())
783 case TopAbs_FORWARD :
784 Param = ToReverse ? CurveE.LastParameter() : CurveE.FirstParameter() ;
787 case TopAbs_INTERNAL :
788 Param = PntE.Parameter() ;
791 case TopAbs_REVERSED :
792 Param = ToReverse ? CurveE.FirstParameter() : CurveE.LastParameter() ;
801 printf("\n ******** ToReverse: %d Param : %g ANParam : %g \n",ToReverse,Param,PntE.Parameter());
803 Param = PntE.Parameter();
805 myIntersector.LocalGeometry(CurveE.Curve(), Param, Tangente2d, Normale2d, Courbure);
807 //-----------------------------------------------------------------------
808 // Calcul de la transition locale. On suppose les relations suivantes :
809 // - Si l orientation de l element est INTERNAL ==> INTERNAL
810 // - Si l orientation de l element est EXTERNAL ==> EXTERNAL
811 // - Si tangence, on a IN-IN ou OUT-OUT ==> INTERNAL/EXTERNAL
812 // - Sinon, on a IN-OUT ou OUT-IN ==> REVERSED/FORWARD
813 // Les deux dernieres conditions avec l element vu en FORWARD.
814 //-----------------------------------------------------------------------
815 TopAbs_Orientation LocalTransition = TopAbs_EXTERNAL;
817 if (ElementOrientation == TopAbs_INTERNAL)
818 LocalTransition = TopAbs_INTERNAL ;
820 else if (ElementOrientation == TopAbs_EXTERNAL)
821 LocalTransition = TopAbs_EXTERNAL ;
823 else if (PntE.IntersectionType() == HatchGen_TANGENT)
825 if (PntE.Position() == TopAbs_INTERNAL)
827 switch (PntE.StateBefore())
829 case TopAbs_IN : LocalTransition = ToReverse ? TopAbs_EXTERNAL : TopAbs_INTERNAL ; break ;
830 case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_INTERNAL : TopAbs_EXTERNAL ; break ;
836 switch (PntE.StateBefore())
838 case TopAbs_IN : LocalTransition = ToReverse ? TopAbs_FORWARD : TopAbs_REVERSED ; break ;
839 case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD ; break ;
846 switch (PntE.StateBefore())
848 case TopAbs_IN : LocalTransition = ToReverse ? TopAbs_FORWARD : TopAbs_REVERSED ; break ;
849 case TopAbs_OUT : LocalTransition = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD ; break ;
854 //-----------------------------------------------------------------------
855 // Orientation de la tangente au point d interference.
856 //-----------------------------------------------------------------------
857 TopAbs_Orientation TangenteOrientation = TopAbs_FORWARD;
858 switch (PntE.Position())
860 case TopAbs_FORWARD : TangenteOrientation = ToReverse ? TopAbs_REVERSED : TopAbs_FORWARD ; break ;
861 case TopAbs_INTERNAL : TangenteOrientation = TopAbs_INTERNAL ; break ;
862 case TopAbs_REVERSED : TangenteOrientation = ToReverse ? TopAbs_FORWARD : TopAbs_REVERSED ; break ;
868 //-----------------------------------------------------------------------
869 // Proprietes geometriques.
870 //-----------------------------------------------------------------------
873 Tangente.SetCoord (-Tangente2d.X(), -Tangente2d.Y(), 0.0) ;
875 Tangente.SetCoord ( Tangente2d.X(), Tangente2d.Y(), 0.0) ;
877 Normale.SetCoord ( Normale2d.X(), Normale2d.Y(), 0.0) ;
880 printf("\n \n----- Global Transition Complex Transition Compare" );
881 char *str1 = " ??? ";
882 char *str2 = " ??? ";
883 if(LocalTransition == TopAbs_INTERNAL) str1=" INTERNAL ";
884 if(LocalTransition == TopAbs_REVERSED) str1=" REVERSED ";
885 if(LocalTransition == TopAbs_FORWARD) str1=" FORWARD ";
887 if(TangenteOrientation == TopAbs_INTERNAL) str2=" INTERNAL ";
888 if(TangenteOrientation == TopAbs_REVERSED) str2=" REVERSED ";
889 if(TangenteOrientation == TopAbs_FORWARD) str2=" FORWARD ";
891 printf("\n P:%+10.5g Tg2d:%+10.5g , %+10.5g N2d:%+10.5g , %+10.5g Crv:%+10.5g LocalTr:%s TangOrie:%s\n",
892 Param,Tangente.X(),Tangente.Y(),Normale.X(),Normale.Y(),Courbure,str1,str2);
895 ComplexTransition.Compare (Precision::Angular(),
896 Tangente, Normale, Courbure,
897 LocalTransition, TangenteOrientation) ;
900 switch (ComplexTransition.StateBefore()) {
901 case TopAbs_IN : StateBefore = TopAbs_IN ; break ;
902 case TopAbs_OUT : StateBefore = TopAbs_OUT ; break ;
903 case TopAbs_ON : return Standard_False ;
904 case TopAbs_UNKNOWN : return Standard_False ;
906 switch (ComplexTransition.StateAfter()) {
907 case TopAbs_IN : StateAfter = TopAbs_IN ; break ;
908 case TopAbs_OUT : StateAfter = TopAbs_OUT ; break ;
909 case TopAbs_ON : return Standard_False ;
910 case TopAbs_UNKNOWN : return Standard_False ;
916 printf("\n --> StateBef :"); if(StateBefore==TopAbs_IN) printf(" IN "); else printf(" OUT ");
917 printf("\n --> StateAft :"); if(StateAfter==TopAbs_IN) printf(" IN "); else printf(" OUT ");
918 printf("\n------ Fin GlobalTransition\n");
921 Point.SetStateBefore (StateBefore) ;
922 Point.SetStateAfter (StateAfter) ;
923 Point.SetSegmentBeginning (SegmentBegin) ;
924 Point.SetSegmentEnd (SegmentEnd) ;
925 return Standard_True ;
928 //=======================================================================
929 // Function : ComputeDomains
930 // Purpose : Computes the domains of all the hatchings.
931 //=======================================================================
933 void HatchGen_Hatcher::ComputeDomains ()
935 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++)
936 if (myHatchings.IsBound (IndH)) ComputeDomains (IndH) ;
939 //=======================================================================
940 // Function : ComputeDomains
941 // Purpose : Computes the domains of the IndH-th hatching.
942 //=======================================================================
944 void HatchGen_Hatcher::ComputeDomains (const Standard_Integer IndH)
946 #if RAISE_IF_NOSUCHOBJECT
947 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
950 HatchGen_Hatching& Hatching = myHatchings.ChangeFind (IndH) ;
951 Hatching.ClrDomains() ;
953 Hatching.IsDone (Standard_False) ;
955 if (!Hatching.TrimDone()) Trim (IndH) ;
956 if (Hatching.Status() != HatchGen_NoProblem) return ;
958 Standard_Boolean Points = myKeepPoints ;
959 Standard_Boolean Segments = myKeepSegments ;
960 Standard_Integer ISav = 0 ;
961 Standard_Boolean SavPnt = Standard_False ;
962 Standard_Integer NbOpenedSegments = 0 ;
963 Standard_Integer NbPnt = Hatching.NbPoints() ;
964 Standard_Integer IPnt =1;
967 //-- cout << "The hatching # " << setw(3) << IndH << " has to be classified" << endl ;
968 HatchGen_Classifier Classifier(myElements,Hatching.ClassificationPoint(),0.0000001);
969 if(Classifier.State() == TopAbs_IN) {
970 HatchGen_Domain domain ;
971 Hatching.AddDomain (domain) ;
973 Hatching.IsDone (Standard_True) ;
977 //for (Standard_Integer IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
978 for (IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
979 Standard_Boolean NoDomain = Hatching.NbDomains() == 0 ;
980 Standard_Boolean FirstPoint = IPnt == 1 ;
981 Standard_Boolean LastPoint = IPnt == NbPnt ;
983 const HatchGen_PointOnHatching& CurPnt = Hatching.Point (IPnt) ;
986 cout << "===== ComputeDomains:: Hatching # " << setw(3) << IndH << " =====" << endl ;
988 cout << "==========================================" << endl ;
992 //-----------------------------------------------------------------------
993 // Calcul des domaines.
994 //-----------------------------------------------------------------------
996 TopAbs_State StateBefore = CurPnt.StateBefore() ;
997 TopAbs_State StateAfter = CurPnt.StateAfter() ;
998 Standard_Boolean SegmentBegin = CurPnt.SegmentBeginning() ;
999 Standard_Boolean SegmentEnd = CurPnt.SegmentEnd() ;
1001 HatchGen_Domain domain ;
1003 //-----------------------------------------------------------------------
1004 // Initialisations dues au premier point.
1005 //-----------------------------------------------------------------------
1008 SavPnt = Standard_False ;
1010 NbOpenedSegments = 0 ;
1011 if (SegmentEnd && SegmentBegin) {
1012 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1013 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1015 SavPnt = Standard_True ;
1018 } else if (SegmentEnd) {
1019 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1021 SavPnt = Standard_True ;
1024 } else if (SegmentBegin) {
1025 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1026 if (StateBefore == TopAbs_IN) {
1027 SavPnt = Standard_True ;
1031 if (StateBefore == TopAbs_IN) {
1032 SavPnt = Standard_True ;
1038 //-----------------------------------------------------------------------
1039 // Initialisations dues au dernier point.
1040 //-----------------------------------------------------------------------
1043 if (SegmentEnd && SegmentBegin) {
1044 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1045 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1046 } else if (SegmentEnd) {
1047 if (StateAfter == TopAbs_UNKNOWN) StateAfter = TopAbs_IN ;
1048 } else if (SegmentBegin) {
1049 if (StateBefore == TopAbs_UNKNOWN) StateBefore = TopAbs_IN ;
1054 //-----------------------------------------------------------------------
1056 //-----------------------------------------------------------------------
1058 Standard_Boolean ToAppend = Standard_False ;
1060 if (SegmentEnd && SegmentBegin) {
1062 if (StateBefore != TopAbs_IN && StateAfter != TopAbs_IN) {
1063 Hatching.Status (HatchGen_IncompatibleStates) ;
1070 Hatching.Status (HatchGen_IncoherentParity) ;
1073 Hatching.IsDone(Standard_True);
1077 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1078 domain.SetSecondPoint (CurPnt) ;
1079 ToAppend = Standard_True ;
1080 SavPnt = Standard_True ;
1083 Standard_Boolean isININ = (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN);
1084 if (SavPnt && !isININ) {
1086 Hatching.Status (HatchGen_IncoherentParity) ;
1089 Hatching.IsDone(Standard_True);
1093 domain.SetPoints (CurPnt, CurPnt) ;
1094 ToAppend = Standard_True ;
1095 SavPnt = Standard_False ;
1100 } else if (SegmentEnd) {
1103 if (StateAfter == TopAbs_OUT) {
1106 Hatching.Status (HatchGen_IncoherentParity) ;
1109 Hatching.IsDone(Standard_True);
1113 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1114 domain.SetSecondPoint (CurPnt) ;
1115 ToAppend = Standard_True ;
1118 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1119 domain.SetSecondPoint (CurPnt) ;
1120 ToAppend = Standard_True ;
1121 SavPnt = Standard_True ;
1126 if (StateAfter == TopAbs_IN) {
1127 SavPnt = Standard_True ;
1131 NbOpenedSegments-- ;
1133 } else if (SegmentBegin) {
1136 if (StateBefore == TopAbs_OUT) {
1137 SavPnt = Standard_True ;
1143 Hatching.Status (HatchGen_IncoherentParity) ;
1146 Hatching.IsDone(Standard_True);
1151 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1152 domain.SetSecondPoint (CurPnt) ;
1153 ToAppend = Standard_True ;
1154 SavPnt = Standard_True ;
1159 if (StateBefore == TopAbs_IN) {
1162 Hatching.Status (HatchGen_IncoherentParity) ;
1165 Hatching.IsDone(Standard_True);
1170 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1171 domain.SetSecondPoint (CurPnt) ;
1172 ToAppend = Standard_True ;
1173 // Modified by Sergey KHROMOV - Fri Jan 5 12:05:30 2001
1174 // SavPnt = Standard_False ;
1176 SavPnt = Standard_True ;
1178 // Modified by Sergey KHROMOV - Fri Jan 5 12:05:31 2001
1181 NbOpenedSegments++ ;
1184 //-- ???????????????????????????????????????????????????????????????????????????
1185 //-- Solution provisoire (lbr le 11 Aout 97 )
1186 //-- si On a 2 points dont des points OUT OUT ou IN IN qui delimitent une isos
1187 //-- on transforme les transitions
1188 if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
1191 StateAfter = TopAbs_IN;
1193 StateBefore = TopAbs_IN;
1196 //-- ???????????????????????????????????????????????????????????????????????????
1197 if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_OUT) {
1201 Hatching.Status (HatchGen_IncoherentParity) ;
1204 Hatching.IsDone(Standard_True);
1210 domain.SetPoints (CurPnt, CurPnt) ;
1211 ToAppend = Standard_True ;
1212 SavPnt = Standard_True ;
1216 } else if (StateBefore == TopAbs_OUT && StateAfter == TopAbs_IN ) {
1218 SavPnt = Standard_True ;
1221 } else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_OUT) {
1225 Hatching.Status (HatchGen_IncoherentParity) ;
1228 Hatching.IsDone(Standard_True);
1233 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1234 domain.SetSecondPoint (CurPnt) ;
1235 ToAppend = Standard_True ;
1236 SavPnt = Standard_False ;
1239 } else if (StateBefore == TopAbs_IN && StateAfter == TopAbs_IN ) {
1242 if (NbOpenedSegments == 0) {
1245 Hatching.Status (HatchGen_IncoherentParity) ;
1248 Hatching.IsDone(Standard_True);
1253 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1254 domain.SetSecondPoint (CurPnt) ;
1255 ToAppend = Standard_True ;
1256 SavPnt = Standard_True ;
1262 Hatching.Status (HatchGen_IncoherentParity) ;
1265 Hatching.IsDone(Standard_True);
1270 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1271 domain.SetSecondPoint (CurPnt) ;
1272 ToAppend = Standard_True ;
1273 SavPnt = Standard_True ;
1278 Hatching.Status (HatchGen_IncoherentParity) ;
1281 Hatching.IsDone(Standard_True);
1286 domain.SetPoints (CurPnt, CurPnt) ;
1287 ToAppend = Standard_True ;
1288 SavPnt = Standard_False ;
1296 Hatching.Status (HatchGen_IncompatibleStates) ;
1303 //-----------------------------------------------------------------------
1304 // Ajout du domaine.
1305 //-----------------------------------------------------------------------
1307 if (ToAppend) Hatching.AddDomain (domain) ;
1309 //-----------------------------------------------------------------------
1310 // Traitement lie au dernier point.
1311 //-----------------------------------------------------------------------
1315 domain.SetPoints () ;
1316 ToAppend = Standard_False ;
1318 if (SegmentEnd && SegmentBegin) {
1323 Hatching.Status (HatchGen_IncoherentParity) ;
1326 Hatching.IsDone(Standard_True);
1331 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1332 ToAppend = Standard_True ;
1335 } else if (SegmentEnd) {
1337 if (StateAfter == TopAbs_IN) {
1340 Hatching.Status (HatchGen_IncoherentParity) ;
1343 Hatching.IsDone(Standard_True);
1348 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1349 ToAppend = Standard_True ;
1352 } else if (SegmentBegin) {
1357 Hatching.Status (HatchGen_IncoherentParity) ;
1360 Hatching.IsDone(Standard_True);
1365 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1366 ToAppend = Standard_True ;
1371 if (StateAfter == TopAbs_IN) {
1374 Hatching.Status (HatchGen_IncoherentParity) ;
1377 Hatching.IsDone(Standard_True);
1382 if (ISav != 0) domain.SetFirstPoint (Hatching.Point(ISav)) ;
1383 ToAppend = Standard_True ;
1387 if (ToAppend) Hatching.AddDomain (domain) ;
1391 Hatching.IsDone(Standard_True) ;
1394 //=======================================================================
1395 //=======================================================================
1396 // Category : Results.
1397 //=======================================================================
1398 //=======================================================================
1401 //=======================================================================
1402 // Function : Domain
1403 // Purpose : Returns the IDom-th domain of the IndH-th hatching.
1404 //=======================================================================
1406 const HatchGen_Domain& HatchGen_Hatcher::Domain (const Standard_Integer IndH,
1407 const Standard_Integer IDom) const
1409 #if RAISE_IF_NOSUCHOBJECT
1410 Standard_NoSuchObject_Raise_if (!myHatchings.IsBound (IndH), "") ;
1412 const HatchGen_Hatching& Hatching = myHatchings.Find (IndH) ;
1413 StdFail_NotDone_Raise_if (!Hatching.IsDone(), "HatchGen_Hatcher::Domain") ;
1414 #if RAISE_IF_NOSUCHOBJECT
1415 Standard_OutOfRange_Raise_if (IDom < 1 || IDom > Hatching.NbDomains(), "") ;
1417 const HatchGen_Domain& Domain = Hatching.Domain (IDom) ;
1421 //=======================================================================
1422 //=======================================================================
1424 //=======================================================================
1425 //=======================================================================
1427 //=======================================================================
1429 // Purpose : Dumps the hatcher.
1430 //=======================================================================
1432 void HatchGen_Hatcher::Dump () const
1435 cout << "========================================================" << endl ;
1436 cout << "=== Dump of the hatcher ================================" << endl ;
1437 cout << "========================================================" << endl ;
1440 cout << "The points are "
1441 << (myKeepPoints ? " " : "not ")
1444 cout << "The segments are "
1445 << (myKeepSegments ? " " : "not ")
1448 cout << "2D Confusion tolerance : " << myConfusion2d << endl ;
1449 cout << "3D Confusion tolerance : " << myConfusion3d << endl ;
1451 cout << myNbHatchings
1453 << ((myNbHatchings == 1) ? "" : "s")
1455 cout << myNbElements
1457 << ((myNbElements == 1) ? "" : "s")
1461 cout << "========================================================" << endl ;
1462 cout << "=== Hatchings ==========================================" << endl ;
1463 cout << "========================================================" << endl ;
1466 for (Standard_Integer IndH = 1 ; IndH <= myNbHatchings ; IndH++) {
1467 cout << "Hatching # " << IndH ;
1468 if (!myHatchings.IsBound (IndH)) {
1469 cout << " is not bound" << endl ;
1471 const HatchGen_Hatching& Hatching = myHatchings.Find (IndH) ;
1472 Standard_Integer NbPnt = Hatching.NbPoints() ;
1473 cout << " contains " << NbPnt << " restriction points :" << endl ;
1474 for (Standard_Integer IPnt = 1 ; IPnt <= NbPnt ; IPnt++) {
1475 const HatchGen_PointOnHatching& PntH = Hatching.Point (IPnt) ;
1478 cout << "----------------------------------------------" << endl ;
1483 cout << "========================================================" << endl ;
1484 cout << "=== Elements ===========================================" << endl ;
1485 cout << "========================================================" << endl ;
1488 for (Standard_Integer IndE = 1 ; IndE <= myNbElements ; IndE++) {
1489 cout << "Element # " << IndE ;
1490 if (!myElements.IsBound (IndE)) {
1491 cout << " is not bound" << endl ;
1493 const HatchGen_Element& Element = myElements.Find (IndE) ;
1494 switch (Element.Orientation()) {
1495 case TopAbs_FORWARD : cout << " is FORWARD" << endl ; break ;
1496 case TopAbs_REVERSED : cout << " is REVERSED" << endl ; break ;
1497 case TopAbs_INTERNAL : cout << " is INTERNAL" << endl ; break ;
1498 case TopAbs_EXTERNAL : cout << " is EXTERNAL" << endl ; break ;