0023634: Eliminate Polyline and Polygon usage in drawers
[occt.git] / src / StdPrs / StdPrs_WFDeflectionRestrictedFace.cxx
CommitLineData
b311480e 1// Created on: 1995-08-07
2// Created by: Modelistation
3// Copyright (c) 1995-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
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.
10//
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.
13//
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.
20
7fd59977 21
22
23#include <StdPrs_WFDeflectionRestrictedFace.ixx>
24
25#include <Hatch_Hatcher.hxx>
7fd59977 26#include <Graphic3d_Group.hxx>
27#include <gp_Pnt.hxx>
28#include <gp_Pnt2d.hxx>
29#include <Prs3d_IsoAspect.hxx>
30#include <Adaptor2d_Curve2d.hxx>
31#include <GCPnts_QuasiUniformDeflection.hxx>
32#include <Adaptor3d_IsoCurve.hxx>
33#include <StdPrs_DeflectionCurve.hxx>
34#include <StdPrs_ToolRFace.hxx>
35#include <Bnd_Box2d.hxx>
36#include <BndLib_Add2dCurve.hxx>
37#include <Precision.hxx>
38#include <GeomAdaptor_Curve.hxx>
39#include <Geom_Curve.hxx>
40#include <GeomAbs_SurfaceType.hxx>
41#include <Geom_Surface.hxx>
42#include <TColgp_SequenceOfPnt2d.hxx>
43
44
45
46
47#ifdef DEB_MESH
48#include <OSD_Chronometer.hxx>
49extern OSD_Chronometer FFaceTimer1,FFaceTimer2,FFaceTimer3,FFaceTimer4;
50#endif
51
52
53//==================================================================
54// function: FindLimits
55// purpose:
56//==================================================================
57static void FindLimits(const Adaptor3d_Curve& aCurve,
58 const Standard_Real aLimit,
59 Standard_Real& First,
60 Standard_Real& Last)
61{
62 First = Max(aCurve.FirstParameter(), First);
63 Last = Min(aCurve.LastParameter(), Last);
64 Standard_Boolean firstInf = Precision::IsNegativeInfinite(First);
65 Standard_Boolean lastInf = Precision::IsPositiveInfinite(Last);
66
67 if (firstInf || lastInf) {
68 gp_Pnt P1,P2;
69 Standard_Real delta = 1;
70 if (firstInf && lastInf) {
71 do {
72 delta *= 2;
73 First = - delta;
74 Last = delta;
75 aCurve.D0(First,P1);
76 aCurve.D0(Last,P2);
77 } while (P1.Distance(P2) < aLimit);
78 }
79 else if (firstInf) {
80 aCurve.D0(Last,P2);
81 do {
82 delta *= 2;
83 First = Last - delta;
84 aCurve.D0(First,P1);
85 } while (P1.Distance(P2) < aLimit);
86 }
87 else if (lastInf) {
88 aCurve.D0(First,P1);
89 do {
90 delta *= 2;
91 Last = First + delta;
92 aCurve.D0(Last,P2);
93 } while (P1.Distance(P2) < aLimit);
94 }
95 }
96
97}
98
99
100//=========================================================================
101// function: Add
102// purpose
103//=========================================================================
104void StdPrs_WFDeflectionRestrictedFace::Add
105 (const Handle (Prs3d_Presentation)& aPresentation,
106 const Handle(BRepAdaptor_HSurface)& aFace,
107 const Standard_Boolean DrawUIso,
108 const Standard_Boolean DrawVIso,
109 const Quantity_Length Deflection,
110 const Standard_Integer NBUiso,
111 const Standard_Integer NBViso,
112 const Handle(Prs3d_Drawer)& aDrawer,
113 Prs3d_NListOfSequenceOfPnt& Curves) {
114
115#ifdef DEB_MESH
116 FFaceTimer1.Start();
117#endif
118
7fd59977 119 StdPrs_ToolRFace ToolRst (aFace);
120 Standard_Real UF, UL, VF, VL;
121 UF = aFace->FirstUParameter();
122 UL = aFace->LastUParameter();
123 VF = aFace->FirstVParameter();
124 VL = aFace->LastVParameter();
125
126 Standard_Real aLimit = aDrawer->MaximalParameterValue();
127
128 // compute bounds of the restriction
129 Standard_Real UMin,UMax,VMin,VMax;
130 //Standard_Real u,v,step;
131 Standard_Integer i;//,nbPoints = 10;
132
133 UMin = Max(UF, -aLimit);
134 UMax = Min(UL, aLimit);
135 VMin = Max(VF, -aLimit);
136 VMax = Min(VL, aLimit);
137
138
139 // update min max for the hatcher.
140 gp_Pnt2d P1,P2;
141 Standard_Real U1, U2;
142 gp_Pnt dummypnt;
143 Standard_Real ddefle= Max(UMax-UMin, VMax-VMin) * aDrawer->DeviationCoefficient();
144 TColgp_SequenceOfPnt2d tabP;
145
146 UMin = VMin = 1.e100;
147 UMax = VMax = -1.e100;
148
149 for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
150 TopAbs_Orientation Orient = ToolRst.Orientation();
151 if ( Orient == TopAbs_FORWARD || Orient == TopAbs_REVERSED ) {
152 Adaptor2d_Curve2dPtr TheRCurve = ToolRst.Value();
153 if (TheRCurve->GetType() != GeomAbs_Line) {
154 GCPnts_QuasiUniformDeflection UDP(*TheRCurve, ddefle);
155 if (UDP.IsDone()) {
156 Standard_Integer NumberOfPoints = UDP.NbPoints();
157 if ( NumberOfPoints >= 2 ) {
158 dummypnt = UDP.Value(1);
159 P2.SetCoord(dummypnt.X(), dummypnt.Y());
160 UMin = Min(P2.X(), UMin);
161 UMax = Max(P2.X(), UMax);
162 VMin = Min(P2.Y(), VMin);
163 VMax = Max(P2.Y(), VMax);
164 for (i = 2; i <= NumberOfPoints; i++) {
165 P1 = P2;
166 dummypnt = UDP.Value(i);
167 P2.SetCoord(dummypnt.X(), dummypnt.Y());
168 UMin = Min(P2.X(), UMin);
169 UMax = Max(P2.X(), UMax);
170 VMin = Min(P2.Y(), VMin);
171 VMax = Max(P2.Y(), VMax);
172
173 if(Orient == TopAbs_FORWARD ) {
174 //isobuild.Trim(P1,P2);
175 tabP.Append(P1);
176 tabP.Append(P2);
177 }
178 else {
179 //isobuild.Trim(P2,P1);
180 tabP.Append(P2);
181 tabP.Append(P1);
182 }
183 }
184 }
185 }
186 else {
187 cout << "Cannot evaluate curve on surface"<<endl;
188 }
189 }
190 else {
191 U1 = TheRCurve->FirstParameter();
192 U2 = TheRCurve->LastParameter();
193 // MSV 17.08.06 OCC13144: U2 occured less than U1, to overcome it
194 // ensure that distance U2-U1 is not greater than aLimit*2,
195 // if greater then choose an origin and use aLimit to define
196 // U1 and U2 anew
197 Standard_Real aOrigin = 0.;
198 if (!Precision::IsNegativeInfinite(U1) || !Precision::IsPositiveInfinite(U2)) {
199 if (Precision::IsNegativeInfinite(U1))
200 aOrigin = U2 - aLimit;
201 else if (Precision::IsPositiveInfinite(U2))
202 aOrigin = U1 + aLimit;
203 else
204 aOrigin = (U1 + U2) * 0.5;
205 }
206 U1 = Max(aOrigin - aLimit, U1);
207 U2 = Min(aOrigin + aLimit, U2);
208 P1 = TheRCurve->Value(U1);
209 P2 = TheRCurve->Value(U2);
210 UMin = Min(P1.X(), UMin);
211 UMax = Max(P1.X(), UMax);
212 VMin = Min(P1.Y(), VMin);
213 VMax = Max(P1.Y(), VMax);
214 UMin = Min(P2.X(), UMin);
215 UMax = Max(P2.X(), UMax);
216 VMin = Min(P2.Y(), VMin);
217 VMax = Max(P2.Y(), VMax);
218 if(Orient == TopAbs_FORWARD ) {
219 // isobuild.Trim(P1,P2);
220 tabP.Append(P1);
221 tabP.Append(P2);
222 }
223 else {
224 //isobuild.Trim(P2,P1);
225 tabP.Append(P2);
226 tabP.Append(P1);
227 }
228 }
229 }
230 }
231
232
233#ifdef DEB_MESH
234 FFaceTimer1.Stop();
235
236 FFaceTimer2.Start();
237#endif
238
239 // load the isos
240 Hatch_Hatcher isobuild(1.e-5,ToolRst.IsOriented());
241 Standard_Boolean UClosed = aFace->IsUClosed();
242 Standard_Boolean VClosed = aFace->IsVClosed();
243
244 if ( ! UClosed ) {
245 UMin = UMin + ( UMax - UMin) /1000.;
246 UMax = UMax - ( UMax - UMin) /1000.;
247 }
248
249 if ( ! VClosed ) {
250 VMin = VMin + ( VMax - VMin) /1000.;
251 VMax = VMax - ( VMax - VMin) /1000.;
252 }
253
254 if (DrawUIso){
255 if (NBUiso > 0) {
256 UClosed = Standard_False; // En attendant un hatcher de course.
257 Standard_Real du= UClosed ? (UMax-UMin)/NBUiso : (UMax-UMin)/(1+NBUiso);
258 for (i=1; i<=NBUiso;i++){
259 isobuild.AddXLine(UMin+du*i);
260 }
261 }
262 }
263 if (DrawVIso){
264 if ( NBViso > 0) {
265 VClosed = Standard_False;
266 Standard_Real dv= VClosed ?(VMax-VMin)/NBViso : (VMax-VMin)/(1+NBViso);
267 for (i=1; i<=NBViso;i++){
268 isobuild.AddYLine(VMin+dv*i);
269 }
270 }
271 }
272
273#ifdef DEB_MESH
274 FFaceTimer2.Stop();
275 FFaceTimer3.Start();
276#endif
277
278
279 Standard_Integer ll = tabP.Length();
280 for (i = 1; i <= ll; i+=2) {
281 isobuild.Trim(tabP(i),tabP(i+1));
282 }
283
284
285#ifdef DEB_MESH
286 FFaceTimer3.Stop();
287 FFaceTimer4.Start();
288#endif
289
290 // draw the isos
291
292 Adaptor3d_IsoCurve anIso;
293 anIso.Load(aFace);
294 Handle(Geom_Curve) BC;
295 const BRepAdaptor_Surface& BS = *(BRepAdaptor_Surface*)&(aFace->Surface());
296 GeomAbs_SurfaceType thetype = aFace->GetType();
297
298 Standard_Integer NumberOfLines = isobuild.NbLines();
299 Handle(Geom_Surface) GB;
300 if (thetype == GeomAbs_BezierSurface) {
301 GB = BS.Bezier();
302 }
303 else if (thetype == GeomAbs_BSplineSurface){
304 GB = BS.BSpline();
305 }
306
307 Standard_Real anAngle = aDrawer->DeviationAngle();
308
309 for (i = 1; i <= NumberOfLines; i++) {
310 Standard_Integer NumberOfIntervals = isobuild.NbIntervals(i);
311 Standard_Real Coord = isobuild.Coordinate(i);
312 for (Standard_Integer j = 1; j <= NumberOfIntervals; j++) {
313 Standard_Real b1=isobuild.Start(i,j),b2=isobuild.End(i,j);
314
315
316 if (!GB.IsNull()) {
317 if (isobuild.IsXLine(i))
318 BC = GB->UIso(Coord);
319 else
320 BC = GB->VIso(Coord);
321 GeomAdaptor_Curve GC(BC);
322 FindLimits(GC, aLimit,b1, b2);
323 if (b2-b1>Precision::Confusion()) {
324 TColgp_SequenceOfPnt Points;
b8ddfc2f 325 StdPrs_DeflectionCurve::Add(aPresentation, GC, b1, b2, Deflection, Points, anAngle, Standard_False);
7fd59977 326 Curves.Append(Points);
327 }
328 }
329 else {
330 if (isobuild.IsXLine(i))
331 anIso.Load(GeomAbs_IsoU,Coord,b1,b2);
332 else
333 anIso.Load(GeomAbs_IsoV,Coord,b1,b2);
334 FindLimits(anIso, aLimit,b1, b2);
335 if (b2-b1>Precision::Confusion()) {
336 TColgp_SequenceOfPnt Points;
b8ddfc2f 337 StdPrs_DeflectionCurve::Add(aPresentation, anIso, b1, b2, Deflection, Points, anAngle, Standard_False);
7fd59977 338 Curves.Append(Points);
339 }
340 }
341 }
342 }
343#ifdef DEB_MESH
344 FFaceTimer4.Stop();
345#endif
346}
347
348
349//=========================================================================
350// function: Match
351// purpose
352//=========================================================================
353Standard_Boolean StdPrs_WFDeflectionRestrictedFace::Match
354 (const Quantity_Length X,
355 const Quantity_Length Y,
356 const Quantity_Length Z,
357 const Quantity_Length aDistance,
358 const Handle(BRepAdaptor_HSurface)& aFace,
359 const Handle(Prs3d_Drawer)& aDrawer,
360 const Standard_Boolean DrawUIso,
361 const Standard_Boolean DrawVIso,
362 const Quantity_Length Deflection,
363 const Standard_Integer NBUiso,
364 const Standard_Integer NBViso)
365{
366
367 StdPrs_ToolRFace ToolRst (aFace);
368 const Standard_Real aLimit = aDrawer->MaximalParameterValue();
369
370 // compute bounds of the restriction
371 Standard_Real UMin,UMax,VMin,VMax;
372 Standard_Real u,v,step;
373 Standard_Integer i,nbPoints = 10;
374 UMin = VMin = RealLast();
375 UMax = VMax = RealFirst();
376
377 for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
378 Adaptor2d_Curve2dPtr TheRCurve = ToolRst.Value();
379 u = TheRCurve->FirstParameter();
380 v = TheRCurve->LastParameter();
381 step = ( v - u) / nbPoints;
382 for (i = 0; i <= nbPoints; i++) {
383 gp_Pnt2d P = TheRCurve->Value(u);
384 if (P.X() < UMin) UMin = P.X();
385 if (P.X() > UMax) UMax = P.X();
386 if (P.Y() < VMin) VMin = P.Y();
387 if (P.Y() > VMax) VMax = P.Y();
388 u += step;
389 }
390 }
391
392 // load the isos
393 Hatch_Hatcher isobuild(1.e-5,ToolRst.IsOriented());
394 Standard_Boolean UClosed = aFace->IsUClosed();
395 Standard_Boolean VClosed = aFace->IsVClosed();
396
397 if ( ! UClosed ) {
398 UMin = UMin + ( UMax - UMin) /1000.;
399 UMax = UMax - ( UMax - UMin) /1000.;
400 }
401
402 if ( ! VClosed ) {
403 VMin = VMin + ( VMax - VMin) /1000.;
404 VMax = VMax - ( VMax - VMin) /1000.;
405 }
406
407 if (DrawUIso){
408 if (NBUiso > 0) {
409 UClosed = Standard_False; // En attendant un hatcher de course.
410 Standard_Real du= UClosed ? (UMax-UMin)/NBUiso : (UMax-UMin)/(1+NBUiso);
411 for (i=1; i<=NBUiso;i++){
412 isobuild.AddXLine(UMin+du*i);
413 }
414 }
415 }
416 if (DrawVIso){
417 if ( NBViso > 0) {
418 VClosed = Standard_False;
419 Standard_Real dv= VClosed ?(VMax-VMin)/NBViso : (VMax-VMin)/(1+NBViso);
420 for (i=1; i<=NBViso;i++){
421 isobuild.AddYLine(VMin+dv*i);
422 }
423 }
424 }
425
426 // trim the isos
427 gp_Pnt2d P1,P2;
428 gp_Pnt dummypnt;
429 for (ToolRst.Init(); ToolRst.More(); ToolRst.Next()) {
430 TopAbs_Orientation Orient = ToolRst.Orientation();
431 if ( Orient == TopAbs_FORWARD || Orient == TopAbs_REVERSED ) {
432 Adaptor2d_Curve2dPtr TheRCurve = ToolRst.Value();
433 GCPnts_QuasiUniformDeflection UDP(*TheRCurve, Deflection);
434 if (UDP.IsDone()) {
435 Standard_Integer NumberOfPoints = UDP.NbPoints();
436 if ( NumberOfPoints >= 2 ) {
437 dummypnt = UDP.Value(1);
438 P2.SetCoord(dummypnt.X(), dummypnt.Y());
439 for (i = 2; i <= NumberOfPoints; i++) {
440 P1 = P2;
441 dummypnt = UDP.Value(i);
442 P2.SetCoord(dummypnt.X(), dummypnt.Y());
443 if(Orient == TopAbs_FORWARD )
444 isobuild.Trim(P1,P2);
445 else
446 isobuild.Trim(P2,P1);
447 }
448 }
449 }
450 else {
451 cout << "Cannot evaluate curve on surface"<<endl;
452 }
453 }
454 }
455
456 // draw the isos
457
458 Adaptor3d_IsoCurve anIso;
459 anIso.Load(aFace);
460 Standard_Integer NumberOfLines = isobuild.NbLines();
461 Standard_Real anAngle = aDrawer->DeviationAngle();
462
463 for (i = 1; i <= NumberOfLines; i++) {
464 Standard_Integer NumberOfIntervals = isobuild.NbIntervals(i);
465 Standard_Real Coord = isobuild.Coordinate(i);
466 for (Standard_Integer j = 1; j <= NumberOfIntervals; j++) {
467 Standard_Real b1=isobuild.Start(i,j),b2=isobuild.End(i,j);
468
469 b1 = b1 == RealFirst() ? - aLimit : b1;
470 b2 = b2 == RealLast() ? aLimit : b2;
471
472 if (isobuild.IsXLine(i))
473 anIso.Load(GeomAbs_IsoU,Coord,b1,b2);
474 else
475 anIso.Load(GeomAbs_IsoV,Coord,b1,b2);
476
477 if (StdPrs_DeflectionCurve::Match(X,Y,Z,aDistance,anIso, b1, b2, Deflection, anAngle))
478 return Standard_True;
479 }
480 }
481 return Standard_False;
482}
483
484
485//=========================================================================
486// function: Add
487// purpose
488//=========================================================================
489void StdPrs_WFDeflectionRestrictedFace::Add
490 (const Handle (Prs3d_Presentation)& aPresentation,
491 const Handle(BRepAdaptor_HSurface)& aFace,
b8ddfc2f 492 const Handle (Prs3d_Drawer)& aDrawer)
493{
7fd59977 494 Prs3d_NListOfSequenceOfPnt Curves;
495 StdPrs_WFDeflectionRestrictedFace::Add (aPresentation,
496 aFace,
497 Standard_True,
498 Standard_True,
b8ddfc2f 499 aDrawer->MaximalChordialDeviation(),
500 aDrawer->UIsoAspect()->Number(),
501 aDrawer->VIsoAspect()->Number(),
7fd59977 502 aDrawer,
503 Curves);
7fd59977 504}
505
506
507//=========================================================================
508// function: AddUIso
509// purpose
510//=========================================================================
511void StdPrs_WFDeflectionRestrictedFace::AddUIso
512 (const Handle (Prs3d_Presentation)& aPresentation,
513 const Handle(BRepAdaptor_HSurface)& aFace,
b8ddfc2f 514 const Handle (Prs3d_Drawer)& aDrawer)
515{
7fd59977 516 Prs3d_NListOfSequenceOfPnt Curves;
517 StdPrs_WFDeflectionRestrictedFace::Add (
518 aPresentation,
519 aFace,
520 Standard_True,
521 Standard_False,
b8ddfc2f 522 aDrawer->MaximalChordialDeviation(),
523 aDrawer->UIsoAspect()->Number(),
524 aDrawer->VIsoAspect()->Number(),
7fd59977 525 aDrawer,
526 Curves);
527}
528
529
530//=========================================================================
531// function: AddVIso
532// purpose
533//=========================================================================
534void StdPrs_WFDeflectionRestrictedFace::AddVIso
535 (const Handle (Prs3d_Presentation)& aPresentation,
536 const Handle(BRepAdaptor_HSurface)& aFace,
b8ddfc2f 537 const Handle (Prs3d_Drawer)& aDrawer)
538{
7fd59977 539 Prs3d_NListOfSequenceOfPnt Curves;
540 StdPrs_WFDeflectionRestrictedFace::Add (
541 aPresentation,
542 aFace,
543 Standard_False,
544 Standard_True,
b8ddfc2f 545 aDrawer->MaximalChordialDeviation(),
546 aDrawer->UIsoAspect()->Number(),
547 aDrawer->VIsoAspect()->Number(),
7fd59977 548 aDrawer,
549 Curves);
550}
551
552
553//=========================================================================
554// function: Match
555// purpose
556//=========================================================================
557Standard_Boolean StdPrs_WFDeflectionRestrictedFace::Match
558 (const Quantity_Length X,
559 const Quantity_Length Y,
560 const Quantity_Length Z,
561 const Quantity_Length aDistance,
562 const Handle(BRepAdaptor_HSurface)& aFace,
b8ddfc2f 563 const Handle (Prs3d_Drawer)& aDrawer)
564{
7fd59977 565 return StdPrs_WFDeflectionRestrictedFace::Match (
566 X,Y,Z,aDistance,
b8ddfc2f 567 aFace,
568 aDrawer,
569 Standard_True,
570 Standard_True,
571 aDrawer->MaximalChordialDeviation(),
572 aDrawer->UIsoAspect()->Number(),
573 aDrawer->VIsoAspect()->Number());
7fd59977 574}
575
576
577//=========================================================================
578// function: MatchUIso
579// purpose
580//=========================================================================
581Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchUIso
582 (const Quantity_Length X,
583 const Quantity_Length Y,
584 const Quantity_Length Z,
585 const Quantity_Length aDistance,
586 const Handle(BRepAdaptor_HSurface)& aFace,
b8ddfc2f 587 const Handle (Prs3d_Drawer)& aDrawer)
588{
7fd59977 589 return StdPrs_WFDeflectionRestrictedFace::Match (
590 X,Y,Z,aDistance,
b8ddfc2f 591 aFace,
592 aDrawer,
593 Standard_True,
594 Standard_False,
595 aDrawer->MaximalChordialDeviation(),
596 aDrawer->UIsoAspect()->Number(),
597 aDrawer->VIsoAspect()->Number());
7fd59977 598}
599
600
601//=========================================================================
602// function: MatchVIso
603// purpose
604//=========================================================================
605Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchVIso
606 (const Quantity_Length X,
607 const Quantity_Length Y,
608 const Quantity_Length Z,
609 const Quantity_Length aDistance,
610 const Handle(BRepAdaptor_HSurface)& aFace,
b8ddfc2f 611 const Handle (Prs3d_Drawer)& aDrawer)
612{
7fd59977 613 return StdPrs_WFDeflectionRestrictedFace::Match (
614 X,Y,Z,aDistance,
b8ddfc2f 615 aFace,
616 aDrawer,
617 Standard_False,
618 Standard_True,
619 aDrawer->MaximalChordialDeviation(),
620 aDrawer->UIsoAspect()->Number(),
621 aDrawer->VIsoAspect()->Number());
7fd59977 622}