1 // Created on: 1995-08-07
2 // Created by: Modelistation
3 // Copyright (c) 1995-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.
18 #include <Adaptor2d_Curve2d.hxx>
19 #include <Adaptor3d_IsoCurve.hxx>
20 #include <Bnd_Box.hxx>
21 #include <Bnd_Box2d.hxx>
22 #include <BndLib_Add2dCurve.hxx>
23 #include <BRepAdaptor_HSurface.hxx>
24 #include <GCPnts_QuasiUniformDeflection.hxx>
25 #include <Geom_BezierSurface.hxx>
26 #include <Geom_BSplineSurface.hxx>
27 #include <Geom_Surface.hxx>
28 #include <GeomAbs_SurfaceType.hxx>
29 #include <GeomAdaptor_Curve.hxx>
31 #include <gp_Pnt2d.hxx>
32 #include <Graphic3d_ArrayOfPolylines.hxx>
33 #include <Graphic3d_AspectLine3d.hxx>
34 #include <Graphic3d_Group.hxx>
35 #include <Hatch_Hatcher.hxx>
36 #include <Precision.hxx>
37 #include <Prs3d_IsoAspect.hxx>
38 #include <Prs3d_Presentation.hxx>
39 #include <StdPrs_DeflectionCurve.hxx>
40 #include <StdPrs_ToolRFace.hxx>
41 #include <StdPrs_WFDeflectionRestrictedFace.hxx>
42 #include <TColgp_SequenceOfPnt2d.hxx>
44 #ifdef OCCT_DEBUG_MESH
45 #include <OSD_Chronometer.hxx>
46 extern OSD_Chronometer FFaceTimer1,FFaceTimer2,FFaceTimer3,FFaceTimer4;
50 //==================================================================
51 // function: FindLimits
53 //==================================================================
54 static void FindLimits(const Adaptor3d_Curve& aCurve,
55 const Standard_Real aLimit,
59 First = Max(aCurve.FirstParameter(), First);
60 Last = Min(aCurve.LastParameter(), Last);
61 Standard_Boolean firstInf = Precision::IsNegativeInfinite(First);
62 Standard_Boolean lastInf = Precision::IsPositiveInfinite(Last);
64 if (firstInf || lastInf) {
66 Standard_Real delta = 1;
67 if (firstInf && lastInf) {
74 } while (P1.Distance(P2) < aLimit);
82 } while (P1.Distance(P2) < aLimit);
90 } while (P1.Distance(P2) < aLimit);
97 //=========================================================================
100 //=========================================================================
101 void StdPrs_WFDeflectionRestrictedFace::Add
102 (const Handle (Prs3d_Presentation)& aPresentation,
103 const Handle(BRepAdaptor_HSurface)& aFace,
104 const Standard_Boolean DrawUIso,
105 const Standard_Boolean DrawVIso,
106 const Standard_Real Deflection,
107 const Standard_Integer NBUiso,
108 const Standard_Integer NBViso,
109 const Handle(Prs3d_Drawer)& aDrawer,
110 Prs3d_NListOfSequenceOfPnt& Curves) {
112 #ifdef OCCT_DEBUG_MESH
116 StdPrs_ToolRFace ToolRst (aFace);
117 Standard_Real UF, UL, VF, VL;
118 UF = aFace->FirstUParameter();
119 UL = aFace->LastUParameter();
120 VF = aFace->FirstVParameter();
121 VL = aFace->LastVParameter();
123 Standard_Real aLimit = aDrawer->MaximalParameterValue();
125 // compute bounds of the restriction
126 Standard_Real UMin,UMax,VMin,VMax;
127 //Standard_Real u,v,step;
128 Standard_Integer i;//,nbPoints = 10;
130 UMin = Max(UF, -aLimit);
131 UMax = Min(UL, aLimit);
132 VMin = Max(VF, -aLimit);
133 VMax = Min(VL, aLimit);
136 // update min max for the hatcher.
138 Standard_Real U1, U2;
140 Standard_Real ddefle= Max(UMax-UMin, VMax-VMin) * aDrawer->DeviationCoefficient();
141 TColgp_SequenceOfPnt2d tabP;
142 Standard_Real aHatchingTol = 1.e100;
144 UMin = VMin = 1.e100;
145 UMax = VMax = -1.e100;
147 for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
148 TopAbs_Orientation Orient = ToolRst.Orientation();
149 const Adaptor2d_Curve2d* TheRCurve = &ToolRst.Value();
150 if (TheRCurve->GetType() != GeomAbs_Line) {
151 GCPnts_QuasiUniformDeflection UDP(*TheRCurve, ddefle);
153 Standard_Integer NumberOfPoints = UDP.NbPoints();
154 if ( NumberOfPoints >= 2 ) {
155 dummypnt = UDP.Value(1);
156 P2.SetCoord(dummypnt.X(), dummypnt.Y());
157 UMin = Min(P2.X(), UMin);
158 UMax = Max(P2.X(), UMax);
159 VMin = Min(P2.Y(), VMin);
160 VMax = Max(P2.Y(), VMax);
161 for (i = 2; i <= NumberOfPoints; i++) {
163 dummypnt = UDP.Value(i);
164 P2.SetCoord(dummypnt.X(), dummypnt.Y());
165 UMin = Min(P2.X(), UMin);
166 UMax = Max(P2.X(), UMax);
167 VMin = Min(P2.Y(), VMin);
168 VMax = Max(P2.Y(), VMax);
169 aHatchingTol = Min(P1.SquareDistance(P2), aHatchingTol);
171 if(Orient == TopAbs_FORWARD ) {
172 //isobuild.Trim(P1,P2);
177 //isobuild.Trim(P2,P1);
185 std::cout << "Cannot evaluate curve on surface"<<std::endl;
190 U1 = TheRCurve->FirstParameter();
191 U2 = TheRCurve->LastParameter();
192 // MSV 17.08.06 OCC13144: U2 occured less than U1, to overcome it
193 // ensure that distance U2-U1 is not greater than aLimit*2,
194 // if greater then choose an origin and use aLimit to define
196 Standard_Real aOrigin = 0.;
197 if (!Precision::IsNegativeInfinite(U1) || !Precision::IsPositiveInfinite(U2)) {
198 if (Precision::IsNegativeInfinite(U1))
199 aOrigin = U2 - aLimit;
200 else if (Precision::IsPositiveInfinite(U2))
201 aOrigin = U1 + aLimit;
203 aOrigin = (U1 + U2) * 0.5;
205 U1 = Max(aOrigin - aLimit, U1);
206 U2 = Min(aOrigin + aLimit, U2);
207 P1 = TheRCurve->Value(U1);
208 P2 = TheRCurve->Value(U2);
209 UMin = Min(P1.X(), UMin);
210 UMax = Max(P1.X(), UMax);
211 VMin = Min(P1.Y(), VMin);
212 VMax = Max(P1.Y(), VMax);
213 UMin = Min(P2.X(), UMin);
214 UMax = Max(P2.X(), UMax);
215 VMin = Min(P2.Y(), VMin);
216 VMax = Max(P2.Y(), VMax);
217 aHatchingTol = Min(P1.SquareDistance(P2), aHatchingTol);
219 if(Orient == TopAbs_FORWARD ) {
220 // isobuild.Trim(P1,P2);
225 //isobuild.Trim(P2,P1);
234 #ifdef OCCT_DEBUG_MESH
240 // Compute the hatching tolerance.
242 aHatchingTol = Max(Precision::Confusion(), aHatchingTol);
243 aHatchingTol = Min(1.e-5, aHatchingTol);
246 Hatch_Hatcher isobuild(aHatchingTol, ToolRst.IsOriented());
247 Standard_Boolean UClosed = aFace->IsUClosed();
248 Standard_Boolean VClosed = aFace->IsVClosed();
251 UMin = UMin + ( UMax - UMin) /1000.;
252 UMax = UMax - ( UMax - UMin) /1000.;
256 VMin = VMin + ( VMax - VMin) /1000.;
257 VMax = VMax - ( VMax - VMin) /1000.;
262 UClosed = Standard_False; // En attendant un hatcher de course.
263 Standard_Real du= UClosed ? (UMax-UMin)/NBUiso : (UMax-UMin)/(1+NBUiso);
264 for (i=1; i<=NBUiso;i++){
265 isobuild.AddXLine(UMin+du*i);
271 VClosed = Standard_False;
272 Standard_Real dv= VClosed ?(VMax-VMin)/NBViso : (VMax-VMin)/(1+NBViso);
273 for (i=1; i<=NBViso;i++){
274 isobuild.AddYLine(VMin+dv*i);
279 #ifdef OCCT_DEBUG_MESH
285 Standard_Integer ll = tabP.Length();
286 for (i = 1; i <= ll; i+=2) {
287 isobuild.Trim(tabP(i),tabP(i+1));
291 #ifdef OCCT_DEBUG_MESH
298 Adaptor3d_IsoCurve anIso;
300 Handle(Geom_Curve) BC;
301 const BRepAdaptor_Surface& BS = *(BRepAdaptor_Surface*)&(aFace->Surface());
302 GeomAbs_SurfaceType thetype = aFace->GetType();
304 Standard_Integer NumberOfLines = isobuild.NbLines();
305 Handle(Geom_Surface) GB;
306 if (thetype == GeomAbs_BezierSurface) {
309 else if (thetype == GeomAbs_BSplineSurface){
313 Standard_Real anAngle = aDrawer->DeviationAngle();
315 for (i = 1; i <= NumberOfLines; i++) {
316 Standard_Integer NumberOfIntervals = isobuild.NbIntervals(i);
317 Standard_Real Coord = isobuild.Coordinate(i);
318 for (Standard_Integer j = 1; j <= NumberOfIntervals; j++) {
319 Standard_Real b1=isobuild.Start(i,j),b2=isobuild.End(i,j);
323 if (isobuild.IsXLine(i))
324 BC = GB->UIso(Coord);
326 BC = GB->VIso(Coord);
327 GeomAdaptor_Curve GC(BC);
328 FindLimits(GC, aLimit,b1, b2);
329 if (b2-b1>Precision::Confusion()) {
330 Handle(TColgp_HSequenceOfPnt) Points = new TColgp_HSequenceOfPnt;
331 StdPrs_DeflectionCurve::Add (aPresentation, GC, b1, b2, Deflection,
332 Points->ChangeSequence(), anAngle, Standard_False);
333 Curves.Append(Points);
337 if (isobuild.IsXLine(i))
338 anIso.Load(GeomAbs_IsoU,Coord,b1,b2);
340 anIso.Load(GeomAbs_IsoV,Coord,b1,b2);
341 FindLimits(anIso, aLimit,b1, b2);
342 if (b2-b1>Precision::Confusion()) {
343 Handle(TColgp_HSequenceOfPnt) Points = new TColgp_HSequenceOfPnt;
344 StdPrs_DeflectionCurve::Add (aPresentation, anIso, b1, b2, Deflection,
345 Points->ChangeSequence(), anAngle, Standard_False);
346 Curves.Append(Points);
351 #ifdef OCCT_DEBUG_MESH
357 //=========================================================================
360 //=========================================================================
361 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::Match
362 (const Standard_Real X,
363 const Standard_Real Y,
364 const Standard_Real Z,
365 const Standard_Real aDistance,
366 const Handle(BRepAdaptor_HSurface)& aFace,
367 const Handle(Prs3d_Drawer)& aDrawer,
368 const Standard_Boolean DrawUIso,
369 const Standard_Boolean DrawVIso,
370 const Standard_Real Deflection,
371 const Standard_Integer NBUiso,
372 const Standard_Integer NBViso)
375 StdPrs_ToolRFace ToolRst (aFace);
376 const Standard_Real aLimit = aDrawer->MaximalParameterValue();
378 // compute bounds of the restriction
379 Standard_Real UMin,UMax,VMin,VMax;
380 Standard_Real u,v,step;
381 Standard_Integer i,nbPoints = 10;
382 UMin = VMin = RealLast();
383 UMax = VMax = RealFirst();
385 for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
386 const Adaptor2d_Curve2d* TheRCurve = &ToolRst.Value();
387 u = TheRCurve->FirstParameter();
388 v = TheRCurve->LastParameter();
389 step = ( v - u) / nbPoints;
390 for (i = 0; i <= nbPoints; i++) {
391 gp_Pnt2d P = TheRCurve->Value(u);
392 if (P.X() < UMin) UMin = P.X();
393 if (P.X() > UMax) UMax = P.X();
394 if (P.Y() < VMin) VMin = P.Y();
395 if (P.Y() > VMax) VMax = P.Y();
401 Hatch_Hatcher isobuild(1.e-5,ToolRst.IsOriented());
402 Standard_Boolean UClosed = aFace->IsUClosed();
403 Standard_Boolean VClosed = aFace->IsVClosed();
406 UMin = UMin + ( UMax - UMin) /1000.;
407 UMax = UMax - ( UMax - UMin) /1000.;
411 VMin = VMin + ( VMax - VMin) /1000.;
412 VMax = VMax - ( VMax - VMin) /1000.;
417 UClosed = Standard_False; // En attendant un hatcher de course.
418 Standard_Real du= UClosed ? (UMax-UMin)/NBUiso : (UMax-UMin)/(1+NBUiso);
419 for (i=1; i<=NBUiso;i++){
420 isobuild.AddXLine(UMin+du*i);
426 VClosed = Standard_False;
427 Standard_Real dv= VClosed ?(VMax-VMin)/NBViso : (VMax-VMin)/(1+NBViso);
428 for (i=1; i<=NBViso;i++){
429 isobuild.AddYLine(VMin+dv*i);
437 for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
438 TopAbs_Orientation Orient = ToolRst.Orientation();
439 const Adaptor2d_Curve2d* TheRCurve = &ToolRst.Value();
440 GCPnts_QuasiUniformDeflection UDP(*TheRCurve, Deflection);
442 Standard_Integer NumberOfPoints = UDP.NbPoints();
443 if ( NumberOfPoints >= 2 ) {
444 dummypnt = UDP.Value(1);
445 P2.SetCoord(dummypnt.X(), dummypnt.Y());
446 for (i = 2; i <= NumberOfPoints; i++) {
448 dummypnt = UDP.Value(i);
449 P2.SetCoord(dummypnt.X(), dummypnt.Y());
450 if(Orient == TopAbs_FORWARD )
451 isobuild.Trim(P1,P2);
453 isobuild.Trim(P2,P1);
459 std::cout << "Cannot evaluate curve on surface"<<std::endl;
466 Adaptor3d_IsoCurve anIso;
468 Standard_Integer NumberOfLines = isobuild.NbLines();
469 Standard_Real anAngle = aDrawer->DeviationAngle();
471 for (i = 1; i <= NumberOfLines; i++) {
472 Standard_Integer NumberOfIntervals = isobuild.NbIntervals(i);
473 Standard_Real Coord = isobuild.Coordinate(i);
474 for (Standard_Integer j = 1; j <= NumberOfIntervals; j++) {
475 Standard_Real b1=isobuild.Start(i,j),b2=isobuild.End(i,j);
477 b1 = b1 == RealFirst() ? - aLimit : b1;
478 b2 = b2 == RealLast() ? aLimit : b2;
480 if (isobuild.IsXLine(i))
481 anIso.Load(GeomAbs_IsoU,Coord,b1,b2);
483 anIso.Load(GeomAbs_IsoV,Coord,b1,b2);
485 if (StdPrs_DeflectionCurve::Match(X,Y,Z,aDistance,anIso, b1, b2, Deflection, anAngle))
486 return Standard_True;
489 return Standard_False;
493 //=========================================================================
496 //=========================================================================
497 void StdPrs_WFDeflectionRestrictedFace::Add
498 (const Handle (Prs3d_Presentation)& aPresentation,
499 const Handle(BRepAdaptor_HSurface)& aFace,
500 const Handle (Prs3d_Drawer)& aDrawer)
502 Prs3d_NListOfSequenceOfPnt Curves;
503 StdPrs_WFDeflectionRestrictedFace::Add (aPresentation,
507 aDrawer->MaximalChordialDeviation(),
508 aDrawer->UIsoAspect()->Number(),
509 aDrawer->VIsoAspect()->Number(),
515 //=========================================================================
518 //=========================================================================
519 void StdPrs_WFDeflectionRestrictedFace::AddUIso
520 (const Handle (Prs3d_Presentation)& aPresentation,
521 const Handle(BRepAdaptor_HSurface)& aFace,
522 const Handle (Prs3d_Drawer)& aDrawer)
524 Prs3d_NListOfSequenceOfPnt Curves;
525 StdPrs_WFDeflectionRestrictedFace::Add (
530 aDrawer->MaximalChordialDeviation(),
531 aDrawer->UIsoAspect()->Number(),
532 aDrawer->VIsoAspect()->Number(),
538 //=========================================================================
541 //=========================================================================
542 void StdPrs_WFDeflectionRestrictedFace::AddVIso
543 (const Handle (Prs3d_Presentation)& aPresentation,
544 const Handle(BRepAdaptor_HSurface)& aFace,
545 const Handle (Prs3d_Drawer)& aDrawer)
547 Prs3d_NListOfSequenceOfPnt Curves;
548 StdPrs_WFDeflectionRestrictedFace::Add (
553 aDrawer->MaximalChordialDeviation(),
554 aDrawer->UIsoAspect()->Number(),
555 aDrawer->VIsoAspect()->Number(),
561 //=========================================================================
564 //=========================================================================
565 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::Match
566 (const Standard_Real X,
567 const Standard_Real Y,
568 const Standard_Real Z,
569 const Standard_Real aDistance,
570 const Handle(BRepAdaptor_HSurface)& aFace,
571 const Handle (Prs3d_Drawer)& aDrawer)
573 return StdPrs_WFDeflectionRestrictedFace::Match (
579 aDrawer->MaximalChordialDeviation(),
580 aDrawer->UIsoAspect()->Number(),
581 aDrawer->VIsoAspect()->Number());
585 //=========================================================================
586 // function: MatchUIso
588 //=========================================================================
589 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchUIso
590 (const Standard_Real X,
591 const Standard_Real Y,
592 const Standard_Real Z,
593 const Standard_Real aDistance,
594 const Handle(BRepAdaptor_HSurface)& aFace,
595 const Handle (Prs3d_Drawer)& aDrawer)
597 return StdPrs_WFDeflectionRestrictedFace::Match (
603 aDrawer->MaximalChordialDeviation(),
604 aDrawer->UIsoAspect()->Number(),
605 aDrawer->VIsoAspect()->Number());
609 //=========================================================================
610 // function: MatchVIso
612 //=========================================================================
613 Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchVIso
614 (const Standard_Real X,
615 const Standard_Real Y,
616 const Standard_Real Z,
617 const Standard_Real aDistance,
618 const Handle(BRepAdaptor_HSurface)& aFace,
619 const Handle (Prs3d_Drawer)& aDrawer)
621 return StdPrs_WFDeflectionRestrictedFace::Match (
627 aDrawer->MaximalChordialDeviation(),
628 aDrawer->UIsoAspect()->Number(),
629 aDrawer->VIsoAspect()->Number());