1 // Created on: 1996-12-11
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
25 #include <Adaptor3d_HCurve.hxx>
26 #include <Adaptor3d_HSurface.hxx>
28 #include <BRepBuilderAPI_MakeEdge.hxx>
29 #include <BRepBuilderAPI_MakeVertex.hxx>
30 #include <BRepAdaptor_Curve.hxx>
31 #include <BRepAdaptor_HSurface.hxx>
32 #include <BRepAdaptor_Surface.hxx>
33 #include <BRepTopAdaptor_FClass2d.hxx>
34 #include <BRep_Tool.hxx>
35 #include <BRepTools.hxx>
36 #include <Bnd_Box.hxx>
41 #include <GccEnt_QualifiedLin.hxx>
42 #include <gce_MakeDir.hxx>
43 #include <gce_MakeLin.hxx>
44 #include <Geom2d_Circle.hxx>
45 #include <GeomAPI_ExtremaCurveCurve.hxx>
46 #include <GeomAPI_IntSS.hxx>
47 #include <GeomAPI_ProjectPointOnCurve.hxx>
48 #include <GeomAPI_ProjectPointOnSurf.hxx>
49 #include <GeomLib.hxx>
50 #include <GeomProjLib.hxx>
51 #include <GeomProjLib.hxx>
52 #include <Geom_CartesianPoint.hxx>
53 #include <Geom_Circle.hxx>
54 #include <Geom_ConicalSurface.hxx>
55 #include <Geom_Curve.hxx>
56 #include <Geom_CylindricalSurface.hxx>
57 #include <Geom_Ellipse.hxx>
58 #include <Geom_Line.hxx>
59 #include <Geom_OffsetSurface.hxx>
60 #include <Geom_Plane.hxx>
61 #include <Geom_SphericalSurface.hxx>
62 #include <Geom_SurfaceOfLinearExtrusion.hxx>
63 #include <Geom_SurfaceOfRevolution.hxx>
64 #include <Geom_ToroidalSurface.hxx>
65 #include <Geom_TrimmedCurve.hxx>
69 #include <gp_Elips.hxx>
75 #include <Precision.hxx>
76 #include <Prs3d_LineAspect.hxx>
77 #include <Prs3d_PointAspect.hxx>
78 #include <StdPrs_Point.hxx>
79 #include <StdPrs_WFDeflectionShape.hxx>
80 #include <TColStd_Array1OfReal.hxx>
81 #include <TColStd_Array2OfReal.hxx>
83 #include <TopExp_Explorer.hxx>
84 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
87 const Standard_Real SquareTolerance = Precision::SquareConfusion();
89 //=======================================================================
92 //=======================================================================
93 gp_Pnt AIS::Nearest(const TopoDS_Shape& ashape, const gp_Pnt& apoint)
95 Standard_Real dist2 = RealLast();
96 Standard_Real curdist2;
97 gp_Pnt result(0.0,0.0,0.0);
98 gp_Pnt curpnt(0.0,0.0,0.0);
99 TopExp_Explorer explo(ashape,TopAbs_VERTEX);
102 curpnt = BRep_Tool::Pnt(TopoDS::Vertex(explo.Current()));
103 curdist2 = apoint.SquareDistance(curpnt);
104 if (curdist2 < dist2)
114 //=======================================================================
116 //purpose : For <thePoint> finds the nearest point on <theLine>.
117 //=======================================================================
118 gp_Pnt AIS::Nearest (const gp_Lin& theLine, const gp_Pnt& thePoint)
120 Handle(Geom_Line) aLine = new Geom_Line (theLine);
122 GeomAPI_ProjectPointOnCurve aPointProj (thePoint, aLine);
123 return aPointProj.Point (1);
126 //=======================================================================
128 //purpose : For the given point finds nearest point on the curve,
129 // return TRUE if found point is belongs to curve
130 // and FALSE otherwise.
131 //=======================================================================
132 Standard_Boolean AIS::Nearest (const Handle(Geom_Curve)& theCurve,
133 const gp_Pnt& thePoint,
134 const gp_Pnt& theFirstPoint,
135 const gp_Pnt& theLastPoint,
136 gp_Pnt& theNearestPoint)
138 GeomAPI_ProjectPointOnCurve aPointProj (thePoint, theCurve);
139 theNearestPoint = theCurve->Value (aPointProj.LowerDistanceParameter());
141 Standard_Real aLength = theFirstPoint.Distance (theLastPoint);
143 if (theNearestPoint.Distance (theFirstPoint) > aLength
144 || theNearestPoint.Distance (theLastPoint) >aLength)
146 return Standard_False;
149 return Standard_True;
152 //=======================================================================
155 //=======================================================================
156 gp_Pnt AIS::Farest( const TopoDS_Shape& aShape, const gp_Pnt& aPoint )
158 Standard_Real MaxDist2 = 0.0e0, curdist2;
159 gp_Pnt Result(0.0,0.0,0.0);
160 gp_Pnt curpnt(0.0,0.0,0.0);
161 TopExp_Explorer Explo( aShape, TopAbs_VERTEX );
162 for (; Explo.More(); Explo.Next())
164 curpnt = BRep_Tool::Pnt( TopoDS::Vertex( Explo.Current() ) );
165 curdist2 = aPoint.SquareDistance( curpnt );
166 if (curdist2 > MaxDist2)
176 //=======================================================================
177 //function : ComputeGeometry
178 //purpose : for line, circle, ellipse.
179 //=======================================================================
180 Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theEdge,
181 Handle(Geom_Curve)& theCurve,
185 TopLoc_Location anEdgeLoc;
186 Standard_Real aFirst, aLast;
187 theCurve = BRep_Tool::Curve (theEdge, anEdgeLoc, aFirst, aLast);
188 if (theCurve.IsNull())
190 return Standard_False;
193 if (!anEdgeLoc.IsIdentity())
195 Handle(Geom_Geometry) aGeometry = theCurve->Transformed (anEdgeLoc.Transformation());
196 theCurve = (Handle(Geom_Curve)&) aGeometry;
199 if (theCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
201 theCurve = ((Handle(Geom_TrimmedCurve)&) theCurve)->BasisCurve();
204 if (theCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
206 Handle(Geom_Line) aLine = (Handle(Geom_Line)&) theCurve;
207 theFirstPnt = ElCLib::Value (aFirst, aLine->Lin());
208 theLastPnt = ElCLib::Value (aLast, aLine->Lin());
210 else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Circle)))
212 Handle(Geom_Circle) aCirc = (Handle(Geom_Circle)&) theCurve;
214 theFirstPnt = ElCLib::Value (aFirst, aCirc->Circ());
215 theLastPnt = ElCLib::Value (aLast, aCirc->Circ());
217 else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Ellipse)))
219 Handle(Geom_Ellipse) anEllipse = (Handle(Geom_Ellipse)&) theCurve;
220 theFirstPnt = ElCLib::Value (aFirst, anEllipse->Elips());
221 theLastPnt = ElCLib::Value (aLast, anEllipse->Elips());
225 return Standard_False;
228 return Standard_True;
231 //=======================================================================
232 //function : ComputeGeometry
233 //purpose : for line, circle, ellipse.
234 //=======================================================================
235 Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theEdge,
236 Handle(Geom_Curve)& theCurve,
239 Standard_Boolean& theIsInfinite)
241 Standard_Real aFirst, aLast;
243 BRepAdaptor_Curve anAdaptor (theEdge);
245 theCurve = Handle(Geom_Curve)::DownCast
246 (anAdaptor.Curve().Curve()->Transformed (anAdaptor.Trsf()));
248 if (theCurve.IsNull())
250 return Standard_False;
253 aFirst = anAdaptor.FirstParameter();
254 aLast = anAdaptor.LastParameter();
256 theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast));
258 if (theCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
260 theCurve = ((Handle(Geom_TrimmedCurve)&) theCurve)->BasisCurve();
265 theFirstPnt = theCurve->Value (aFirst);
266 theLastPnt = theCurve->Value (aLast);
270 theFirstPnt = gp::Origin();
271 theLastPnt = gp::Origin();
274 return Standard_True;
277 //=======================================================================
278 //function : ComputeGeometry
280 //=======================================================================
282 Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theEdge,
283 Handle(Geom_Curve)& theCurve,
286 Handle(Geom_Curve)& theExtCurve,
287 Standard_Boolean& theIsInfinite,
288 Standard_Boolean& theIsOnPlane,
289 const Handle(Geom_Plane)& thePlane)
291 if (thePlane.IsNull())
293 return Standard_False;
296 Standard_Real aFirst, aLast;
297 BRepAdaptor_Curve aCurveAdaptor (theEdge);
298 theCurve = Handle(Geom_Curve)::DownCast (aCurveAdaptor.Curve().Curve()->Transformed (aCurveAdaptor.Trsf()));
299 aFirst = aCurveAdaptor.FirstParameter();
300 aLast = aCurveAdaptor.LastParameter();
302 if (theCurve.IsNull())
304 return Standard_False;
307 theExtCurve = theCurve;
308 theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast));
310 // Checks that the projected curve is not in the plane.
311 theIsOnPlane = Standard_True;
312 if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
314 theExtCurve = ((Handle(Geom_TrimmedCurve)&) theExtCurve)->BasisCurve();
317 if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
319 Handle(Geom_Line) aLine = (Handle(Geom_Line)&) theExtCurve;
320 theIsOnPlane = thePlane->Pln().Contains (aLine->Lin(),
321 Precision::Confusion(),
322 Precision::Angular());
324 else if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_Circle)))
326 Handle(Geom_Circle) aCircle = (Handle(Geom_Circle)&) theExtCurve;
328 gp_Ax3 aCircPos (aCircle->Position());
329 theIsOnPlane = aCircPos.IsCoplanar (thePlane->Pln().Position(),
330 Precision::Confusion(),
331 Precision::Angular());
336 theExtCurve.Nullify();
339 theCurve = GeomProjLib::ProjectOnPlane (theCurve, thePlane,
340 thePlane->Pln().Axis().Direction(),
343 if (theCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
345 Handle(Geom_Line) aLine = (Handle(Geom_Line)&) theCurve;
348 theFirstPnt = ElCLib::Value (aFirst, aLine->Lin());
349 theLastPnt = ElCLib::Value (aLast, aLine->Lin());
352 else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Circle)))
354 Handle(Geom_Circle) aCirc = (Handle(Geom_Circle)&) theCurve;
356 theFirstPnt = ElCLib::Value (aFirst, aCirc->Circ());
357 theLastPnt = ElCLib::Value (aLast, aCirc->Circ());
359 else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Ellipse)))
361 Handle(Geom_Ellipse) anEllipse = (Handle(Geom_Ellipse)&) theCurve;
363 theFirstPnt = ElCLib::Value (aFirst, anEllipse->Elips());
364 theLastPnt = ElCLib::Value (aLast, anEllipse->Elips());
368 return Standard_False;
371 return Standard_True;
374 //=======================================================================
375 //function : ComputeGeometry
377 //=======================================================================
378 Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
379 const TopoDS_Edge& theSecondEdge,
380 Handle(Geom_Curve)& theFirstCurve,
381 Handle(Geom_Curve)& theSecondCurve,
382 gp_Pnt& theFirstPnt1,
384 gp_Pnt& theFirstPnt2,
386 const Handle(Geom_Plane)& thePlane)
388 if (thePlane.IsNull())
390 return Standard_False;
393 TopLoc_Location aFirstEdgeLoc, aSecondEdgeLoc;
394 Standard_Real aFirst1, aLast1, aFirst2, aLast2;
396 theFirstCurve = BRep_Tool::Curve (theFirstEdge, aFirstEdgeLoc, aFirst1, aLast1);
397 theSecondCurve = BRep_Tool::Curve (theSecondEdge, aSecondEdgeLoc, aFirst2, aLast2);
399 if (theFirstCurve.IsNull())
401 return Standard_False;
404 if (theSecondCurve.IsNull())
406 return Standard_False;
409 if (!aFirstEdgeLoc.IsIdentity())
411 Handle(Geom_Geometry) aGeomGeometry = theFirstCurve->Transformed (aFirstEdgeLoc.Transformation());
412 theFirstCurve = (Handle(Geom_Curve)&) aGeomGeometry;
415 if (!aSecondEdgeLoc.IsIdentity())
417 Handle(Geom_Geometry) aGeomGeometry = theSecondCurve->Transformed (aSecondEdgeLoc.Transformation());
418 theSecondCurve = (Handle(Geom_Curve)&) aGeomGeometry;
421 theFirstCurve = GeomProjLib::ProjectOnPlane (theFirstCurve, thePlane,
422 thePlane->Pln().Axis().Direction(),
426 theSecondCurve = GeomProjLib::ProjectOnPlane (theSecondCurve, thePlane,
427 thePlane->Pln().Axis().Direction(),
431 if (theFirstCurve->IsInstance (STANDARD_TYPE(Geom_TrimmedCurve)))
433 theFirstCurve = ((Handle(Geom_TrimmedCurve)&) theFirstCurve)->BasisCurve();
436 if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
438 theSecondCurve = ((Handle(Geom_TrimmedCurve)&) theSecondCurve)->BasisCurve();
441 if (theFirstCurve->IsInstance(STANDARD_TYPE(Geom_Line)))
443 Handle(Geom_Line) aLine = (Handle(Geom_Line)&) theFirstCurve;
445 theFirstPnt1 = ElCLib::Value (aFirst1, aLine->Lin());
446 theLastPnt1 = ElCLib::Value (aLast1, aLine->Lin());
448 else if (theFirstCurve->IsInstance(STANDARD_TYPE(Geom_Circle)))
450 Handle(Geom_Circle) aCirc = (Handle(Geom_Circle)&) theFirstCurve;
452 theFirstPnt1 = ElCLib::Value (aFirst1, aCirc->Circ());
453 theLastPnt1 = ElCLib::Value (aLast1, aCirc->Circ());
457 return Standard_False;
460 if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
462 Handle(Geom_Line) aLine = (Handle(Geom_Line)&) theSecondCurve;
464 theFirstPnt2 = ElCLib::Value (aFirst2, aLine->Lin());
465 theLastPnt2 = ElCLib::Value (aLast2, aLine->Lin());
467 else if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_Circle)))
469 Handle(Geom_Circle) aCirc = (Handle(Geom_Circle)&) theSecondCurve;
471 theFirstPnt2 = ElCLib::Value (aFirst2, aCirc->Circ());
472 theLastPnt2 = ElCLib::Value (aLast2, aCirc->Circ());
476 return Standard_False;
479 return Standard_True;
482 //=======================================================================
483 //function : ComputeGeometry
484 //purpose : Computes the geometry of the 2 edges.
485 //=======================================================================
486 Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
487 const TopoDS_Edge& theSecondEdge,
488 Handle(Geom_Curve)& theFirstCurve,
489 Handle(Geom_Curve)& theSecondCurve,
490 gp_Pnt& theFirstPnt1,
492 gp_Pnt& theFirstPnt2,
494 Standard_Boolean& theIsInfinite1,
495 Standard_Boolean& theIsInfinite2)
497 theIsInfinite1 = theIsInfinite2 = Standard_False;
499 if (!AIS::ComputeGeometry (theFirstEdge, theFirstCurve,theFirstPnt1, theLastPnt1, theIsInfinite1))
501 return Standard_False;
504 if (!AIS::ComputeGeometry (theSecondEdge, theSecondCurve,theFirstPnt2, theLastPnt2, theIsInfinite2))
506 return Standard_False;
509 if (theIsInfinite1 || theIsInfinite2)
511 if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType())
513 gp_Lin aLin1 = ((Handle(Geom_Line)&) theFirstCurve)->Lin();
514 gp_Lin aLin2 = ((Handle(Geom_Line)&) theSecondCurve)->Lin();
518 theFirstPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theFirstPnt2), aLin1);
519 theLastPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theLastPnt2), aLin1);
521 else if (theIsInfinite2)
523 theFirstPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theFirstPnt1), aLin2);
524 theLastPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theLastPnt1), aLin2);
529 if (theIsInfinite1 && !theIsInfinite2)
531 GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt2, theFirstCurve);
532 theFirstPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter ());
534 aProjector.Init (theLastPnt2, theFirstCurve);
535 theLastPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter ());
537 else if (!theIsInfinite1 && theIsInfinite2)
539 GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt1, theSecondCurve);
540 theFirstPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter ());
542 aProjector.Init (theLastPnt1, theSecondCurve);
543 theLastPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter ());
547 return Standard_False;
552 return Standard_True;
555 //=======================================================================
556 //function : ComputeGeometry
557 //purpose : Computes the geometry of the 2 edges in the current wp
558 // and the 'right' geometry of the edges if one doesn't
559 // belong to the current working plane.
560 // There may be only one curve that can't belong to the
561 // current working plane ( attachement constraint)
562 // if the 2 edges belong to the current WP, <WhatProj> = 0
564 // indexExt = 0 2 edges are in the current wp
565 // indexExt = 1 first edge is not in the current wp
566 // indexExt = 2 second edge is not in the current wp
567 // if none of the two edges is in the current wp ,
568 // it returns Standard_False
569 //=======================================================================
570 Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
571 const TopoDS_Edge& theSecondEdge,
572 Standard_Integer& theExtIndex,
573 Handle(Geom_Curve)& theFirstCurve,
574 Handle(Geom_Curve)& theSecondCurve,
575 gp_Pnt& theFirstPnt1,
577 gp_Pnt& theFirstPnt2,
579 Handle(Geom_Curve)& theExtCurve,
580 Standard_Boolean& theIsInfinite1,
581 Standard_Boolean& theIsInfinite2,
582 const Handle(Geom_Plane)& thePlane)
584 if (thePlane.IsNull())
586 return Standard_False;
589 theExtCurve.Nullify();
592 Standard_Real aFirst1, aLast1, aFirst2, aLast2;
593 theIsInfinite1 = theIsInfinite2 = Standard_False;
595 BRepAdaptor_Curve aFirstAdaptor (theFirstEdge);
596 BRepAdaptor_Curve aSecondAdaptor (theSecondEdge);
598 theFirstCurve = Handle(Geom_Curve)::DownCast
599 (aFirstAdaptor.Curve().Curve()->Transformed (aFirstAdaptor.Trsf()));
600 theSecondCurve = Handle(Geom_Curve)::DownCast
601 (aSecondAdaptor.Curve().Curve()->Transformed (aSecondAdaptor.Trsf()));
603 if (theFirstCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
605 theFirstCurve = ((Handle(Geom_TrimmedCurve)&) theFirstCurve)->BasisCurve();
607 if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
609 theSecondCurve = ((Handle(Geom_TrimmedCurve)&) theSecondCurve)->BasisCurve();
612 aFirst1 = aFirstAdaptor.FirstParameter();
613 aLast1 = aFirstAdaptor.LastParameter();
615 aFirst2 = aSecondAdaptor.FirstParameter();
616 aLast2 = aSecondAdaptor.LastParameter();
618 if (theFirstCurve.IsNull() || theSecondCurve.IsNull())
620 return Standard_False;
623 Handle(Geom_Curve) aFirstSaved = theFirstCurve;
624 Handle(Geom_Curve) aSecondSaved = theSecondCurve;
626 // Checks that the projected curve is not in the plane
627 Standard_Boolean isFirstOnPlane,isSecondOnPlane;
629 if ((!ComputeGeomCurve (theFirstCurve, aFirst1, aLast1, theFirstPnt1, theLastPnt1, thePlane, isFirstOnPlane))
630 || (!ComputeGeomCurve( theSecondCurve, aFirst2, aLast2, theFirstPnt2, theLastPnt2, thePlane,isSecondOnPlane)))
632 return Standard_False;
635 if (Precision::IsInfinite (aFirst1) || Precision::IsInfinite (aLast1))
637 theIsInfinite1 = Standard_True;
640 if (Precision::IsInfinite (aFirst2) || Precision::IsInfinite (aLast2))
642 theIsInfinite2 = Standard_True;
645 if (theIsInfinite1 && theIsInfinite2)
650 if (theIsInfinite1 || theIsInfinite2)
652 if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType())
654 gp_Lin aLin1 = ((Handle(Geom_Line)&) theFirstCurve)->Lin();
655 gp_Lin aLin2 = ((Handle(Geom_Line)&) theSecondCurve)->Lin();
657 if (theExtIndex == 1)
659 theFirstPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theFirstPnt2), aLin1);
660 theLastPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theLastPnt2), aLin1);
662 else if (theExtIndex == 2)
664 theFirstPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theFirstPnt1), aLin2);
665 theLastPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theLastPnt1), aLin2);
670 if (isFirstOnPlane && isSecondOnPlane)
672 return Standard_True;
675 if (!isFirstOnPlane && isSecondOnPlane)
676 {// curve 2 only in the plane
678 theExtCurve = aFirstSaved;
680 else if (isFirstOnPlane && !isSecondOnPlane)
681 {// curve 1 only in the plane
683 theExtCurve = aSecondSaved;
687 return Standard_False;
690 return Standard_True;
693 //=======================================================================
694 //function : ComputeGeomCurve
695 //purpose : Checks if aCurve belongs to aPlane; if not, projects aCurve in aPlane
696 // and returns aCurveproj;
698 //=======================================================================
699 Standard_Boolean AIS::ComputeGeomCurve (Handle(Geom_Curve)& aCurve,
700 const Standard_Real first1,
701 const Standard_Real last1,
704 const Handle(Geom_Plane)& aPlane,
705 Standard_Boolean& isOnPlane)
707 isOnPlane = Standard_True;
708 const Standard_Integer NodeNumber = 20;
709 Standard_Real Delta = (last1 - first1) / (NodeNumber - 1);
710 if (Delta <= Precision::PConfusion())
712 Delta = last1 - first1;
715 gp_Pnt CurPnt(0.0, 0.0, 0.0);
716 Standard_Real CurPar = first1;
717 for (Standard_Integer i = 1; i <= NodeNumber; i++)
719 CurPnt = aCurve->Value( CurPar );
720 if (aPlane->Pln().SquareDistance( CurPnt ) > SquareTolerance)
722 isOnPlane = Standard_False;
728 if (!Precision::IsInfinite(first1) && !Precision::IsInfinite(last1))
730 FirstPnt1 = aCurve->Value (first1);
731 LastPnt1 = aCurve->Value (last1);
736 Handle(Geom_Curve) aGeomCurve = GeomProjLib::ProjectOnPlane (aCurve,
738 aPlane->Pln().Axis().Direction(),
741 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
743 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
745 if (! Precision::IsInfinite(first1) && ! Precision::IsInfinite(last1))
747 FirstPnt1 = AIS::ProjectPointOnPlane( FirstPnt1, aPlane->Pln() );
748 LastPnt1 = AIS::ProjectPointOnPlane( LastPnt1, aPlane->Pln() );
751 return Standard_True;
754 //=======================================================================
755 //function : ComputeGeometry
756 //purpose : computes the point corresponding to the vertex <aVertex>
757 // in the plane <aPlane>. If the vertex is already in the plane
758 // <isOnPlane>, <isOnPlane> = true.
759 // <point> is the projected vertex in the plane.
760 //=======================================================================
761 Standard_Boolean AIS::ComputeGeometry(const TopoDS_Vertex& aVertex,
763 const Handle(Geom_Plane)& aPlane,
764 Standard_Boolean& isOnPlane)
766 point = BRep_Tool::Pnt(aVertex);
767 isOnPlane = aPlane->Pln().Contains(point, Precision::Confusion());
769 point = AIS::ProjectPointOnPlane( point, aPlane->Pln() );
771 return Standard_True;
774 //=======================================================================
775 //function : GetPlaneFromFace
777 // Returns type of surface which can be Plane or OtherSurface
778 //=======================================================================
779 Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace,
781 Handle( Geom_Surface )& aSurf,
782 AIS_KindOfSurface & aSurfType,
783 Standard_Real & Offset)
786 Standard_Boolean Result = Standard_False;
787 BRepAdaptor_Surface surf1( aFace );
788 Handle( Adaptor3d_HSurface ) surf2;
789 Standard_Boolean isOffset = Standard_False;
791 if (surf1.GetType() == GeomAbs_OffsetSurface)
793 // Extracting Basis Surface
794 surf2 = surf1.BasisSurface();
795 isOffset = Standard_True;
798 surf2 = new BRepAdaptor_HSurface( surf1 );
800 aSurf = surf1.Surface().Surface();
801 // aSurf->Transform(surf1.Trsf()) ;
802 aSurf = Handle( Geom_Surface )::DownCast( aSurf->Transformed( surf1.Trsf() ) );
804 if (surf2->GetType() == GeomAbs_Plane)
806 aPlane = surf2->Plane();
807 aSurfType = AIS_KOS_Plane;
809 Result = Standard_True;
812 else if (surf2->GetType() == GeomAbs_SurfaceOfExtrusion)
814 Handle( Adaptor3d_HCurve ) BasisCurve = surf2->BasisCurve();
815 gp_Dir ExtrusionDir = surf2->Direction();
816 if (BasisCurve->GetType() == GeomAbs_Line)
818 gp_Lin BasisLine = BasisCurve->Line();
819 gp_Dir LineDir = BasisLine.Direction();
820 gp_Pnt LinePos = BasisLine.Location();
821 gp_Pln thePlane( LinePos, LineDir ^ ExtrusionDir);
823 aSurfType = AIS_KOS_Plane;
825 Result = Standard_True;
829 if (Result == Standard_True && isOffset)
831 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
832 aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln();
835 if (Result == Standard_False)
839 Handle( Standard_Type ) TheType = aSurf->DynamicType();
840 if (TheType == STANDARD_TYPE(Geom_CylindricalSurface) ||
841 TheType == STANDARD_TYPE(Geom_ConicalSurface) ||
842 TheType == STANDARD_TYPE(Geom_SphericalSurface) ||
843 TheType == STANDARD_TYPE(Geom_ToroidalSurface))
845 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
850 Offset = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Offset();
851 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->BasisSurface();
854 Handle( Standard_Type ) TheType = aSurf->DynamicType();
855 if (TheType == STANDARD_TYPE(Geom_CylindricalSurface))
856 aSurfType = AIS_KOS_Cylinder;
857 else if (TheType == STANDARD_TYPE(Geom_ConicalSurface))
858 aSurfType = AIS_KOS_Cone;
859 else if (TheType == STANDARD_TYPE(Geom_SphericalSurface))
860 aSurfType = AIS_KOS_Sphere;
861 else if (TheType == STANDARD_TYPE(Geom_ToroidalSurface))
862 aSurfType = AIS_KOS_Torus;
863 else if (TheType == STANDARD_TYPE(Geom_SurfaceOfRevolution))
864 aSurfType = AIS_KOS_Revolution;
865 else if (TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
866 aSurfType = AIS_KOS_Extrusion;
868 aSurfType = AIS_KOS_OtherSurface;
874 //=======================================================================
875 //function : ProjectPointOnPlane
877 //=======================================================================
879 gp_Pnt AIS::ProjectPointOnPlane( const gp_Pnt & aPoint, const gp_Pln & aPlane )
881 gp_Vec aVec( aPlane.Location(), aPoint );
882 gp_Vec Normal = aPlane.Axis().Direction();
883 Normal = (aVec * Normal) * Normal;
885 return ( aPoint.Translated( -Normal ) );
888 //=======================================================================
889 //function : ProjectPointOnLine
891 //=======================================================================
893 gp_Pnt AIS::ProjectPointOnLine( const gp_Pnt & aPoint, const gp_Lin & aLine )
895 gp_XYZ LinLoc = aLine.Location().XYZ();
896 gp_XYZ LinDir = aLine.Direction().XYZ();
897 Standard_Real Parameter = (aPoint.XYZ() - LinLoc) * LinDir;
898 gp_Pnt Result( LinLoc + Parameter * LinDir );
902 //=======================================================================
903 //function : InitFaceLength
905 //=======================================================================
906 void AIS::InitFaceLength (const TopoDS_Face& aFace,
908 Handle(Geom_Surface) & aSurface,
909 AIS_KindOfSurface & aSurfaceType,
910 Standard_Real & anOffset)
912 AIS::GetPlaneFromFace( aFace, aPlane, aSurface, aSurfaceType, anOffset );
914 if (Abs( anOffset ) > Precision::Confusion())
916 aSurface = new Geom_OffsetSurface( aSurface, anOffset );
922 //=======================================================================
923 //function : InitAngleBetweenPlanarFaces
925 //=======================================================================
926 Standard_Boolean AIS::InitAngleBetweenPlanarFaces (const TopoDS_Face& theFirstFace,
927 const TopoDS_Face& theSecondFace,
929 gp_Pnt & theFirstAttach,
930 gp_Pnt & theSecondAttach,
931 const Standard_Boolean theIsFirstPointSet)
933 Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (BRep_Tool::Surface (theFirstFace));
934 Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (BRep_Tool::Surface (theSecondFace));
936 GeomAPI_IntSS aPlaneIntersector (aFirstPlane, aSecondPlane, Precision::Confusion());
938 // Fails if two planes haven't only one intersection line.
939 if (!aPlaneIntersector.IsDone())
941 return Standard_False;
944 if (aPlaneIntersector.NbLines() != 1)
946 return Standard_False;
949 // Get intersect line.
950 Handle(Geom_Curve) anIntersectCurve = aPlaneIntersector.Line (1);
952 Handle(Geom_Line) anIntersectLine = Handle(Geom_Line)::DownCast (anIntersectCurve);
954 if (anIntersectLine.IsNull())
956 return Standard_False;
959 gp_Lin anIntersectLin = anIntersectLine->Lin();
961 gp_Pnt aFirstCenter, aSecondCenter;
962 Standard_Real anU1Min, anU1Max, aV1Min, aV1Max;
963 Standard_Real anU2Min, anU2Max, aV2Min, aV2Max;
965 BRepTools::UVBounds (theFirstFace, anU1Min, anU1Max, aV1Min, aV1Max);
966 BRepTools::UVBounds (theSecondFace, anU2Min, anU2Max, aV2Min, aV2Max);
968 // Get first and second attach.
969 if (theIsFirstPointSet)
971 GeomAPI_ProjectPointOnSurf aProjector (theFirstAttach, aFirstPlane);
972 if (!aProjector.IsDone())
974 return Standard_False;
977 aFirstCenter = aProjector.Point (1);
981 aFirstCenter = aFirstPlane->Value ((anU1Min + anU1Max) * 0.5, (aV1Min + aV1Max) * 0.5);
984 aSecondCenter = aSecondPlane->Value ((anU2Min + anU2Max) * 0.5, (aV2Min + aV2Max) * 0.5);
986 GeomAPI_ProjectPointOnCurve aProj (aFirstCenter, anIntersectCurve);
987 theCenter = aProj.NearestPoint();
989 gp_Vec aFirstNormal = anIntersectLin.Direction() ^ aFirstPlane->Pln().Axis().Direction();
990 if (aFirstNormal * gp_Vec (theCenter, aFirstCenter) < 0.0)
992 aFirstNormal.Reverse();
994 theFirstAttach = theCenter.Translated (aFirstNormal);
996 gp_Vec aSecondNormal = anIntersectLin.Direction() ^ aSecondPlane->Pln().Axis().Direction();
997 if (aSecondNormal * gp_Vec (theCenter, aSecondCenter) < 0.0)
999 aSecondNormal.Reverse();
1001 theSecondAttach = theCenter.Translated (aSecondNormal);
1003 return Standard_True;
1006 //=======================================================================
1007 //function : InitAngleBetweenCurvilinearFaces
1009 //=======================================================================
1010 Standard_Boolean AIS::InitAngleBetweenCurvilinearFaces (const TopoDS_Face& theFirstFace,
1011 const TopoDS_Face& theSecondFace,
1012 const AIS_KindOfSurface theFirstSurfType,
1013 const AIS_KindOfSurface theSecondSurfType,
1015 gp_Pnt& theFirstAttach,
1016 gp_Pnt& theSecondAttach,
1017 const Standard_Boolean theIsFirstPointSet)
1019 Handle(Geom_Surface) aFirstSurf = BRep_Tool::Surface (theFirstFace);
1020 Handle(Geom_Surface) aSecondSurf = BRep_Tool::Surface (theSecondFace);
1022 // Find intersection curve between two surfaces.
1023 GeomAPI_IntSS aSurfaceIntersector (aFirstSurf, aSecondSurf, Precision::Confusion());
1025 // Fails if two planes haven't only one intersection line.
1026 if (!aSurfaceIntersector.IsDone())
1028 return Standard_False;
1031 if (aSurfaceIntersector.NbLines() != 1)
1033 return Standard_False;
1036 // Get intersect line.
1037 Handle(Geom_Curve) anIntersectCurve = aSurfaceIntersector.Line (1);
1039 Handle(Geom_Line) aFirstLine, aSecondLine;
1040 Standard_Real aFirstU = 0.0;
1041 Standard_Real aFirstV = 0.0;
1043 if (theIsFirstPointSet)
1045 GeomAPI_ProjectPointOnSurf aProjector (theFirstAttach, aFirstSurf);
1046 if (!aProjector.IsDone())
1048 return Standard_False;
1051 theFirstAttach = aProjector.Point (1);
1055 theFirstAttach = aFirstSurf->Value (aFirstU, aFirstV);
1058 aFirstLine = Handle(Geom_Line)::DownCast (aFirstSurf->UIso (aFirstU));
1060 if (theSecondSurfType == AIS_KOS_Cylinder)
1062 Handle(Geom_CylindricalSurface) aCylinder = Handle(Geom_CylindricalSurface)::DownCast (aSecondSurf);
1064 Standard_Real aSecondU = aCylinder->Cylinder().XAxis().Direction().Angle(
1065 gce_MakeDir (ProjectPointOnLine (theFirstAttach,
1066 gp_Lin (aCylinder->Cylinder().Axis())),
1069 aSecondLine = Handle(Geom_Line)::DownCast (aCylinder->UIso (aSecondU));
1071 else if (theSecondSurfType == AIS_KOS_Cone)
1073 Handle(Geom_ConicalSurface) aCone = Handle(Geom_ConicalSurface)::DownCast (aSecondSurf);
1075 gp_Dir anXdirection = aCone->Cone().XAxis().Direction();
1077 gp_Dir aToFirstAttach = gce_MakeDir (ProjectPointOnLine (theFirstAttach,
1078 gp_Lin (aCone->Cone().Axis())),
1081 Standard_Real aSecondU = anXdirection.Angle (aToFirstAttach);
1084 if (!anXdirection.IsEqual (aToFirstAttach, Precision::Angular()) &&
1085 !anXdirection.IsOpposite (aToFirstAttach, Precision::Angular()) &&
1086 (anXdirection ^ aToFirstAttach) * aCone->Cone().Axis().Direction() < 0.0)
1088 aSecondU = 2*M_PI - aSecondU;
1090 aSecondLine = Handle( Geom_Line )::DownCast (aCone->UIso(aSecondU));
1094 return Standard_False;
1097 // If angle can be computed between two lines.
1098 if (!(aFirstLine->Lin().Direction().IsEqual (aSecondLine->Lin().Direction(), Precision::Angular() )) &&
1099 !(aFirstLine->Lin().Direction().IsOpposite (aSecondLine->Lin().Direction(), Precision::Angular())))
1101 GeomAPI_ExtremaCurveCurve anIntersector (aFirstLine, aSecondLine);
1102 anIntersector.Points (1, theCenter, theCenter);
1104 // Move theFirstAttach on aFirstLine if it is on theCenter.
1105 if (theCenter.SquareDistance(theFirstAttach ) <= SquareTolerance)
1107 gp_Vec aDir (aFirstLine->Lin().Direction());
1108 theFirstAttach = theCenter.Translated (aDir);
1110 // theFirstAttach should be on theFirstSurf.
1111 Standard_Real anU, aV;
1112 if (theFirstSurfType == AIS_KOS_Cylinder)
1114 ElSLib::Parameters ((Handle(Geom_CylindricalSurface)::DownCast (aFirstSurf))->Cylinder(),
1115 theFirstAttach, anU, aV);
1117 theFirstAttach = ElSLib::Value (aFirstU, aV,
1118 (Handle( Geom_CylindricalSurface )::DownCast (aFirstSurf))->Cylinder() );
1120 else if (theFirstSurfType == AIS_KOS_Cone)
1122 ElSLib::Parameters ((Handle(Geom_ConicalSurface)::DownCast (aFirstSurf))->Cone(),
1123 theFirstAttach, anU, aV);
1124 theFirstAttach = ElSLib::Value (aFirstU, aV,
1125 (Handle(Geom_ConicalSurface)::DownCast (aFirstSurf))->Cone());
1129 return Standard_False;
1133 // Find theSecondAttach
1134 GeomAPI_ProjectPointOnSurf aProjector (theFirstAttach, aSecondSurf);
1135 if (!aProjector.IsDone())
1137 return Standard_False;
1139 Quantity_Parameter anU, aV;
1140 aProjector.LowerDistanceParameters (anU, aV);
1141 theSecondAttach = aSecondSurf->Value (anU, aV);
1143 else // aFirstLine and aSecondLine are coincident
1145 gp_Vec aDir (aFirstLine->Lin().Direction());
1146 theFirstAttach = theCenter.Translated (aDir);
1147 theSecondAttach = theCenter.Translated (-aDir);
1149 return Standard_True;
1152 //=======================================================================
1153 //function : ComputeLengthBetweenCurvilinearFaces
1155 //=======================================================================
1156 void AIS::InitLengthBetweenCurvilinearFaces (const TopoDS_Face& theFirstFace,
1157 const TopoDS_Face& theSecondFace,
1158 Handle(Geom_Surface)& theFirstSurf,
1159 Handle(Geom_Surface)& theSecondSurf,
1160 gp_Pnt& theFirstAttach,
1161 gp_Pnt& theSecondAttach,
1162 gp_Dir& theDirOnPlane)
1164 GeomAPI_ProjectPointOnSurf aProjector;
1165 Quantity_Parameter aPU, aPV;
1167 TopExp_Explorer anExplorer (theFirstFace, TopAbs_VERTEX);
1169 theFirstAttach = BRep_Tool::Pnt (TopoDS::Vertex (anExplorer.Current()));
1170 aProjector.Init (theFirstAttach, theFirstSurf);
1172 theFirstAttach = aProjector.NearestPoint();
1173 aProjector.LowerDistanceParameters (aPU, aPV);
1176 theFirstSurf->D1 (aPU, aPV, theFirstAttach, aD1U, aD1V);
1178 if (aD1U.SquareMagnitude() <= SquareTolerance || aD1V.SquareMagnitude() <= SquareTolerance)
1180 theFirstAttach = AIS::Farest (theFirstFace, theFirstAttach);
1181 aProjector.Init (theFirstAttach, theFirstSurf);
1182 aProjector.LowerDistanceParameters (aPU, aPV);
1183 theFirstSurf->D1 (aPU, aPV, theFirstAttach, aD1U, aD1V);
1189 theDirOnPlane = gp_Dir (aD1U);
1191 gp_Dir aFirstSurfN = gp_Dir (aD1U ^ aD1V);
1193 aProjector.Init (theFirstAttach, theSecondSurf);
1195 Standard_Integer aBestPointIndex = 0;
1196 Quantity_Length aMinDist = RealLast();
1199 for (Standard_Integer aPointIt = 1; aPointIt <= aProjector.NbPoints(); aPointIt++)
1201 aProjector.Parameters (aPointIt, aPU, aPV);
1203 theSecondSurf->D1 (aPU, aPV, theSecondAttach, aD1U, aD1V);
1205 aLocalDir = aD1U.SquareMagnitude() <= SquareTolerance || aD1V.SquareMagnitude() <= SquareTolerance
1206 ? gp_Dir (gp_Vec (theFirstAttach, aProjector.Point (aPointIt)))
1207 : gp_Dir (aD1U ^ aD1V);
1209 if (aFirstSurfN.IsParallel (aLocalDir, Precision::Angular()) && aProjector.Distance (aPointIt) < aMinDist)
1211 aBestPointIndex = aPointIt;
1212 aMinDist = aProjector.Distance (aPointIt);
1216 if (aBestPointIndex == 0)
1218 theSecondAttach = theFirstAttach;
1222 theSecondAttach = aProjector.Point (aBestPointIndex);
1223 aProjector.Parameters (aBestPointIndex, aPU, aPV);
1225 // Now there is projection of FirstAttach onto SecondSurf in aProjector
1226 BRepTopAdaptor_FClass2d aClassifier (theSecondFace, Precision::Confusion());
1228 TopAbs_State aState =
1229 aClassifier.Perform (gp_Pnt2d (aPU, aPV), theSecondSurf->IsUPeriodic() || theSecondSurf->IsVPeriodic());
1231 if (aState == TopAbs_OUT || aState == TopAbs_UNKNOWN)
1233 theSecondAttach = AIS::Nearest (theSecondFace, theSecondAttach);
1238 gp_Pnt AIS::TranslatePointToBound( const gp_Pnt & aPoint, const gp_Dir & aDir, const Bnd_Box & aBndBox )
1240 if (aBndBox.IsOut( aPoint ))
1244 gp_Pnt Result(0.0,0.0,0.0);
1245 TColStd_Array2OfReal Bound( 1, 3, 1, 2 );
1246 TColStd_Array1OfReal Origin( 1, 3 );
1247 TColStd_Array1OfReal Dir( 1, 3 );
1250 aBndBox.Get( Bound(1,1), Bound(2,1), Bound(3,1), Bound(1,2), Bound(2,2), Bound(3,2) );
1251 aPoint.Coord( Origin(1), Origin(2), Origin(3) );
1252 aDir.Coord( Dir(1), Dir(2), Dir(3) );
1254 Bnd_Box EnlargedBox = aBndBox;
1255 EnlargedBox.Enlarge( aBndBox.GetGap() + Precision::Confusion() );
1257 Standard_Boolean IsFound = Standard_False;
1258 for (Standard_Integer i = 1; i <= 3; i++)
1260 if (Abs( Dir( i ) ) <= gp::Resolution())
1262 for (Standard_Integer j = 1; j <= 2; j++)
1264 t = (Bound( i, j ) - Origin( i )) / Dir( i );
1267 Result = aPoint.Translated( gp_Vec( aDir ) * t );
1268 if (! EnlargedBox.IsOut( Result ))
1270 IsFound = Standard_True;
1281 //=======================================================================
1282 //function : InDomain
1284 //=======================================================================
1286 Standard_Boolean AIS::InDomain(const Standard_Real fpar,
1287 const Standard_Real lpar,
1288 const Standard_Real para)
1292 return ((para >= fpar) && (para <= lpar));
1293 else { // fpar > lpar
1294 Standard_Real delta = 2*M_PI-fpar;
1295 Standard_Real lp, par, fp;
1298 while(lp > 2*M_PI) lp-=2*M_PI;
1299 while(par > 2*M_PI) par-=2*M_PI;
1301 return ((par >= fp) && (par <= lp));
1305 if (para >= (fpar+2*M_PI)) return Standard_True;
1306 if (para <= lpar) return Standard_True;
1307 return Standard_False;
1310 //=======================================================================
1311 //function : DistanceFromApex
1312 //purpose : calculates parametric length arc of ellipse
1313 //=======================================================================
1315 Standard_Real AIS::DistanceFromApex(const gp_Elips & elips,
1316 const gp_Pnt & Apex,
1317 const Standard_Real par)
1320 Standard_Real parApex = ElCLib::Parameter ( elips, Apex );
1321 if(parApex == 0.0 || parApex == M_PI)
1323 if(parApex == 0.0) //pos Apex
1324 dist = (par < M_PI) ? par : (2*M_PI - par);
1326 dist = (par < M_PI) ? ( M_PI - par) : ( par - M_PI );
1330 if(parApex == M_PI / 2) //pos Apex
1332 if(par <= parApex + M_PI && par > parApex) // 3/2*M_PI < par < M_PI/2
1333 dist = par - parApex;
1336 if(par > parApex + M_PI) // 3/2*M_PI < par < 2*M_PI
1337 dist = 2*M_PI - par + parApex;
1339 dist = parApex - par;
1342 else //neg Apex == 3/2*M_PI
1344 if(par <= parApex && par >= M_PI/2) // M_PI/2 < par < 3/2*M_PI
1345 dist = parApex - par;
1348 if(par > parApex) // 3/2*M_PI < par < 2*M_PI
1349 dist = par - parApex;
1351 dist = par + M_PI/2; // 0 < par < M_PI/2
1358 //=======================================================================
1359 //function : NearestApex
1361 //=======================================================================
1363 gp_Pnt AIS::NearestApex(const gp_Elips & elips,
1364 const gp_Pnt & pApex,
1365 const gp_Pnt & nApex,
1366 const Standard_Real fpara,
1367 const Standard_Real lpara,
1368 Standard_Boolean & IsInDomain)
1370 Standard_Real parP, parN;
1371 gp_Pnt EndOfArrow(0.0,0.0,0.0);
1372 IsInDomain = Standard_True;
1373 parP = ElCLib::Parameter ( elips, pApex );
1374 if(InDomain(fpara, lpara, parP)) EndOfArrow = pApex;
1377 parN = ElCLib::Parameter ( elips, nApex );
1378 if(InDomain(fpara, lpara, parN)) EndOfArrow = nApex;
1380 IsInDomain = Standard_False;
1381 Standard_Real posd = Min(DistanceFromApex (elips,pApex, fpara),
1382 DistanceFromApex (elips,pApex, lpara));
1383 Standard_Real negd = Min(DistanceFromApex (elips,nApex, fpara),
1384 DistanceFromApex (elips,nApex, lpara));
1394 //=======================================================================
1395 //function : ComputeProjEdgePresentation
1397 //=======================================================================
1399 void AIS::ComputeProjEdgePresentation( const Handle( Prs3d_Presentation )& aPresentation,
1400 const Handle( AIS_Drawer )& aDrawer,
1401 const TopoDS_Edge& anEdge,
1402 const Handle( Geom_Curve )& ProjCurve,
1403 const gp_Pnt& FirstP,
1404 const gp_Pnt& LastP,
1405 const Quantity_NameOfColor aColor,
1406 const Standard_Real aWidth,
1407 const Aspect_TypeOfLine aProjTOL,
1408 const Aspect_TypeOfLine aCallTOL )
1410 if (!aDrawer->HasWireAspect()){
1411 aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aProjTOL,2.));}
1414 // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect();
1415 Handle(Prs3d_LineAspect) li = aDrawer->WireAspect();
1417 li->SetColor(aColor);
1418 li->SetTypeOfLine(aProjTOL);
1419 li->SetWidth(aWidth);
1422 Standard_Real pf, pl;
1423 TopLoc_Location loc;
1424 Handle(Geom_Curve) curve;
1425 Standard_Boolean isInfinite;
1426 curve = BRep_Tool::Curve(anEdge,loc,pf,pl);
1427 isInfinite = (Precision::IsInfinite(pf) || Precision::IsInfinite(pl));
1431 // Calculate presentation of the edge
1432 if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
1434 // const Handle(Geom_Line) & gl = (Handle(Geom_Line)&) ProjCurve;
1435 Handle(Geom_Line) gl = (Handle(Geom_Line)&) ProjCurve;
1438 pf = ElCLib::Parameter(gl->Lin(),FirstP);
1439 pl = ElCLib::Parameter(gl->Lin(),LastP);
1440 BRepBuilderAPI_MakeEdge MakEd(gl->Lin(), pf, pl);
1444 BRepBuilderAPI_MakeEdge MakEd(gl->Lin());
1448 else if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
1450 // const Handle(Geom_Circle) & gc = (Handle(Geom_Circle)&) ProjCurve;
1451 Handle(Geom_Circle) gc = (Handle(Geom_Circle)&) ProjCurve;
1453 pf = ElCLib::Parameter(gc->Circ(),FirstP);
1454 pl = ElCLib::Parameter(gc->Circ(),LastP);
1455 BRepBuilderAPI_MakeEdge MakEd(gc->Circ(),pf, pl);
1458 StdPrs_WFDeflectionShape::Add(aPresentation, E, aDrawer);
1460 //Calculate the presentation of line connections
1461 aDrawer->WireAspect()->SetTypeOfLine(aCallTOL);
1463 gp_Pnt ppf(0.0,0.0,0.0), ppl(0.0,0.0,0.0);
1464 ppf = BRep_Tool::Pnt( TopExp::FirstVertex(TopoDS::Edge(anEdge)));
1465 ppl = BRep_Tool::Pnt( TopExp::LastVertex(TopoDS::Edge(anEdge)));
1468 if (FirstP.SquareDistance( ppf ) > SquareTolerance)
1470 BRepBuilderAPI_MakeEdge MakEd1(FirstP, ppf);
1471 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd1.Edge(), aDrawer);
1475 BRepBuilderAPI_MakeVertex MakVert1( FirstP );
1476 StdPrs_WFDeflectionShape::Add(aPresentation, MakVert1.Vertex(), aDrawer);
1478 if (LastP.SquareDistance( ppl ) > SquareTolerance)
1480 BRepBuilderAPI_MakeEdge MakEd2(LastP, ppl);
1481 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd2.Edge(), aDrawer);
1485 BRepBuilderAPI_MakeVertex MakVert2( LastP );
1486 StdPrs_WFDeflectionShape::Add(aPresentation, MakVert2.Vertex(), aDrawer);
1489 BRepBuilderAPI_MakeEdge MakEd1(FirstP, ppf);
1490 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd1.Edge(), aDrawer);
1491 BRepBuilderAPI_MakeEdge MakEd2(LastP, ppl);
1492 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd2.Edge(), aDrawer);
1497 //=======================================================================
1498 //function : ComputeProjVertexPresentation
1500 //=======================================================================
1502 void AIS::ComputeProjVertexPresentation( const Handle( Prs3d_Presentation )& aPresentation,
1503 const Handle( AIS_Drawer )& aDrawer,
1504 const TopoDS_Vertex& aVertex,
1505 const gp_Pnt& ProjPoint,
1506 const Quantity_NameOfColor aColor,
1507 const Standard_Real aWidth,
1508 const Aspect_TypeOfMarker aProjTOM,
1509 const Aspect_TypeOfLine aCallTOL )
1511 if (!aDrawer->HasPointAspect()){
1512 aDrawer->SetPointAspect(new Prs3d_PointAspect(aProjTOM, aColor,1));}
1515 // const Handle(Prs3d_PointAspect)& pa = aDrawer->PointAspect();
1516 Handle(Prs3d_PointAspect) pa = aDrawer->PointAspect();
1518 pa->SetColor(aColor);
1519 pa->SetTypeOfMarker(aProjTOM);
1522 // calculate the projection
1523 StdPrs_Point::Add(aPresentation, new Geom_CartesianPoint(ProjPoint), aDrawer);
1525 if (!aDrawer->HasWireAspect()){
1526 aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aCallTOL,2.));}
1529 // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect();
1530 Handle(Prs3d_LineAspect) li = aDrawer->WireAspect();
1532 li->SetColor(aColor);
1533 li->SetTypeOfLine(aCallTOL);
1534 li->SetWidth(aWidth);
1537 // If the points are not mixed...
1538 if (!ProjPoint.IsEqual (BRep_Tool::Pnt(aVertex),Precision::Confusion())) {
1539 // calculate the lines of recall
1540 BRepBuilderAPI_MakeEdge MakEd(ProjPoint,BRep_Tool::Pnt(aVertex));
1541 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd.Edge(), aDrawer);