0031459: Visualization, AIS_TextLabel - add missing getters
[occt.git] / src / AIS / AIS.cxx
CommitLineData
b311480e 1// Created on: 1996-12-11
2// Created by: Robert COUBLANC
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7dd7c146 17#include <AIS.hxx>
7fd59977 18
19#include <Adaptor3d_HCurve.hxx>
20#include <Adaptor3d_HSurface.hxx>
42cf5bc1 21#include <Bnd_Box.hxx>
22#include <BRep_Tool.hxx>
7fd59977 23#include <BRepAdaptor_Curve.hxx>
24#include <BRepAdaptor_HSurface.hxx>
25#include <BRepAdaptor_Surface.hxx>
42cf5bc1 26#include <BRepBuilderAPI_MakeEdge.hxx>
27#include <BRepBuilderAPI_MakeVertex.hxx>
60bf98ae 28#include <BRepTools.hxx>
42cf5bc1 29#include <BRepTopAdaptor_FClass2d.hxx>
7fd59977 30#include <ElCLib.hxx>
31#include <ElSLib.hxx>
7fd59977 32#include <GccEnt_QualifiedLin.hxx>
60bf98ae 33#include <gce_MakeDir.hxx>
34#include <gce_MakeLin.hxx>
7fd59977 35#include <Geom2d_Circle.hxx>
7fd59977 36#include <Geom_CartesianPoint.hxx>
37#include <Geom_Circle.hxx>
38#include <Geom_ConicalSurface.hxx>
39#include <Geom_Curve.hxx>
40#include <Geom_CylindricalSurface.hxx>
41#include <Geom_Ellipse.hxx>
42#include <Geom_Line.hxx>
43#include <Geom_OffsetSurface.hxx>
44#include <Geom_Plane.hxx>
45#include <Geom_SphericalSurface.hxx>
42cf5bc1 46#include <Geom_Surface.hxx>
7fd59977 47#include <Geom_SurfaceOfLinearExtrusion.hxx>
48#include <Geom_SurfaceOfRevolution.hxx>
49#include <Geom_ToroidalSurface.hxx>
50#include <Geom_TrimmedCurve.hxx>
42cf5bc1 51#include <GeomAPI_ExtremaCurveCurve.hxx>
52#include <GeomAPI_IntSS.hxx>
53#include <GeomAPI_ProjectPointOnCurve.hxx>
54#include <GeomAPI_ProjectPointOnSurf.hxx>
55#include <GeomLib.hxx>
56#include <GeomProjLib.hxx>
60bf98ae 57#include <gp_Ax1.hxx>
58#include <gp_Ax3.hxx>
59#include <gp_Dir.hxx>
60#include <gp_Elips.hxx>
61#include <gp_Lin.hxx>
62#include <gp_Pln.hxx>
63#include <gp_Pnt.hxx>
64#include <gp_Vec.hxx>
65#include <gp_XYZ.hxx>
7fd59977 66#include <Precision.hxx>
67#include <Prs3d_LineAspect.hxx>
68#include <Prs3d_PointAspect.hxx>
42cf5bc1 69#include <Prs3d_Presentation.hxx>
7fd59977 70#include <StdPrs_Point.hxx>
5ad8c033 71#include <StdPrs_WFShape.hxx>
7fd59977 72#include <TColStd_Array1OfReal.hxx>
73#include <TColStd_Array2OfReal.hxx>
74#include <TopExp.hxx>
75#include <TopExp_Explorer.hxx>
7fd59977 76#include <TopoDS.hxx>
42cf5bc1 77#include <TopoDS_Edge.hxx>
78#include <TopoDS_Face.hxx>
79#include <TopoDS_Shape.hxx>
80#include <TopoDS_Vertex.hxx>
81#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
7fd59977 82
08cd2f6b 83const Standard_Real SquareTolerance = Precision::SquareConfusion();
7fd59977 84
85//=======================================================================
86//function : Nearest
87//purpose :
88//=======================================================================
7fd59977 89gp_Pnt AIS::Nearest(const TopoDS_Shape& ashape, const gp_Pnt& apoint)
90{
91 Standard_Real dist2 = RealLast();
92 Standard_Real curdist2;
93 gp_Pnt result(0.0,0.0,0.0);
94 gp_Pnt curpnt(0.0,0.0,0.0);
95 TopExp_Explorer explo(ashape,TopAbs_VERTEX);
96 while (explo.More())
97 {
98 curpnt = BRep_Tool::Pnt(TopoDS::Vertex(explo.Current()));
99 curdist2 = apoint.SquareDistance(curpnt);
100 if (curdist2 < dist2)
101 {
102 result = curpnt;
103 dist2 = curdist2;
104 }
105 explo.Next();
106 }
107 return result;
108}
109
60bf98ae 110//=======================================================================
111//function : Nearest
112//purpose : For <thePoint> finds the nearest point on <theLine>.
113//=======================================================================
114gp_Pnt AIS::Nearest (const gp_Lin& theLine, const gp_Pnt& thePoint)
115{
116 Handle(Geom_Line) aLine = new Geom_Line (theLine);
117
118 GeomAPI_ProjectPointOnCurve aPointProj (thePoint, aLine);
119 return aPointProj.Point (1);
120}
121
122//=======================================================================
123//function : Nearest
124//purpose : For the given point finds nearest point on the curve,
125// return TRUE if found point is belongs to curve
126// and FALSE otherwise.
127//=======================================================================
128Standard_Boolean AIS::Nearest (const Handle(Geom_Curve)& theCurve,
129 const gp_Pnt& thePoint,
130 const gp_Pnt& theFirstPoint,
131 const gp_Pnt& theLastPoint,
132 gp_Pnt& theNearestPoint)
133{
134 GeomAPI_ProjectPointOnCurve aPointProj (thePoint, theCurve);
135 theNearestPoint = theCurve->Value (aPointProj.LowerDistanceParameter());
136
137 Standard_Real aLength = theFirstPoint.Distance (theLastPoint);
138
139 if (theNearestPoint.Distance (theFirstPoint) > aLength
140 || theNearestPoint.Distance (theLastPoint) >aLength)
141 {
142 return Standard_False;
143 }
144
145 return Standard_True;
146}
147
7fd59977 148//=======================================================================
149//function : Farest
150//purpose :
151//=======================================================================
7fd59977 152gp_Pnt AIS::Farest( const TopoDS_Shape& aShape, const gp_Pnt& aPoint )
153{
154 Standard_Real MaxDist2 = 0.0e0, curdist2;
155 gp_Pnt Result(0.0,0.0,0.0);
156 gp_Pnt curpnt(0.0,0.0,0.0);
157 TopExp_Explorer Explo( aShape, TopAbs_VERTEX );
158 for (; Explo.More(); Explo.Next())
159 {
160 curpnt = BRep_Tool::Pnt( TopoDS::Vertex( Explo.Current() ) );
161 curdist2 = aPoint.SquareDistance( curpnt );
162 if (curdist2 > MaxDist2)
163 {
164 MaxDist2 = curdist2;
165 Result = curpnt;
166 }
167 }
168 return Result;
169}
170
171
172//=======================================================================
173//function : ComputeGeometry
60bf98ae 174//purpose : for line, circle, ellipse.
7fd59977 175//=======================================================================
60bf98ae 176Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theEdge,
177 Handle(Geom_Curve)& theCurve,
178 gp_Pnt& theFirstPnt,
179 gp_Pnt& theLastPnt)
180{
181 TopLoc_Location anEdgeLoc;
182 Standard_Real aFirst, aLast;
183 theCurve = BRep_Tool::Curve (theEdge, anEdgeLoc, aFirst, aLast);
184 if (theCurve.IsNull())
185 {
186 return Standard_False;
187 }
188
189 if (!anEdgeLoc.IsIdentity())
190 {
191 Handle(Geom_Geometry) aGeometry = theCurve->Transformed (anEdgeLoc.Transformation());
c5f3a425 192 theCurve = Handle(Geom_Curve)::DownCast (aGeometry);
60bf98ae 193 }
194
195 if (theCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
196 {
c5f3a425 197 theCurve = Handle(Geom_TrimmedCurve)::DownCast (theCurve)->BasisCurve();
60bf98ae 198 }
199
200 if (theCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
201 {
c5f3a425 202 Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theCurve);
60bf98ae 203 theFirstPnt = ElCLib::Value (aFirst, aLine->Lin());
204 theLastPnt = ElCLib::Value (aLast, aLine->Lin());
205 }
206 else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Circle)))
207 {
c5f3a425 208 Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theCurve);
60bf98ae 209
210 theFirstPnt = ElCLib::Value (aFirst, aCirc->Circ());
211 theLastPnt = ElCLib::Value (aLast, aCirc->Circ());
212 }
213 else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Ellipse)))
214 {
c5f3a425 215 Handle(Geom_Ellipse) anEllipse = Handle(Geom_Ellipse)::DownCast (theCurve);
60bf98ae 216 theFirstPnt = ElCLib::Value (aFirst, anEllipse->Elips());
217 theLastPnt = ElCLib::Value (aLast, anEllipse->Elips());
218 }
219 else
220 {
221 return Standard_False;
222 }
7fd59977 223
60bf98ae 224 return Standard_True;
225}
226
227//=======================================================================
228//function : ComputeGeometry
229//purpose : for line, circle, ellipse.
230//=======================================================================
231Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theEdge,
232 Handle(Geom_Curve)& theCurve,
233 gp_Pnt& theFirstPnt,
234 gp_Pnt& theLastPnt,
235 Standard_Boolean& theIsInfinite)
7fd59977 236{
60bf98ae 237 Standard_Real aFirst, aLast;
238
239 BRepAdaptor_Curve anAdaptor (theEdge);
240
241 theCurve = Handle(Geom_Curve)::DownCast
242 (anAdaptor.Curve().Curve()->Transformed (anAdaptor.Trsf()));
243
244 if (theCurve.IsNull())
245 {
246 return Standard_False;
247 }
248
249 aFirst = anAdaptor.FirstParameter();
250 aLast = anAdaptor.LastParameter();
251
252 theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast));
253
254 if (theCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
255 {
c5f3a425 256 theCurve = Handle(Geom_TrimmedCurve)::DownCast (theCurve)->BasisCurve();
60bf98ae 257 }
258
259 if (!theIsInfinite)
260 {
261 theFirstPnt = theCurve->Value (aFirst);
262 theLastPnt = theCurve->Value (aLast);
263 }
264 else
265 {
266 theFirstPnt = gp::Origin();
267 theLastPnt = gp::Origin();
268 }
269
7fd59977 270 return Standard_True;
271}
272
273//=======================================================================
274//function : ComputeGeometry
275//purpose :
276//=======================================================================
277
60bf98ae 278Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theEdge,
279 Handle(Geom_Curve)& theCurve,
280 gp_Pnt& theFirstPnt,
281 gp_Pnt& theLastPnt,
282 Handle(Geom_Curve)& theExtCurve,
283 Standard_Boolean& theIsInfinite,
284 Standard_Boolean& theIsOnPlane,
285 const Handle(Geom_Plane)& thePlane)
7fd59977 286{
60bf98ae 287 if (thePlane.IsNull())
288 {
289 return Standard_False;
290 }
7fd59977 291
60bf98ae 292 Standard_Real aFirst, aLast;
293 BRepAdaptor_Curve aCurveAdaptor (theEdge);
294 theCurve = Handle(Geom_Curve)::DownCast (aCurveAdaptor.Curve().Curve()->Transformed (aCurveAdaptor.Trsf()));
295 aFirst = aCurveAdaptor.FirstParameter();
296 aLast = aCurveAdaptor.LastParameter();
7fd59977 297
60bf98ae 298 if (theCurve.IsNull())
299 {
300 return Standard_False;
301 }
7fd59977 302
60bf98ae 303 theExtCurve = theCurve;
304 theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast));
305
306 // Checks that the projected curve is not in the plane.
307 theIsOnPlane = Standard_True;
308 if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
309 {
c5f3a425 310 theExtCurve = Handle(Geom_TrimmedCurve)::DownCast (theExtCurve)->BasisCurve();
60bf98ae 311 }
7fd59977 312
60bf98ae 313 if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
314 {
c5f3a425 315 Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theExtCurve);
60bf98ae 316 theIsOnPlane = thePlane->Pln().Contains (aLine->Lin(),
317 Precision::Confusion(),
318 Precision::Angular());
7fd59977 319 }
60bf98ae 320 else if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_Circle)))
321 {
c5f3a425 322 Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast (theExtCurve);
60bf98ae 323
324 gp_Ax3 aCircPos (aCircle->Position());
325 theIsOnPlane = aCircPos.IsCoplanar (thePlane->Pln().Position(),
326 Precision::Confusion(),
327 Precision::Angular());
328 }
329
330 if (theIsOnPlane)
331 {
332 theExtCurve.Nullify();
333 }
334
335 theCurve = GeomProjLib::ProjectOnPlane (theCurve, thePlane,
336 thePlane->Pln().Axis().Direction(),
337 Standard_False);
338
339 if (theCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
340 {
c5f3a425 341 Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theCurve);
60bf98ae 342 if (!theIsInfinite)
343 {
344 theFirstPnt = ElCLib::Value (aFirst, aLine->Lin());
345 theLastPnt = ElCLib::Value (aLast, aLine->Lin());
7fd59977 346 }
347 }
60bf98ae 348 else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Circle)))
349 {
c5f3a425 350 Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theCurve);
60bf98ae 351
352 theFirstPnt = ElCLib::Value (aFirst, aCirc->Circ());
353 theLastPnt = ElCLib::Value (aLast, aCirc->Circ());
7fd59977 354 }
60bf98ae 355 else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Ellipse)))
7fd59977 356 {
c5f3a425 357 Handle(Geom_Ellipse) anEllipse = Handle(Geom_Ellipse)::DownCast (theCurve);
60bf98ae 358
359 theFirstPnt = ElCLib::Value (aFirst, anEllipse->Elips());
360 theLastPnt = ElCLib::Value (aLast, anEllipse->Elips());
7fd59977 361 }
60bf98ae 362 else
363 {
364 return Standard_False;
365 }
366
7fd59977 367 return Standard_True;
368}
369
370//=======================================================================
371//function : ComputeGeometry
372//purpose :
373//=======================================================================
60bf98ae 374Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
375 const TopoDS_Edge& theSecondEdge,
376 Handle(Geom_Curve)& theFirstCurve,
377 Handle(Geom_Curve)& theSecondCurve,
378 gp_Pnt& theFirstPnt1,
379 gp_Pnt& theLastPnt1,
380 gp_Pnt& theFirstPnt2,
381 gp_Pnt& theLastPnt2,
382 const Handle(Geom_Plane)& thePlane)
7fd59977 383{
60bf98ae 384 if (thePlane.IsNull())
385 {
386 return Standard_False;
387 }
7fd59977 388
60bf98ae 389 TopLoc_Location aFirstEdgeLoc, aSecondEdgeLoc;
390 Standard_Real aFirst1, aLast1, aFirst2, aLast2;
7fd59977 391
60bf98ae 392 theFirstCurve = BRep_Tool::Curve (theFirstEdge, aFirstEdgeLoc, aFirst1, aLast1);
393 theSecondCurve = BRep_Tool::Curve (theSecondEdge, aSecondEdgeLoc, aFirst2, aLast2);
7fd59977 394
60bf98ae 395 if (theFirstCurve.IsNull())
396 {
397 return Standard_False;
398 }
399
400 if (theSecondCurve.IsNull())
401 {
402 return Standard_False;
403 }
7fd59977 404
60bf98ae 405 if (!aFirstEdgeLoc.IsIdentity())
406 {
407 Handle(Geom_Geometry) aGeomGeometry = theFirstCurve->Transformed (aFirstEdgeLoc.Transformation());
c5f3a425 408 theFirstCurve = Handle(Geom_Curve)::DownCast (aGeomGeometry);
60bf98ae 409 }
410
411 if (!aSecondEdgeLoc.IsIdentity())
412 {
413 Handle(Geom_Geometry) aGeomGeometry = theSecondCurve->Transformed (aSecondEdgeLoc.Transformation());
c5f3a425 414 theSecondCurve = Handle(Geom_Curve)::DownCast (aGeomGeometry);
60bf98ae 415 }
416
417 theFirstCurve = GeomProjLib::ProjectOnPlane (theFirstCurve, thePlane,
418 thePlane->Pln().Axis().Direction(),
419 Standard_False);
420
421
422 theSecondCurve = GeomProjLib::ProjectOnPlane (theSecondCurve, thePlane,
423 thePlane->Pln().Axis().Direction(),
424 Standard_False);
425
426
427 if (theFirstCurve->IsInstance (STANDARD_TYPE(Geom_TrimmedCurve)))
428 {
c5f3a425 429 theFirstCurve = Handle(Geom_TrimmedCurve)::DownCast (theFirstCurve)->BasisCurve();
60bf98ae 430 }
431
432 if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
433 {
c5f3a425 434 theSecondCurve = Handle(Geom_TrimmedCurve)::DownCast (theSecondCurve)->BasisCurve();
60bf98ae 435 }
436
437 if (theFirstCurve->IsInstance(STANDARD_TYPE(Geom_Line)))
438 {
c5f3a425 439 Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theFirstCurve);
60bf98ae 440
441 theFirstPnt1 = ElCLib::Value (aFirst1, aLine->Lin());
442 theLastPnt1 = ElCLib::Value (aLast1, aLine->Lin());
443 }
444 else if (theFirstCurve->IsInstance(STANDARD_TYPE(Geom_Circle)))
445 {
c5f3a425 446 Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theFirstCurve);
60bf98ae 447
448 theFirstPnt1 = ElCLib::Value (aFirst1, aCirc->Circ());
449 theLastPnt1 = ElCLib::Value (aLast1, aCirc->Circ());
450 }
451 else
452 {
453 return Standard_False;
454 }
455
456 if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
457{
c5f3a425 458 Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theSecondCurve);
60bf98ae 459
460 theFirstPnt2 = ElCLib::Value (aFirst2, aLine->Lin());
461 theLastPnt2 = ElCLib::Value (aLast2, aLine->Lin());
462 }
463 else if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_Circle)))
464 {
c5f3a425 465 Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theSecondCurve);
60bf98ae 466
467 theFirstPnt2 = ElCLib::Value (aFirst2, aCirc->Circ());
468 theLastPnt2 = ElCLib::Value (aLast2, aCirc->Circ());
469 }
470 else
471 {
472 return Standard_False;
473 }
7fd59977 474
475 return Standard_True;
476}
477
60bf98ae 478//=======================================================================
479//function : ComputeGeometry
480//purpose : Computes the geometry of the 2 edges.
481//=======================================================================
482Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
483 const TopoDS_Edge& theSecondEdge,
484 Handle(Geom_Curve)& theFirstCurve,
485 Handle(Geom_Curve)& theSecondCurve,
486 gp_Pnt& theFirstPnt1,
487 gp_Pnt& theLastPnt1,
488 gp_Pnt& theFirstPnt2,
489 gp_Pnt& theLastPnt2,
490 Standard_Boolean& theIsInfinite1,
491 Standard_Boolean& theIsInfinite2)
492{
493 theIsInfinite1 = theIsInfinite2 = Standard_False;
494
495 if (!AIS::ComputeGeometry (theFirstEdge, theFirstCurve,theFirstPnt1, theLastPnt1, theIsInfinite1))
496 {
497 return Standard_False;
498 }
499
500 if (!AIS::ComputeGeometry (theSecondEdge, theSecondCurve,theFirstPnt2, theLastPnt2, theIsInfinite2))
501 {
502 return Standard_False;
503 }
504
505 if (theIsInfinite1 || theIsInfinite2)
506 {
507 if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType())
508 {
c5f3a425 509 gp_Lin aLin1 = Handle(Geom_Line)::DownCast (theFirstCurve)->Lin();
510 gp_Lin aLin2 = Handle(Geom_Line)::DownCast (theSecondCurve)->Lin();
60bf98ae 511
512 if (theIsInfinite1)
513 {
514 theFirstPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theFirstPnt2), aLin1);
515 theLastPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theLastPnt2), aLin1);
516 }
517 else if (theIsInfinite2)
518 {
519 theFirstPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theFirstPnt1), aLin2);
520 theLastPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theLastPnt1), aLin2);
521 }
522 }
523 else
524 {
525 if (theIsInfinite1 && !theIsInfinite2)
526 {
527 GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt2, theFirstCurve);
528 theFirstPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter ());
529
530 aProjector.Init (theLastPnt2, theFirstCurve);
531 theLastPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter ());
532 }
533 else if (!theIsInfinite1 && theIsInfinite2)
534 {
535 GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt1, theSecondCurve);
536 theFirstPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter ());
537
538 aProjector.Init (theLastPnt1, theSecondCurve);
539 theLastPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter ());
540 }
541 else
542 {
543 return Standard_False;
544 }
545 }
546 }
547
548 return Standard_True;
549}
550
7fd59977 551//=======================================================================
552//function : ComputeGeometry
553//purpose : Computes the geometry of the 2 edges in the current wp
a6eb515f 554// and the 'right' geometry of the edges if one doesn't
555// belong to the current working plane.
7fd59977 556// There may be only one curve that can't belong to the
a6eb515f 557// current working plane ( attachement constraint)
7fd59977 558// if the 2 edges belong to the current WP, <WhatProj> = 0
559//
560// indexExt = 0 2 edges are in the current wp
561// indexExt = 1 first edge is not in the current wp
562// indexExt = 2 second edge is not in the current wp
563// if none of the two edges is in the current wp ,
564// it returns Standard_False
565//=======================================================================
60bf98ae 566Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
567 const TopoDS_Edge& theSecondEdge,
568 Standard_Integer& theExtIndex,
569 Handle(Geom_Curve)& theFirstCurve,
570 Handle(Geom_Curve)& theSecondCurve,
571 gp_Pnt& theFirstPnt1,
572 gp_Pnt& theLastPnt1,
573 gp_Pnt& theFirstPnt2,
574 gp_Pnt& theLastPnt2,
575 Handle(Geom_Curve)& theExtCurve,
576 Standard_Boolean& theIsInfinite1,
577 Standard_Boolean& theIsInfinite2,
578 const Handle(Geom_Plane)& thePlane)
7fd59977 579{
60bf98ae 580 if (thePlane.IsNull())
581 {
582 return Standard_False;
583 }
584
585 theExtCurve.Nullify();
586 theExtIndex = 0;
587
588 Standard_Real aFirst1, aLast1, aFirst2, aLast2;
589 theIsInfinite1 = theIsInfinite2 = Standard_False;
7fd59977 590
60bf98ae 591 BRepAdaptor_Curve aFirstAdaptor (theFirstEdge);
592 BRepAdaptor_Curve aSecondAdaptor (theSecondEdge);
7fd59977 593
60bf98ae 594 theFirstCurve = Handle(Geom_Curve)::DownCast
595 (aFirstAdaptor.Curve().Curve()->Transformed (aFirstAdaptor.Trsf()));
596 theSecondCurve = Handle(Geom_Curve)::DownCast
597 (aSecondAdaptor.Curve().Curve()->Transformed (aSecondAdaptor.Trsf()));
598
599 if (theFirstCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
600 {
c5f3a425 601 theFirstCurve = Handle(Geom_TrimmedCurve)::DownCast (theFirstCurve)->BasisCurve();
7fd59977 602 }
60bf98ae 603 if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
604 {
c5f3a425 605 theSecondCurve = Handle(Geom_TrimmedCurve)::DownCast (theSecondCurve)->BasisCurve();
7fd59977 606 }
607
60bf98ae 608 aFirst1 = aFirstAdaptor.FirstParameter();
609 aLast1 = aFirstAdaptor.LastParameter();
7fd59977 610
60bf98ae 611 aFirst2 = aSecondAdaptor.FirstParameter();
612 aLast2 = aSecondAdaptor.LastParameter();
613
614 if (theFirstCurve.IsNull() || theSecondCurve.IsNull())
615 {
7fd59977 616 return Standard_False;
60bf98ae 617 }
618
619 Handle(Geom_Curve) aFirstSaved = theFirstCurve;
620 Handle(Geom_Curve) aSecondSaved = theSecondCurve;
621
622 // Checks that the projected curve is not in the plane
623 Standard_Boolean isFirstOnPlane,isSecondOnPlane;
624
625 if ((!ComputeGeomCurve (theFirstCurve, aFirst1, aLast1, theFirstPnt1, theLastPnt1, thePlane, isFirstOnPlane))
626 || (!ComputeGeomCurve( theSecondCurve, aFirst2, aLast2, theFirstPnt2, theLastPnt2, thePlane,isSecondOnPlane)))
627 {
628 return Standard_False;
629 }
630
631 if (Precision::IsInfinite (aFirst1) || Precision::IsInfinite (aLast1))
632 {
633 theIsInfinite1 = Standard_True;
634 theExtIndex = 1;
635 }
636 if (Precision::IsInfinite (aFirst2) || Precision::IsInfinite (aLast2))
637 {
638 theIsInfinite2 = Standard_True;
639 theExtIndex = 2;
640 }
641 if (theIsInfinite1 && theIsInfinite2)
642 {
643 theExtIndex = 0;
644 }
645
646 if (theIsInfinite1 || theIsInfinite2)
647 {
648 if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType())
649 {
c5f3a425 650 gp_Lin aLin1 = Handle(Geom_Line)::DownCast (theFirstCurve)->Lin();
651 gp_Lin aLin2 = Handle(Geom_Line)::DownCast (theSecondCurve)->Lin();
60bf98ae 652
653 if (theExtIndex == 1)
654 {
655 theFirstPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theFirstPnt2), aLin1);
656 theLastPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theLastPnt2), aLin1);
7fd59977 657 }
60bf98ae 658 else if (theExtIndex == 2)
659 {
660 theFirstPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theFirstPnt1), aLin2);
661 theLastPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theLastPnt1), aLin2);
7fd59977 662 }
663 }
664 }
665
60bf98ae 666 if (isFirstOnPlane && isSecondOnPlane)
667 {
668 return Standard_True;
669 }
7fd59977 670
60bf98ae 671 if (!isFirstOnPlane && isSecondOnPlane)
672 {// curve 2 only in the plane
673 theExtIndex = 1;
674 theExtCurve = aFirstSaved;
7fd59977 675 }
60bf98ae 676 else if (isFirstOnPlane && !isSecondOnPlane)
677 {// curve 1 only in the plane
678 theExtIndex = 2;
679 theExtCurve = aSecondSaved;
7fd59977 680 }
681 else
60bf98ae 682 {
7fd59977 683 return Standard_False;
60bf98ae 684 }
685
7fd59977 686 return Standard_True;
687}
688
7fd59977 689//=======================================================================
690//function : ComputeGeomCurve
691//purpose : Checks if aCurve belongs to aPlane; if not, projects aCurve in aPlane
692// and returns aCurveproj;
693// Return TRUE if ok
694//=======================================================================
60bf98ae 695Standard_Boolean AIS::ComputeGeomCurve (Handle(Geom_Curve)& aCurve,
696 const Standard_Real first1,
697 const Standard_Real last1,
698 gp_Pnt& FirstPnt1,
699 gp_Pnt& LastPnt1,
700 const Handle(Geom_Plane)& aPlane,
701 Standard_Boolean& isOnPlane)
7fd59977 702{
703 isOnPlane = Standard_True;
7fd59977 704 const Standard_Integer NodeNumber = 20;
705 Standard_Real Delta = (last1 - first1) / (NodeNumber - 1);
706 if (Delta <= Precision::PConfusion())
60bf98ae 707 {
7fd59977 708 Delta = last1 - first1;
60bf98ae 709 }
710
711 gp_Pnt CurPnt(0.0, 0.0, 0.0);
7fd59977 712 Standard_Real CurPar = first1;
713 for (Standard_Integer i = 1; i <= NodeNumber; i++)
60bf98ae 714 {
715 CurPnt = aCurve->Value( CurPar );
716 if (aPlane->Pln().SquareDistance( CurPnt ) > SquareTolerance)
7fd59977 717 {
60bf98ae 718 isOnPlane = Standard_False;
719 break;
7fd59977 720 }
60bf98ae 721 CurPar += Delta;
722 }
723
724 if (!Precision::IsInfinite(first1) && !Precision::IsInfinite(last1))
725 {
726 FirstPnt1 = aCurve->Value (first1);
727 LastPnt1 = aCurve->Value (last1);
728 }
729
730 if (!isOnPlane)
731 {
732 Handle(Geom_Curve) aGeomCurve = GeomProjLib::ProjectOnPlane (aCurve,
733 aPlane,
734 aPlane->Pln().Axis().Direction(),
735 Standard_False);
736 aCurve = aGeomCurve;
737 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
7fd59977 738 {
c5f3a425 739 aCurve = Handle(Geom_TrimmedCurve)::DownCast (aCurve)->BasisCurve();
7fd59977 740 }
60bf98ae 741 if (! Precision::IsInfinite(first1) && ! Precision::IsInfinite(last1))
742 {
7fd59977 743 FirstPnt1 = AIS::ProjectPointOnPlane( FirstPnt1, aPlane->Pln() );
744 LastPnt1 = AIS::ProjectPointOnPlane( LastPnt1, aPlane->Pln() );
745 }
746 }
747 return Standard_True;
748}
749
7fd59977 750//=======================================================================
751//function : ComputeGeometry
752//purpose : computes the point corresponding to the vertex <aVertex>
753// in the plane <aPlane>. If the vertex is already in the plane
754// <isOnPlane>, <isOnPlane> = true.
755// <point> is the projected vertex in the plane.
756//=======================================================================
7fd59977 757Standard_Boolean AIS::ComputeGeometry(const TopoDS_Vertex& aVertex,
758 gp_Pnt& point,
759 const Handle(Geom_Plane)& aPlane,
760 Standard_Boolean& isOnPlane)
761{
762 point = BRep_Tool::Pnt(aVertex);
763 isOnPlane = aPlane->Pln().Contains(point, Precision::Confusion());
764 if ( !isOnPlane) {
765 point = AIS::ProjectPointOnPlane( point, aPlane->Pln() );
766 }
767 return Standard_True;
768}
769
770//=======================================================================
771//function : GetPlaneFromFace
772//purpose :
773// Returns type of surface which can be Plane or OtherSurface
774//=======================================================================
60bf98ae 775Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
7fd59977 776 gp_Pln & aPlane,
777 Handle( Geom_Surface )& aSurf,
778 AIS_KindOfSurface & aSurfType,
60bf98ae 779 Standard_Real & Offset)
7fd59977 780
781{
782 Standard_Boolean Result = Standard_False;
783 BRepAdaptor_Surface surf1( aFace );
784 Handle( Adaptor3d_HSurface ) surf2;
7fd59977 785 Standard_Boolean isOffset = Standard_False;
912761ea 786 Offset = 0.0;
7fd59977 787
788 if (surf1.GetType() == GeomAbs_OffsetSurface)
60bf98ae 789 {
790 // Extracting Basis Surface
791 surf2 = surf1.BasisSurface();
792 isOffset = Standard_True;
793 }
7fd59977 794 else
795 surf2 = new BRepAdaptor_HSurface( surf1 );
796
797 aSurf = surf1.Surface().Surface();
798 // aSurf->Transform(surf1.Trsf()) ;
799 aSurf = Handle( Geom_Surface )::DownCast( aSurf->Transformed( surf1.Trsf() ) );
800
801 if (surf2->GetType() == GeomAbs_Plane)
60bf98ae 802 {
803 aPlane = surf2->Plane();
804 aSurfType = AIS_KOS_Plane;
60bf98ae 805 Result = Standard_True;
806 }
807
808 else if (surf2->GetType() == GeomAbs_SurfaceOfExtrusion)
809 {
810 Handle( Adaptor3d_HCurve ) BasisCurve = surf2->BasisCurve();
811 gp_Dir ExtrusionDir = surf2->Direction();
812 if (BasisCurve->GetType() == GeomAbs_Line)
7fd59977 813 {
60bf98ae 814 gp_Lin BasisLine = BasisCurve->Line();
815 gp_Dir LineDir = BasisLine.Direction();
816 gp_Pnt LinePos = BasisLine.Location();
817 gp_Pln thePlane( LinePos, LineDir ^ ExtrusionDir);
818 aPlane = thePlane;
7fd59977 819 aSurfType = AIS_KOS_Plane;
7fd59977 820 Result = Standard_True;
821 }
60bf98ae 822 }
7fd59977 823
824 if (Result == Standard_True && isOffset)
60bf98ae 825 {
826 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
827 aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln();
60bf98ae 828 }
7fd59977 829 if (Result == Standard_False)
60bf98ae 830 {
831 if (isOffset)
7fd59977 832 {
7fd59977 833 Handle( Standard_Type ) TheType = aSurf->DynamicType();
60bf98ae 834 if (TheType == STANDARD_TYPE(Geom_CylindricalSurface) ||
835 TheType == STANDARD_TYPE(Geom_ConicalSurface) ||
836 TheType == STANDARD_TYPE(Geom_SphericalSurface) ||
837 TheType == STANDARD_TYPE(Geom_ToroidalSurface))
838 {
839 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
60bf98ae 840 }
7fd59977 841 else
60bf98ae 842 {
843 Offset = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Offset();
844 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->BasisSurface();
845 }
7fd59977 846 }
60bf98ae 847 Handle( Standard_Type ) TheType = aSurf->DynamicType();
848 if (TheType == STANDARD_TYPE(Geom_CylindricalSurface))
849 aSurfType = AIS_KOS_Cylinder;
850 else if (TheType == STANDARD_TYPE(Geom_ConicalSurface))
851 aSurfType = AIS_KOS_Cone;
852 else if (TheType == STANDARD_TYPE(Geom_SphericalSurface))
853 aSurfType = AIS_KOS_Sphere;
854 else if (TheType == STANDARD_TYPE(Geom_ToroidalSurface))
855 aSurfType = AIS_KOS_Torus;
856 else if (TheType == STANDARD_TYPE(Geom_SurfaceOfRevolution))
857 aSurfType = AIS_KOS_Revolution;
858 else if (TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
859 aSurfType = AIS_KOS_Extrusion;
860 else
861 aSurfType = AIS_KOS_OtherSurface;
862 }
7fd59977 863 return Result;
864}
865
866
867//=======================================================================
868//function : ProjectPointOnPlane
869//purpose :
870//=======================================================================
871
872gp_Pnt AIS::ProjectPointOnPlane( const gp_Pnt & aPoint, const gp_Pln & aPlane )
873{
874 gp_Vec aVec( aPlane.Location(), aPoint );
875 gp_Vec Normal = aPlane.Axis().Direction();
876 Normal = (aVec * Normal) * Normal;
877
878 return ( aPoint.Translated( -Normal ) );
879}
880
881//=======================================================================
882//function : ProjectPointOnLine
883//purpose :
884//=======================================================================
885
886gp_Pnt AIS::ProjectPointOnLine( const gp_Pnt & aPoint, const gp_Lin & aLine )
887{
888 gp_XYZ LinLoc = aLine.Location().XYZ();
889 gp_XYZ LinDir = aLine.Direction().XYZ();
890 Standard_Real Parameter = (aPoint.XYZ() - LinLoc) * LinDir;
891 gp_Pnt Result( LinLoc + Parameter * LinDir );
892 return Result;
893}
894
7fd59977 895//=======================================================================
896//function : InitFaceLength
897//purpose :
898//=======================================================================
912761ea 899void AIS::InitFaceLength (const TopoDS_Face& theFace,
900 gp_Pln& thePlane,
901 Handle(Geom_Surface)& theSurface,
902 AIS_KindOfSurface& theSurfaceType,
903 Standard_Real& theOffset)
7fd59977 904{
912761ea 905 if (AIS::GetPlaneFromFace (theFace, thePlane, theSurface, theSurfaceType, theOffset)
906 && Abs (theOffset) > Precision::Confusion())
907 {
908 theSurface = new Geom_OffsetSurface (theSurface, theOffset);
909 theOffset = 0.0e0;
910 }
7fd59977 911}
912
913//=======================================================================
60bf98ae 914//function : InitAngleBetweenPlanarFaces
7fd59977 915//purpose :
916//=======================================================================
60bf98ae 917Standard_Boolean AIS::InitAngleBetweenPlanarFaces (const TopoDS_Face& theFirstFace,
918 const TopoDS_Face& theSecondFace,
919 gp_Pnt & theCenter,
920 gp_Pnt & theFirstAttach,
921 gp_Pnt & theSecondAttach,
922 const Standard_Boolean theIsFirstPointSet)
7fd59977 923{
60bf98ae 924 Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (BRep_Tool::Surface (theFirstFace));
925 Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (BRep_Tool::Surface (theSecondFace));
7fd59977 926
60bf98ae 927 GeomAPI_IntSS aPlaneIntersector (aFirstPlane, aSecondPlane, Precision::Confusion());
928
929 // Fails if two planes haven't only one intersection line.
930 if (!aPlaneIntersector.IsDone())
931 {
932 return Standard_False;
933 }
7fd59977 934
60bf98ae 935 if (aPlaneIntersector.NbLines() != 1)
936 {
937 return Standard_False;
938 }
7fd59977 939
60bf98ae 940 // Get intersect line.
941 Handle(Geom_Curve) anIntersectCurve = aPlaneIntersector.Line (1);
942
943 Handle(Geom_Line) anIntersectLine = Handle(Geom_Line)::DownCast (anIntersectCurve);
944
945 if (anIntersectLine.IsNull())
946 {
947 return Standard_False;
7fd59977 948 }
949
60bf98ae 950 gp_Lin anIntersectLin = anIntersectLine->Lin();
951
952 gp_Pnt aFirstCenter, aSecondCenter;
953 Standard_Real anU1Min, anU1Max, aV1Min, aV1Max;
954 Standard_Real anU2Min, anU2Max, aV2Min, aV2Max;
7fd59977 955
60bf98ae 956 BRepTools::UVBounds (theFirstFace, anU1Min, anU1Max, aV1Min, aV1Max);
957 BRepTools::UVBounds (theSecondFace, anU2Min, anU2Max, aV2Min, aV2Max);
958
959 // Get first and second attach.
960 if (theIsFirstPointSet)
961 {
962 GeomAPI_ProjectPointOnSurf aProjector (theFirstAttach, aFirstPlane);
963 if (!aProjector.IsDone())
7fd59977 964 {
60bf98ae 965 return Standard_False;
7fd59977 966 }
7fd59977 967
60bf98ae 968 aFirstCenter = aProjector.Point (1);
969 }
7fd59977 970 else
60bf98ae 971 {
972 aFirstCenter = aFirstPlane->Value ((anU1Min + anU1Max) * 0.5, (aV1Min + aV1Max) * 0.5);
973 }
974
975 aSecondCenter = aSecondPlane->Value ((anU2Min + anU2Max) * 0.5, (aV2Min + aV2Max) * 0.5);
976
977 GeomAPI_ProjectPointOnCurve aProj (aFirstCenter, anIntersectCurve);
978 theCenter = aProj.NearestPoint();
979
980 gp_Vec aFirstNormal = anIntersectLin.Direction() ^ aFirstPlane->Pln().Axis().Direction();
981 if (aFirstNormal * gp_Vec (theCenter, aFirstCenter) < 0.0)
982 {
983 aFirstNormal.Reverse();
984 }
985 theFirstAttach = theCenter.Translated (aFirstNormal);
986
987 gp_Vec aSecondNormal = anIntersectLin.Direction() ^ aSecondPlane->Pln().Axis().Direction();
988 if (aSecondNormal * gp_Vec (theCenter, aSecondCenter) < 0.0)
989 {
990 aSecondNormal.Reverse();
991 }
992 theSecondAttach = theCenter.Translated (aSecondNormal);
993
994 return Standard_True;
7fd59977 995}
60bf98ae 996
997//=======================================================================
998//function : InitAngleBetweenCurvilinearFaces
999//purpose :
1000//=======================================================================
1001Standard_Boolean AIS::InitAngleBetweenCurvilinearFaces (const TopoDS_Face& theFirstFace,
1002 const TopoDS_Face& theSecondFace,
1003 const AIS_KindOfSurface theFirstSurfType,
1004 const AIS_KindOfSurface theSecondSurfType,
1005 gp_Pnt& theCenter,
1006 gp_Pnt& theFirstAttach,
1007 gp_Pnt& theSecondAttach,
1008 const Standard_Boolean theIsFirstPointSet)
7fd59977 1009{
60bf98ae 1010 Handle(Geom_Surface) aFirstSurf = BRep_Tool::Surface (theFirstFace);
1011 Handle(Geom_Surface) aSecondSurf = BRep_Tool::Surface (theSecondFace);
1012
1013 // Find intersection curve between two surfaces.
1014 GeomAPI_IntSS aSurfaceIntersector (aFirstSurf, aSecondSurf, Precision::Confusion());
1015
1016 // Fails if two planes haven't only one intersection line.
1017 if (!aSurfaceIntersector.IsDone())
1018 {
1019 return Standard_False;
1020 }
1021
1022 if (aSurfaceIntersector.NbLines() != 1)
1023 {
1024 return Standard_False;
1025 }
1026
1027 // Get intersect line.
1028 Handle(Geom_Curve) anIntersectCurve = aSurfaceIntersector.Line (1);
1029
1030 Handle(Geom_Line) aFirstLine, aSecondLine;
1031 Standard_Real aFirstU = 0.0;
1032 Standard_Real aFirstV = 0.0;
1033
1034 if (theIsFirstPointSet)
1035 {
1036 GeomAPI_ProjectPointOnSurf aProjector (theFirstAttach, aFirstSurf);
1037 if (!aProjector.IsDone())
7fd59977 1038 {
60bf98ae 1039 return Standard_False;
7fd59977 1040 }
7fd59977 1041
60bf98ae 1042 theFirstAttach = aProjector.Point (1);
1043 }
1044 else
1045 {
1046 theFirstAttach = aFirstSurf->Value (aFirstU, aFirstV);
1047 }
1048
1049 aFirstLine = Handle(Geom_Line)::DownCast (aFirstSurf->UIso (aFirstU));
1050
1051 if (theSecondSurfType == AIS_KOS_Cylinder)
1052 {
1053 Handle(Geom_CylindricalSurface) aCylinder = Handle(Geom_CylindricalSurface)::DownCast (aSecondSurf);
1054
1055 Standard_Real aSecondU = aCylinder->Cylinder().XAxis().Direction().Angle(
1056 gce_MakeDir (ProjectPointOnLine (theFirstAttach,
1057 gp_Lin (aCylinder->Cylinder().Axis())),
1058 theFirstAttach));
1059
1060 aSecondLine = Handle(Geom_Line)::DownCast (aCylinder->UIso (aSecondU));
1061 }
1062 else if (theSecondSurfType == AIS_KOS_Cone)
1063 {
1064 Handle(Geom_ConicalSurface) aCone = Handle(Geom_ConicalSurface)::DownCast (aSecondSurf);
1065
1066 gp_Dir anXdirection = aCone->Cone().XAxis().Direction();
1067
1068 gp_Dir aToFirstAttach = gce_MakeDir (ProjectPointOnLine (theFirstAttach,
1069 gp_Lin (aCone->Cone().Axis())),
1070 theFirstAttach);
1071
1072 Standard_Real aSecondU = anXdirection.Angle (aToFirstAttach);
1073
1074 // Check sign
1075 if (!anXdirection.IsEqual (aToFirstAttach, Precision::Angular()) &&
1076 !anXdirection.IsOpposite (aToFirstAttach, Precision::Angular()) &&
1077 (anXdirection ^ aToFirstAttach) * aCone->Cone().Axis().Direction() < 0.0)
7fd59977 1078 {
60bf98ae 1079 aSecondU = 2*M_PI - aSecondU;
7fd59977 1080 }
60bf98ae 1081 aSecondLine = Handle( Geom_Line )::DownCast (aCone->UIso(aSecondU));
1082 }
1083 else
1084 {
1085 return Standard_False;
1086 }
1087
1088 // If angle can be computed between two lines.
1089 if (!(aFirstLine->Lin().Direction().IsEqual (aSecondLine->Lin().Direction(), Precision::Angular() )) &&
1090 !(aFirstLine->Lin().Direction().IsOpposite (aSecondLine->Lin().Direction(), Precision::Angular())))
1091 {
1092 GeomAPI_ExtremaCurveCurve anIntersector (aFirstLine, aSecondLine);
1093 anIntersector.Points (1, theCenter, theCenter);
1094
1095 // Move theFirstAttach on aFirstLine if it is on theCenter.
1096 if (theCenter.SquareDistance(theFirstAttach ) <= SquareTolerance)
7fd59977 1097 {
60bf98ae 1098 gp_Vec aDir (aFirstLine->Lin().Direction());
1099 theFirstAttach = theCenter.Translated (aDir);
1100
1101 // theFirstAttach should be on theFirstSurf.
1102 Standard_Real anU, aV;
1103 if (theFirstSurfType == AIS_KOS_Cylinder)
1104 {
1105 ElSLib::Parameters ((Handle(Geom_CylindricalSurface)::DownCast (aFirstSurf))->Cylinder(),
1106 theFirstAttach, anU, aV);
1107
1108 theFirstAttach = ElSLib::Value (aFirstU, aV,
1109 (Handle( Geom_CylindricalSurface )::DownCast (aFirstSurf))->Cylinder() );
1110 }
1111 else if (theFirstSurfType == AIS_KOS_Cone)
1112 {
1113 ElSLib::Parameters ((Handle(Geom_ConicalSurface)::DownCast (aFirstSurf))->Cone(),
1114 theFirstAttach, anU, aV);
1115 theFirstAttach = ElSLib::Value (aFirstU, aV,
1116 (Handle(Geom_ConicalSurface)::DownCast (aFirstSurf))->Cone());
1117 }
1118 else
1119 {
1120 return Standard_False;
1121 }
7fd59977 1122 }
1123
60bf98ae 1124 // Find theSecondAttach
1125 GeomAPI_ProjectPointOnSurf aProjector (theFirstAttach, aSecondSurf);
1126 if (!aProjector.IsDone())
1127 {
1128 return Standard_False;
7fd59977 1129 }
ee2be2a8 1130 Standard_Real anU, aV;
60bf98ae 1131 aProjector.LowerDistanceParameters (anU, aV);
1132 theSecondAttach = aSecondSurf->Value (anU, aV);
1133 }
1134 else // aFirstLine and aSecondLine are coincident
1135 {
1136 gp_Vec aDir (aFirstLine->Lin().Direction());
1137 theFirstAttach = theCenter.Translated (aDir);
1138 theSecondAttach = theCenter.Translated (-aDir);
1139 }
1140 return Standard_True;
7fd59977 1141}
1142
60bf98ae 1143//=======================================================================
1144//function : ComputeLengthBetweenCurvilinearFaces
1145//purpose :
1146//=======================================================================
1147void AIS::InitLengthBetweenCurvilinearFaces (const TopoDS_Face& theFirstFace,
1148 const TopoDS_Face& theSecondFace,
1149 Handle(Geom_Surface)& theFirstSurf,
1150 Handle(Geom_Surface)& theSecondSurf,
1151 gp_Pnt& theFirstAttach,
1152 gp_Pnt& theSecondAttach,
1153 gp_Dir& theDirOnPlane)
7fd59977 1154{
1155 GeomAPI_ProjectPointOnSurf aProjector;
ee2be2a8 1156 Standard_Real aPU, aPV;
60bf98ae 1157
1158 TopExp_Explorer anExplorer (theFirstFace, TopAbs_VERTEX);
1159
1160 theFirstAttach = BRep_Tool::Pnt (TopoDS::Vertex (anExplorer.Current()));
1161 aProjector.Init (theFirstAttach, theFirstSurf);
1162
1163 theFirstAttach = aProjector.NearestPoint();
1164 aProjector.LowerDistanceParameters (aPU, aPV);
1165
1166 gp_Vec aD1U, aD1V;
1167 theFirstSurf->D1 (aPU, aPV, theFirstAttach, aD1U, aD1V);
1168
1169 if (aD1U.SquareMagnitude() <= SquareTolerance || aD1V.SquareMagnitude() <= SquareTolerance)
1170 {
1171 theFirstAttach = AIS::Farest (theFirstFace, theFirstAttach);
1172 aProjector.Init (theFirstAttach, theFirstSurf);
1173 aProjector.LowerDistanceParameters (aPU, aPV);
1174 theFirstSurf->D1 (aPU, aPV, theFirstAttach, aD1U, aD1V);
1175 }
7fd59977 1176
60bf98ae 1177 aD1U.Normalize();
1178 aD1V.Normalize();
1179
1180 theDirOnPlane = gp_Dir (aD1U);
1181
1182 gp_Dir aFirstSurfN = gp_Dir (aD1U ^ aD1V);
1183
1184 aProjector.Init (theFirstAttach, theSecondSurf);
1185
1186 Standard_Integer aBestPointIndex = 0;
ee2be2a8 1187 Standard_Real aMinDist = RealLast();
60bf98ae 1188 gp_Dir aLocalDir;
1189
1190 for (Standard_Integer aPointIt = 1; aPointIt <= aProjector.NbPoints(); aPointIt++)
1191 {
1192 aProjector.Parameters (aPointIt, aPU, aPV);
1193
1194 theSecondSurf->D1 (aPU, aPV, theSecondAttach, aD1U, aD1V);
1195
1196 aLocalDir = aD1U.SquareMagnitude() <= SquareTolerance || aD1V.SquareMagnitude() <= SquareTolerance
1197 ? gp_Dir (gp_Vec (theFirstAttach, aProjector.Point (aPointIt)))
1198 : gp_Dir (aD1U ^ aD1V);
1199
1200 if (aFirstSurfN.IsParallel (aLocalDir, Precision::Angular()) && aProjector.Distance (aPointIt) < aMinDist)
7fd59977 1201 {
60bf98ae 1202 aBestPointIndex = aPointIt;
1203 aMinDist = aProjector.Distance (aPointIt);
7fd59977 1204 }
60bf98ae 1205 }
7fd59977 1206
60bf98ae 1207 if (aBestPointIndex == 0)
1208 {
1209 theSecondAttach = theFirstAttach;
1210 }
1211 else
1212 {
1213 theSecondAttach = aProjector.Point (aBestPointIndex);
1214 aProjector.Parameters (aBestPointIndex, aPU, aPV);
1215
1216 // Now there is projection of FirstAttach onto SecondSurf in aProjector
1217 BRepTopAdaptor_FClass2d aClassifier (theSecondFace, Precision::Confusion());
1218
1219 TopAbs_State aState =
1220 aClassifier.Perform (gp_Pnt2d (aPU, aPV), theSecondSurf->IsUPeriodic() || theSecondSurf->IsVPeriodic());
1221
1222 if (aState == TopAbs_OUT || aState == TopAbs_UNKNOWN)
1223 {
1224 theSecondAttach = AIS::Nearest (theSecondFace, theSecondAttach);
7fd59977 1225 }
60bf98ae 1226 }
7fd59977 1227}
60bf98ae 1228
7fd59977 1229gp_Pnt AIS::TranslatePointToBound( const gp_Pnt & aPoint, const gp_Dir & aDir, const Bnd_Box & aBndBox )
1230{
1231 if (aBndBox.IsOut( aPoint ))
1232 return aPoint;
1233 else
1234 {
1235 gp_Pnt Result(0.0,0.0,0.0);
1236 TColStd_Array2OfReal Bound( 1, 3, 1, 2 );
1237 TColStd_Array1OfReal Origin( 1, 3 );
1238 TColStd_Array1OfReal Dir( 1, 3 );
1239 Standard_Real t;
1240
1241 aBndBox.Get( Bound(1,1), Bound(2,1), Bound(3,1), Bound(1,2), Bound(2,2), Bound(3,2) );
1242 aPoint.Coord( Origin(1), Origin(2), Origin(3) );
1243 aDir.Coord( Dir(1), Dir(2), Dir(3) );
1244
1245 Bnd_Box EnlargedBox = aBndBox;
1246 EnlargedBox.Enlarge( aBndBox.GetGap() + Precision::Confusion() );
1247
1248 Standard_Boolean IsFound = Standard_False;
1249 for (Standard_Integer i = 1; i <= 3; i++)
1250 {
1251 if (Abs( Dir( i ) ) <= gp::Resolution())
1252 continue;
1253 for (Standard_Integer j = 1; j <= 2; j++)
1254 {
1255 t = (Bound( i, j ) - Origin( i )) / Dir( i );
1256 if (t < 0.0e0)
1257 continue;
1258 Result = aPoint.Translated( gp_Vec( aDir ) * t );
1259 if (! EnlargedBox.IsOut( Result ))
1260 {
1261 IsFound = Standard_True;
1262 break;
1263 }
1264 }
1265 if (IsFound) break;
1266 }
1267 return Result;
1268 }
1269}
1270
1271
1272//=======================================================================
1273//function : InDomain
1274//purpose :
1275//=======================================================================
1276
1277Standard_Boolean AIS::InDomain(const Standard_Real fpar,
1278 const Standard_Real lpar,
1279 const Standard_Real para)
1280{
1281 if (fpar >= 0.) {
1282 if(lpar > fpar)
1283 return ((para >= fpar) && (para <= lpar));
1284 else { // fpar > lpar
c6541a0c 1285 Standard_Real delta = 2*M_PI-fpar;
7fd59977 1286 Standard_Real lp, par, fp;
1287 lp = lpar + delta;
1288 par = para + delta;
c6541a0c
D
1289 while(lp > 2*M_PI) lp-=2*M_PI;
1290 while(par > 2*M_PI) par-=2*M_PI;
7fd59977 1291 fp = 0.;
1292 return ((par >= fp) && (par <= lp));
1293 }
1294
1295 }
c6541a0c 1296 if (para >= (fpar+2*M_PI)) return Standard_True;
7fd59977 1297 if (para <= lpar) return Standard_True;
1298 return Standard_False;
1299}
1300
1301//=======================================================================
1302//function : DistanceFromApex
1303//purpose : calculates parametric length arc of ellipse
1304//=======================================================================
1305
1306Standard_Real AIS::DistanceFromApex(const gp_Elips & elips,
1307 const gp_Pnt & Apex,
1308 const Standard_Real par)
1309{
1310 Standard_Real dist;
1311 Standard_Real parApex = ElCLib::Parameter ( elips, Apex );
c6541a0c 1312 if(parApex == 0.0 || parApex == M_PI)
7fd59977 1313 {//Major case
1314 if(parApex == 0.0) //pos Apex
c6541a0c 1315 dist = (par < M_PI) ? par : (2*M_PI - par);
7fd59977 1316 else //neg Apex
c6541a0c 1317 dist = (par < M_PI) ? ( M_PI - par) : ( par - M_PI );
7fd59977 1318 }
1319 else
1320 {// Minor case
c6541a0c 1321 if(parApex == M_PI / 2) //pos Apex
7fd59977 1322 {
c6541a0c 1323 if(par <= parApex + M_PI && par > parApex) // 3/2*M_PI < par < M_PI/2
7fd59977 1324 dist = par - parApex;
1325 else
1326 {
c6541a0c
D
1327 if(par > parApex + M_PI) // 3/2*M_PI < par < 2*M_PI
1328 dist = 2*M_PI - par + parApex;
7fd59977 1329 else
1330 dist = parApex - par;
1331 }
1332 }
c6541a0c 1333 else //neg Apex == 3/2*M_PI
7fd59977 1334 {
c6541a0c 1335 if(par <= parApex && par >= M_PI/2) // M_PI/2 < par < 3/2*M_PI
7fd59977 1336 dist = parApex - par;
1337 else
1338 {
c6541a0c 1339 if(par > parApex) // 3/2*M_PI < par < 2*M_PI
7fd59977 1340 dist = par - parApex;
1341 else
c6541a0c 1342 dist = par + M_PI/2; // 0 < par < M_PI/2
7fd59977 1343 }
1344 }
1345 }
1346 return dist;
1347}
1348
1349//=======================================================================
1350//function : NearestApex
1351//purpose :
1352//=======================================================================
1353
1354gp_Pnt AIS::NearestApex(const gp_Elips & elips,
1355 const gp_Pnt & pApex,
1356 const gp_Pnt & nApex,
1357 const Standard_Real fpara,
1358 const Standard_Real lpara,
1359 Standard_Boolean & IsInDomain)
1360{
1361 Standard_Real parP, parN;
1362 gp_Pnt EndOfArrow(0.0,0.0,0.0);
1363 IsInDomain = Standard_True;
1364 parP = ElCLib::Parameter ( elips, pApex );
1365 if(InDomain(fpara, lpara, parP)) EndOfArrow = pApex;
1366 else
1367 {
1368 parN = ElCLib::Parameter ( elips, nApex );
1369 if(InDomain(fpara, lpara, parN)) EndOfArrow = nApex;
1370 else {
1371 IsInDomain = Standard_False;
1372 Standard_Real posd = Min(DistanceFromApex (elips,pApex, fpara),
1373 DistanceFromApex (elips,pApex, lpara));
1374 Standard_Real negd = Min(DistanceFromApex (elips,nApex, fpara),
1375 DistanceFromApex (elips,nApex, lpara));
1376 if( posd < negd )
1377 EndOfArrow = pApex;
1378 else
1379 EndOfArrow = nApex;
1380 }
1381 }
1382 return EndOfArrow;
1383}
1384
1385//=======================================================================
1386//function : ComputeProjEdgePresentation
1387//purpose :
1388//=======================================================================
1389
6262338c 1390void AIS::ComputeProjEdgePresentation (const Handle(Prs3d_Presentation)& aPresentation,
1391 const Handle(Prs3d_Drawer)& aDrawer,
1392 const TopoDS_Edge& anEdge,
1393 const Handle(Geom_Curve)& ProjCurve,
1394 const gp_Pnt& FirstP,
1395 const gp_Pnt& LastP,
1396 const Quantity_NameOfColor aColor,
1397 const Standard_Real aWidth,
1398 const Aspect_TypeOfLine aProjTOL,
1399 const Aspect_TypeOfLine aCallTOL)
7fd59977 1400{
6262338c 1401 if (!aDrawer->HasOwnWireAspect()){
7fd59977 1402 aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aProjTOL,2.));}
1403 else {
1404 // CLE
1405 // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect();
1406 Handle(Prs3d_LineAspect) li = aDrawer->WireAspect();
1407 // ENDCLE
1408 li->SetColor(aColor);
1409 li->SetTypeOfLine(aProjTOL);
1410 li->SetWidth(aWidth);
1411 }
1412
1413 Standard_Real pf, pl;
1414 TopLoc_Location loc;
1415 Handle(Geom_Curve) curve;
1416 Standard_Boolean isInfinite;
1417 curve = BRep_Tool::Curve(anEdge,loc,pf,pl);
1418 isInfinite = (Precision::IsInfinite(pf) || Precision::IsInfinite(pl));
1419
1420 TopoDS_Edge E;
1421
0d969553 1422 // Calculate presentation of the edge
7fd59977 1423 if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
1424 // CLE
c5f3a425 1425 // Handle(Geom_Line) gl (Handle(Geom_Line)::DownCast (ProjCurve));
1426 Handle(Geom_Line) gl = Handle(Geom_Line)::DownCast (ProjCurve);
7fd59977 1427 // ENDCLE
1428 if ( !isInfinite) {
1429 pf = ElCLib::Parameter(gl->Lin(),FirstP);
1430 pl = ElCLib::Parameter(gl->Lin(),LastP);
1431 BRepBuilderAPI_MakeEdge MakEd(gl->Lin(), pf, pl);
1432 E = MakEd.Edge();
1433 }
1434 else {
1435 BRepBuilderAPI_MakeEdge MakEd(gl->Lin());
1436 E = MakEd.Edge();
1437 }
1438 }
1439 else if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
1440 // CLE
c5f3a425 1441 // Handle(Geom_Circle) gc (Handle(Geom_Circle)::DownCast (ProjCurve));
1442 Handle(Geom_Circle) gc = Handle(Geom_Circle)::DownCast (ProjCurve);
7fd59977 1443 // ENDCLE
1444 pf = ElCLib::Parameter(gc->Circ(),FirstP);
1445 pl = ElCLib::Parameter(gc->Circ(),LastP);
1446 BRepBuilderAPI_MakeEdge MakEd(gc->Circ(),pf, pl);
1447 E = MakEd.Edge();
1448 }
5ad8c033 1449 StdPrs_WFShape::Add (aPresentation, E, aDrawer);
7fd59977 1450
0d969553 1451 //Calculate the presentation of line connections
7fd59977 1452 aDrawer->WireAspect()->SetTypeOfLine(aCallTOL);
1453 if (!isInfinite) {
1454 gp_Pnt ppf(0.0,0.0,0.0), ppl(0.0,0.0,0.0);
1455 ppf = BRep_Tool::Pnt( TopExp::FirstVertex(TopoDS::Edge(anEdge)));
1456 ppl = BRep_Tool::Pnt( TopExp::LastVertex(TopoDS::Edge(anEdge)));
1457
1458 // it is patch!
5ad8c033 1459 if (FirstP.SquareDistance (ppf) > SquareTolerance)
1460 {
1461 BRepBuilderAPI_MakeEdge MakEd1 (FirstP, ppf);
1462 StdPrs_WFShape::Add (aPresentation, MakEd1.Edge(), aDrawer);
1463 }
7fd59977 1464 else
5ad8c033 1465 {
1466 BRepBuilderAPI_MakeVertex MakVert1 (FirstP);
1467 StdPrs_WFShape::Add (aPresentation, MakVert1.Vertex(), aDrawer);
1468 }
1469 if (LastP.SquareDistance (ppl) > SquareTolerance)
1470 {
1471 BRepBuilderAPI_MakeEdge MakEd2 (LastP, ppl);
1472 StdPrs_WFShape::Add (aPresentation, MakEd2.Edge(), aDrawer);
1473 }
7fd59977 1474 else
5ad8c033 1475 {
1476 BRepBuilderAPI_MakeVertex MakVert2 (LastP);
1477 StdPrs_WFShape::Add (aPresentation, MakVert2.Vertex(), aDrawer);
1478 }
7fd59977 1479/*
5ad8c033 1480 BRepBuilderAPI_MakeEdge MakEd1 (FirstP, ppf);
1481 StdPrs_WFShape::Add (aPresentation, MakEd1.Edge(), aDrawer);
1482 BRepBuilderAPI_MakeEdge MakEd2 (LastP, ppl);
1483 StdPrs_WFShape::Add (aPresentation, MakEd2.Edge(), aDrawer);
7fd59977 1484*/
1485 }
1486}
1487
1488//=======================================================================
1489//function : ComputeProjVertexPresentation
1490//purpose :
1491//=======================================================================
1492
6262338c 1493void AIS::ComputeProjVertexPresentation (const Handle( Prs3d_Presentation )& aPresentation,
1494 const Handle( Prs3d_Drawer )& aDrawer,
1495 const TopoDS_Vertex& aVertex,
1496 const gp_Pnt& ProjPoint,
1497 const Quantity_NameOfColor aColor,
1498 const Standard_Real aWidth,
1499 const Aspect_TypeOfMarker aProjTOM,
1500 const Aspect_TypeOfLine aCallTOL)
7fd59977 1501{
6262338c 1502 if (!aDrawer->HasOwnPointAspect()){
7fd59977 1503 aDrawer->SetPointAspect(new Prs3d_PointAspect(aProjTOM, aColor,1));}
1504 else {
1505 // CLE
1506 // const Handle(Prs3d_PointAspect)& pa = aDrawer->PointAspect();
1507 Handle(Prs3d_PointAspect) pa = aDrawer->PointAspect();
1508 // ENDCLE
1509 pa->SetColor(aColor);
1510 pa->SetTypeOfMarker(aProjTOM);
1511 }
1512
0d969553 1513 // calculate the projection
7fd59977 1514 StdPrs_Point::Add(aPresentation, new Geom_CartesianPoint(ProjPoint), aDrawer);
1515
6262338c 1516 if (!aDrawer->HasOwnWireAspect()){
7fd59977 1517 aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aCallTOL,2.));}
1518 else {
1519 // CLE
1520 // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect();
1521 Handle(Prs3d_LineAspect) li = aDrawer->WireAspect();
1522 // ENDCLE
1523 li->SetColor(aColor);
1524 li->SetTypeOfLine(aCallTOL);
1525 li->SetWidth(aWidth);
1526 }
1527
0d969553 1528 // If the points are not mixed...
5ad8c033 1529 if (!ProjPoint.IsEqual (BRep_Tool::Pnt (aVertex), Precision::Confusion()))
1530 {
0d969553 1531 // calculate the lines of recall
5ad8c033 1532 BRepBuilderAPI_MakeEdge MakEd (ProjPoint, BRep_Tool::Pnt (aVertex));
1533 StdPrs_WFShape::Add (aPresentation, MakEd.Edge(), aDrawer);
7fd59977 1534 }
1535}