0024157: Parallelization of assembly part of BO
[occt.git] / src / StdPrs / StdPrs_DeflectionCurve.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
2// Copyright (c) 1999-2012 OPEN CASCADE SAS
3//
4// The content of this file is subject to the Open CASCADE Technology Public
5// License Version 6.5 (the "License"). You may not use the content of this file
6// except in compliance with the License. Please obtain a copy of the License
7// at http://www.opencascade.org and read it completely before using this file.
8//
9// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11//
12// The Original Code and all software distributed under the License is
13// distributed on an "AS IS" basis, without warranty of any kind, and the
14// Initial Developer hereby disclaims all such warranties, including without
15// limitation, any warranties of merchantability, fitness for a particular
16// purpose or non-infringement. Please see the License for the specific terms
17// and conditions governing the rights and limitations under the License.
18
7fd59977 19// Great zoom leads to non-coincidence of
20// a point and non-infinite lines passing throught this point:
21#define OCC64
22
23#include <StdPrs_DeflectionCurve.ixx>
24
b8ddfc2f 25#include <Graphic3d_ArrayOfSegments.hxx>
26#include <Graphic3d_ArrayOfPolylines.hxx>
7fd59977 27#include <Graphic3d_Group.hxx>
28#include <Prs3d_LineAspect.hxx>
29#include <Prs3d_Arrow.hxx>
30#include <Prs3d_ArrowAspect.hxx>
31#include <gp_Pnt.hxx>
32#include <gp_Circ.hxx>
33#include <gp_Dir.hxx>
34#include <gp_Vec.hxx>
35#include <Prs3d.hxx>
36#include <Bnd_Box.hxx>
37#include <BndLib_Add3dCurve.hxx>
38#include <Precision.hxx>
39#include <GCPnts_QuasiUniformDeflection.hxx>
40#include <GCPnts_TangentialDeflection.hxx>
41#include <TColgp_SequenceOfPnt.hxx>
42#include <TColStd_Array1OfReal.hxx>
43
44
45//==================================================================
46// function: GetDeflection
47// purpose:
48//==================================================================
49static Standard_Real GetDeflection(const Adaptor3d_Curve& aCurve,
b8ddfc2f 50 const Standard_Real U1,
51 const Standard_Real U2,
52 const Handle(Prs3d_Drawer)& aDrawer)
53{
54 Standard_Real TheDeflection;
55
56 if (aDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE)
57 {
58 // On calcule la fleche en fonction des min max globaux de la piece:
59 Bnd_Box Total;
60 BndLib_Add3dCurve::Add(aCurve, U1, U2, 0.,Total);
61 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
62 Total.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
63 Standard_Real m = RealLast();
64 if ( ! (Total.IsOpenXmin() || Total.IsOpenXmax() ))
65 m = Abs (aXmax-aXmin);
66 if ( ! (Total.IsOpenYmin() || Total.IsOpenYmax() ))
67 m = Max ( m , Abs (aYmax-aYmin));
68 if ( ! (Total.IsOpenZmin() || Total.IsOpenZmax() ))
69 m = Max ( m , Abs (aZmax-aZmin));
7fd59977 70
b8ddfc2f 71 m = Min ( m , aDrawer->MaximalParameterValue());
72 m = Max(m, Precision::Confusion());
7fd59977 73
b8ddfc2f 74 TheDeflection = m * aDrawer->DeviationCoefficient();
7fd59977 75 }
b8ddfc2f 76 else
77 TheDeflection = aDrawer->MaximalChordialDeviation();
78
79 return TheDeflection;
80}
7fd59977 81
82//==================================================================
83// function: FindLimits
84// purpose:
85//==================================================================
b8ddfc2f 86static Standard_Boolean FindLimits(const Adaptor3d_Curve& aCurve,
87 const Standard_Real aLimit,
88 Standard_Real& First,
89 Standard_Real& Last)
7fd59977 90{
91 First = aCurve.FirstParameter();
92 Last = aCurve.LastParameter();
93 Standard_Boolean firstInf = Precision::IsNegativeInfinite(First);
94 Standard_Boolean lastInf = Precision::IsPositiveInfinite(Last);
95
96 if (firstInf || lastInf) {
97 gp_Pnt P1,P2;
98 Standard_Real delta = 1;
99 Standard_Integer count = 0;
100 if (firstInf && lastInf) {
101 do {
b8ddfc2f 102 if (count++ == 100000) return Standard_False;
103 delta *= 2;
104 First = - delta;
105 Last = delta;
106 aCurve.D0(First,P1);
107 aCurve.D0(Last,P2);
7fd59977 108 } while (P1.Distance(P2) < aLimit);
109 }
110 else if (firstInf) {
111 aCurve.D0(Last,P2);
112 do {
b8ddfc2f 113 if (count++ == 100000) return Standard_False;
114 delta *= 2;
115 First = Last - delta;
116 aCurve.D0(First,P1);
7fd59977 117 } while (P1.Distance(P2) < aLimit);
118 }
119 else if (lastInf) {
120 aCurve.D0(First,P1);
121 do {
b8ddfc2f 122 if (count++ == 100000) return Standard_False;
123 delta *= 2;
124 Last = First + delta;
125 aCurve.D0(Last,P2);
7fd59977 126 } while (P1.Distance(P2) < aLimit);
127 }
128 }
129 return Standard_True;
130}
131
132
7fd59977 133//==================================================================
134// function: DrawCurve
135// purpose:
136//==================================================================
b8ddfc2f 137static void DrawCurve (Adaptor3d_Curve& aCurve,
7fd59977 138 const Handle(Graphic3d_Group) aGroup,
139 const Quantity_Length TheDeflection,
b8ddfc2f 140 const Standard_Real anAngle,
7fd59977 141 const Standard_Real U1,
142 const Standard_Real U2,
b8ddfc2f 143 TColgp_SequenceOfPnt& Points,
144 const Standard_Boolean drawCurve)
7fd59977 145{
b8ddfc2f 146 switch (aCurve.GetType())
147 {
148 case GeomAbs_Line:
7fd59977 149 {
b8ddfc2f 150 gp_Pnt p1 = aCurve.Value(U1);
151 gp_Pnt p2 = aCurve.Value(U2);
152 Points.Append(p1);
153 Points.Append(p2);
154 if(drawCurve)
155 {
156 Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
157 aPrims->AddVertex(p1);
158 aPrims->AddVertex(p2);
159 aGroup->AddPrimitiveArray(aPrims);
160 }
161 break;
162 }
163 default:
7fd59977 164 {
b8ddfc2f 165 const Standard_Integer nbinter = aCurve.NbIntervals(GeomAbs_C1);
7fd59977 166 TColStd_Array1OfReal T(1, nbinter+1);
167 aCurve.Intervals(T, GeomAbs_C1);
b8ddfc2f 168
7fd59977 169 Standard_Real theU1, theU2;
b8ddfc2f 170 Standard_Integer NumberOfPoints, i, j;
7fd59977 171 TColgp_SequenceOfPnt SeqP;
172
173 for (j = 1; j <= nbinter; j++) {
b8ddfc2f 174 theU1 = T(j); theU2 = T(j+1);
175 if (theU2 > U1 && theU1 < U2) {
176 theU1 = Max(theU1, U1);
177 theU2 = Min(theU2, U2);
7fd59977 178
b8ddfc2f 179 GCPnts_TangentialDeflection Algo(aCurve, theU1, theU2, anAngle, TheDeflection);
180 NumberOfPoints = Algo.NbPoints();
181
182 if (NumberOfPoints > 0) {
183 for (i=1;i<NumberOfPoints;i++) {
184 SeqP.Append(Algo.Value(i));
185 }
186 if (j == nbinter) {
187 SeqP.Append(Algo.Value(NumberOfPoints));
188 }
189 }
190 }
7fd59977 191 }
192
b8ddfc2f 193 Handle(Graphic3d_ArrayOfPolylines) aPrims;
194 if(drawCurve)
195 aPrims = new Graphic3d_ArrayOfPolylines(SeqP.Length());
7fd59977 196
7fd59977 197 for (i = 1; i <= SeqP.Length(); i++) {
b8ddfc2f 198 const gp_Pnt& p = SeqP.Value(i);
199 Points.Append(p);
200 if(drawCurve)
201 aPrims->AddVertex(p);
7fd59977 202 }
b8ddfc2f 203 if(drawCurve)
204 aGroup->AddPrimitiveArray(aPrims);
7fd59977 205 }
206 }
7fd59977 207}
208
209
210//==================================================================
211// function: MatchCurve
212// purpose:
213//==================================================================
214static Standard_Boolean MatchCurve (
215 const Quantity_Length X,
216 const Quantity_Length Y,
217 const Quantity_Length Z,
218 const Quantity_Length aDistance,
219 const Adaptor3d_Curve& aCurve,
b8ddfc2f 220 const Quantity_Length TheDeflection,
7fd59977 221 const Standard_Real anAngle,
b8ddfc2f 222 const Standard_Real U1,
223 const Standard_Real U2)
7fd59977 224{
225 Quantity_Length retdist;
b8ddfc2f 226 switch (aCurve.GetType())
227 {
228 case GeomAbs_Line:
7fd59977 229 {
b8ddfc2f 230 gp_Pnt p1 = aCurve.Value(U1);
231 if ( Abs(X-p1.X()) + Abs(Y-p1.Y()) + Abs(Z-p1.Z()) <= aDistance)
232 return Standard_True;
233 gp_Pnt p2 = aCurve.Value(U2);
234 if ( Abs(X-p2.X()) + Abs(Y-p2.Y()) + Abs(Z-p2.Z()) <= aDistance)
235 return Standard_True;
236 return Prs3d::MatchSegment(X,Y,Z,aDistance,p1,p2,retdist);
237 }
238 case GeomAbs_Circle:
7fd59977 239 {
b8ddfc2f 240 const Standard_Real Radius = aCurve.Circle().Radius();
7fd59977 241 if (!Precision::IsInfinite(Radius)) {
b8ddfc2f 242 const Standard_Real DU = Sqrt(8.0 * TheDeflection / Radius);
243 const Standard_Real Er = Abs( U2 - U1) / DU;
244 const Standard_Integer N = Max(2, (Standard_Integer)IntegerPart(Er));
245 if ( N > 0) {
246 gp_Pnt p1,p2;
247 for (Standard_Integer Index = 1; Index <= N+1; Index++) {
248 p2 = aCurve.Value(U1 + (Index - 1) * DU);
249 if ( Abs(X-p2.X()) + Abs(Y-p2.Y()) + Abs(Z-p2.Z()) <= aDistance)
250 return Standard_True;
251
252 if (Index>1) {
253 if (Prs3d::MatchSegment(X,Y,Z,aDistance,p1,p2,retdist))
254 return Standard_True;
255 }
256 p1=p2;
257 }
258 }
7fd59977 259 }
b8ddfc2f 260 break;
261 }
262 default:
7fd59977 263 {
264 GCPnts_TangentialDeflection Algo(aCurve,U1, U2, anAngle, TheDeflection);
b8ddfc2f 265 const Standard_Integer NumberOfPoints = Algo.NbPoints();
7fd59977 266 if (NumberOfPoints > 0) {
b8ddfc2f 267 gp_Pnt p1,p2;
268 for (Standard_Integer i=1;i<=NumberOfPoints;i++) {
269 p2 = Algo.Value(i);
270 if ( Abs(X-p2.X()) + Abs(Y-p2.Y()) + Abs(Z-p2.Z()) <= aDistance)
271 return Standard_True;
272 if (i>1) {
273 if (Prs3d::MatchSegment(X,Y,Z,aDistance,p1,p2,retdist))
274 return Standard_True;
275 }
276 p1=p2;
277 }
7fd59977 278 }
7fd59977 279 }
280 }
281 return Standard_False;
282}
283
284
285//==================================================================
286// function: Add
287// purpose:
288//==================================================================
289void StdPrs_DeflectionCurve::Add (const Handle (Prs3d_Presentation)& aPresentation,
b8ddfc2f 290 Adaptor3d_Curve& aCurve,
291 const Handle (Prs3d_Drawer)& aDrawer,
292 const Standard_Boolean drawCurve)
293{
7fd59977 294 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(aDrawer->LineAspect()->Aspect());
295
b8ddfc2f 296 Standard_Real V1, V2;
297 if (FindLimits(aCurve, aDrawer->MaximalParameterValue(), V1, V2))
298 {
299 TColgp_SequenceOfPnt Points;
7fd59977 300 DrawCurve(aCurve,
b8ddfc2f 301 Prs3d_Root::CurrentGroup(aPresentation),
302 GetDeflection(aCurve, V1, V2, aDrawer),
303 aDrawer->DeviationAngle(),
304 V1, V2, Points, drawCurve);
305
7fd59977 306 if (aDrawer->LineArrowDraw()) {
307 gp_Pnt Location;
308 gp_Vec Direction;
309 aCurve.D1(V2, Location,Direction);
310 Prs3d_Arrow::Draw (aPresentation,
b8ddfc2f 311 Location,
312 gp_Dir(Direction),
313 aDrawer->ArrowAspect()->Angle(),
314 aDrawer->ArrowAspect()->Length());
7fd59977 315 }
316 }
317}
318
319
320//==================================================================
321// function: Add
322// purpose:
323//==================================================================
324void StdPrs_DeflectionCurve::Add (const Handle (Prs3d_Presentation)& aPresentation,
b8ddfc2f 325 Adaptor3d_Curve& aCurve,
326 const Standard_Real U1,
327 const Standard_Real U2,
328 const Handle (Prs3d_Drawer)& aDrawer,
329 const Standard_Boolean drawCurve)
330{
7fd59977 331 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(aDrawer->LineAspect()->Aspect());
332
333 Standard_Real V1 = U1;
334 Standard_Real V2 = U2;
335
7fd59977 336 if (Precision::IsNegativeInfinite(V1)) V1 = -aDrawer->MaximalParameterValue();
337 if (Precision::IsPositiveInfinite(V2)) V2 = aDrawer->MaximalParameterValue();
338
7fd59977 339 TColgp_SequenceOfPnt Points;
340 DrawCurve(aCurve,
b8ddfc2f 341 Prs3d_Root::CurrentGroup(aPresentation),
342 GetDeflection(aCurve, V1, V2, aDrawer),
343 aDrawer->DeviationAngle(),
344 V1 , V2, Points, drawCurve);
7fd59977 345
346 if (aDrawer->LineArrowDraw()) {
347 gp_Pnt Location;
348 gp_Vec Direction;
349 aCurve.D1(V2, Location,Direction);
350 Prs3d_Arrow::Draw (aPresentation,
b8ddfc2f 351 Location,
352 gp_Dir(Direction),
353 aDrawer->ArrowAspect()->Angle(),
354 aDrawer->ArrowAspect()->Length());
7fd59977 355 }
356}
357
358//==================================================================
359// function: Add
360// purpose:
361//==================================================================
362void StdPrs_DeflectionCurve::Add (const Handle (Prs3d_Presentation)& aPresentation,
b8ddfc2f 363 Adaptor3d_Curve& aCurve,
364 const Standard_Real U1,
365 const Standard_Real U2,
366 const Standard_Real aDeflection,
367 TColgp_SequenceOfPnt& Points,
368 const Standard_Real anAngle,
369 const Standard_Boolean drawCurve)
7fd59977 370{
371 DrawCurve(aCurve, Prs3d_Root::CurrentGroup(aPresentation),
372 aDeflection, anAngle, U1, U2, Points, drawCurve);
373}
374
7fd59977 375//==================================================================
376// function: Add
377// purpose:
378//==================================================================
379void StdPrs_DeflectionCurve::Add (const Handle (Prs3d_Presentation)& aPresentation,
b8ddfc2f 380 Adaptor3d_Curve& aCurve,
381 const Standard_Real aDeflection,
382 const Standard_Real aLimit,
383 const Standard_Real anAngle,
384 const Standard_Boolean drawCurve)
7fd59977 385{
386 Standard_Real V1, V2;
b8ddfc2f 387 if (FindLimits(aCurve, aLimit, V1, V2))
388 {
389 TColgp_SequenceOfPnt Points;
390 DrawCurve(aCurve, Prs3d_Root::CurrentGroup(aPresentation),
391 aDeflection, anAngle, V1, V2, Points, drawCurve);
392 }
7fd59977 393}
394
395
396//================================================================================
397// function: Add
398// purpose:
399//================================================================================
400void StdPrs_DeflectionCurve::Add (const Handle (Prs3d_Presentation)& aPresentation,
b8ddfc2f 401 Adaptor3d_Curve& aCurve,
402 const Standard_Real aDeflection,
403 const Handle(Prs3d_Drawer)& aDrawer,
404 TColgp_SequenceOfPnt& Points,
405 const Standard_Boolean drawCurve)
7fd59977 406{
7fd59977 407 Standard_Real V1, V2;
b8ddfc2f 408 if (FindLimits(aCurve, aDrawer->MaximalParameterValue(), V1, V2))
409 DrawCurve(aCurve, Prs3d_Root::CurrentGroup(aPresentation),
410 aDeflection, aDrawer->DeviationAngle(), V1, V2, Points, drawCurve);
7fd59977 411}
412
413
414//==================================================================
415// function: Match
416// purpose:
417//==================================================================
418Standard_Boolean StdPrs_DeflectionCurve::Match
419 (const Quantity_Length X,
420 const Quantity_Length Y,
421 const Quantity_Length Z,
422 const Quantity_Length aDistance,
423 const Adaptor3d_Curve& aCurve,
424 const Handle (Prs3d_Drawer)& aDrawer)
425{
426 Standard_Real V1, V2;
b8ddfc2f 427 if (FindLimits(aCurve, aDrawer->MaximalParameterValue(), V1, V2))
428 {
7fd59977 429 return MatchCurve(X,Y,Z,aDistance,aCurve,
b8ddfc2f 430 GetDeflection(aCurve, V1, V2, aDrawer),
431 aDrawer->DeviationAngle(),
432 V1, V2);
7fd59977 433 }
b8ddfc2f 434 return Standard_False;
7fd59977 435}
436
7fd59977 437//==================================================================
438// function: Match
439// purpose:
440//==================================================================
441Standard_Boolean StdPrs_DeflectionCurve::Match
442 (const Quantity_Length X,
443 const Quantity_Length Y,
444 const Quantity_Length Z,
445 const Quantity_Length aDistance,
446 const Adaptor3d_Curve& aCurve,
447 const Standard_Real U1,
448 const Standard_Real U2,
449 const Handle (Prs3d_Drawer)& aDrawer)
450{
451 Standard_Real V1 = U1;
b8ddfc2f 452 Standard_Real V2 = U2;
7fd59977 453
454 if (Precision::IsNegativeInfinite(V1)) V1 = -aDrawer->MaximalParameterValue();
455 if (Precision::IsPositiveInfinite(V2)) V2 = aDrawer->MaximalParameterValue();
456
457 return MatchCurve(X,Y,Z,aDistance,aCurve,
b8ddfc2f 458 GetDeflection(aCurve, V1, V2, aDrawer),
459 aDrawer->DeviationAngle(), V1, V2);
7fd59977 460}
461
7fd59977 462//==================================================================
463// function: Match
464// purpose:
465//==================================================================
466Standard_Boolean StdPrs_DeflectionCurve::Match
467 (const Quantity_Length X,
b8ddfc2f 468 const Quantity_Length Y,
469 const Quantity_Length Z,
470 const Quantity_Length aDistance,
471 const Adaptor3d_Curve& aCurve,
472 const Standard_Real U1,
473 const Standard_Real U2,
474 const Standard_Real aDeflection,
475 const Standard_Real anAngle)
476{
7fd59977 477 return MatchCurve(X,Y,Z,aDistance,aCurve,aDeflection,anAngle,U1,U2);
7fd59977 478}
479
480//==================================================================
481// function: Match
482// purpose:
483//==================================================================
484Standard_Boolean StdPrs_DeflectionCurve::Match
485 (const Quantity_Length X,
486 const Quantity_Length Y,
487 const Quantity_Length Z,
488 const Quantity_Length aDistance,
489 const Adaptor3d_Curve& aCurve,
490 const Standard_Real aDeflection,
491 const Standard_Real aLimit,
b8ddfc2f 492 const Standard_Real anAngle)
493{
7fd59977 494 Standard_Real V1, V2;
b8ddfc2f 495 if (FindLimits(aCurve, aLimit, V1, V2))
496 {
497 return MatchCurve(X,Y,Z,aDistance,aCurve,aDeflection,anAngle,V1,V2);
7fd59977 498 }
b8ddfc2f 499 return Standard_False;
7fd59977 500}