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 <Bnd_Box.hxx>
40 #include <GccEnt_QualifiedLin.hxx>
41 #include <Geom2d_Circle.hxx>
42 #include <GeomAPI_ExtremaCurveCurve.hxx>
43 #include <GeomAPI_ProjectPointOnSurf.hxx>
44 #include <GeomLib.hxx>
45 #include <GeomProjLib.hxx>
46 #include <GeomProjLib.hxx>
47 #include <Geom_CartesianPoint.hxx>
48 #include <Geom_Circle.hxx>
49 #include <Geom_ConicalSurface.hxx>
50 #include <Geom_Curve.hxx>
51 #include <Geom_CylindricalSurface.hxx>
52 #include <Geom_Ellipse.hxx>
53 #include <Geom_Line.hxx>
54 #include <Geom_OffsetSurface.hxx>
55 #include <Geom_Plane.hxx>
56 #include <Geom_SphericalSurface.hxx>
57 #include <Geom_SurfaceOfLinearExtrusion.hxx>
58 #include <Geom_SurfaceOfRevolution.hxx>
59 #include <Geom_ToroidalSurface.hxx>
60 #include <Geom_TrimmedCurve.hxx>
61 #include <Precision.hxx>
62 #include <Prs3d_LineAspect.hxx>
63 #include <Prs3d_PointAspect.hxx>
64 #include <StdPrs_Point.hxx>
65 #include <StdPrs_WFDeflectionShape.hxx>
66 #include <TColStd_Array1OfReal.hxx>
67 #include <TColStd_Array2OfReal.hxx>
69 #include <TopExp_Explorer.hxx>
70 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
72 #include <gce_MakeLin.hxx>
76 #include <gp_Elips.hxx>
83 const Standard_Real SquareTolerance = Precision::SquareConfusion();
85 //=======================================================================
88 //=======================================================================
90 gp_Pnt AIS::Nearest(const TopoDS_Shape& ashape, const gp_Pnt& apoint)
92 Standard_Real dist2 = RealLast();
93 Standard_Real curdist2;
94 gp_Pnt result(0.0,0.0,0.0);
95 gp_Pnt curpnt(0.0,0.0,0.0);
96 TopExp_Explorer explo(ashape,TopAbs_VERTEX);
99 curpnt = BRep_Tool::Pnt(TopoDS::Vertex(explo.Current()));
100 curdist2 = apoint.SquareDistance(curpnt);
101 if (curdist2 < dist2)
111 //=======================================================================
114 //=======================================================================
116 gp_Pnt AIS::Farest( const TopoDS_Shape& aShape, const gp_Pnt& aPoint )
118 Standard_Real MaxDist2 = 0.0e0, curdist2;
119 gp_Pnt Result(0.0,0.0,0.0);
120 gp_Pnt curpnt(0.0,0.0,0.0);
121 TopExp_Explorer Explo( aShape, TopAbs_VERTEX );
122 for (; Explo.More(); Explo.Next())
124 curpnt = BRep_Tool::Pnt( TopoDS::Vertex( Explo.Current() ) );
125 curdist2 = aPoint.SquareDistance( curpnt );
126 if (curdist2 > MaxDist2)
136 //=======================================================================
137 //function : ComputeGeometry
138 //purpose : for line, circle, ellipse
139 //=======================================================================
141 Standard_Boolean AIS::ComputeGeometry(const TopoDS_Edge& anEdge,
142 Handle(Geom_Curve)& aCurve,
146 TopLoc_Location loc_edge;
147 Standard_Real first,last;
148 aCurve = BRep_Tool::Curve(anEdge,loc_edge,first,last);
149 if (aCurve.IsNull()) return Standard_False;
150 if (!loc_edge.IsIdentity()) {
152 Handle(Geom_Geometry) aGeomGeometry = aCurve->Transformed(loc_edge.Transformation());
153 aCurve = (Handle(Geom_Curve)&) aGeomGeometry ;
155 // aCurve = (Handle(Geom_Curve)&) aCurve->Transformed(loc_edge.Transformation());
158 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
159 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
162 if (aCurve->IsInstance(STANDARD_TYPE(Geom_Line))) {
164 // const Handle(Geom_Line)& line = (Handle(Geom_Line)&) aCurve;
165 Handle(Geom_Line) line = (Handle(Geom_Line)&) aCurve;
168 FirstPnt = ElCLib::Value(first,line->Lin());
169 LastPnt = ElCLib::Value(last,line->Lin());
171 else if (aCurve->IsInstance(STANDARD_TYPE(Geom_Circle))) {
173 // const Handle(Geom_Circle)& circ = (Handle(Geom_Circle)&) aCurve;
174 Handle(Geom_Circle) circ = (Handle(Geom_Circle)&) aCurve;
176 FirstPnt = ElCLib::Value(first,circ->Circ());
177 LastPnt = ElCLib::Value(last,circ->Circ());
179 else if (aCurve->IsInstance(STANDARD_TYPE(Geom_Ellipse))) {
181 // const Handle(Geom_Ellipse)& elips = (Handle(Geom_Ellipse)&) aCurve;
182 Handle(Geom_Ellipse) elips = (Handle(Geom_Ellipse)&) aCurve;
184 FirstPnt = ElCLib::Value(first, elips->Elips());
185 LastPnt = ElCLib::Value(last, elips->Elips());
187 else return Standard_False;
188 return Standard_True;
191 //=======================================================================
192 //function : ComputeGeometry
194 //=======================================================================
196 Standard_Boolean AIS::ComputeGeometry(const TopoDS_Edge& anEdge,
197 Handle(Geom_Curve)& aCurve,
200 Handle(Geom_Curve)& extCurve,
201 Standard_Boolean& isInfinite,
202 Standard_Boolean& isOnPlane,
203 const Handle(Geom_Plane)& aPlane)
205 if (aPlane.IsNull()) return Standard_False;
207 Standard_Real first,last;
208 BRepAdaptor_Curve brepCurv(anEdge);
209 aCurve = Handle(Geom_Curve)::DownCast(brepCurv.Curve().Curve()->Transformed(brepCurv.Trsf()));
210 first = brepCurv.FirstParameter();
211 last = brepCurv.LastParameter();
213 if (aCurve.IsNull()) return Standard_False;
216 isInfinite = (Precision::IsInfinite(first) || Precision::IsInfinite(last));
218 // Checks that the projcurve is not in the plane
219 isOnPlane = Standard_True;
220 if (extCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
221 extCurve = ((Handle(Geom_TrimmedCurve)&) extCurve)->BasisCurve();
224 if ( extCurve->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
226 // const Handle(Geom_Line) & gl = (Handle(Geom_Line)&) extCurve;
227 Handle(Geom_Line) gl = (Handle(Geom_Line)&) extCurve;
229 isOnPlane = aPlane->Pln().Contains( gl->Lin(), Precision::Confusion(), Precision::Angular() );
231 else if (extCurve->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
233 // const Handle(Geom_Circle) & gc = (Handle(Geom_Circle)&) extCurve;
234 Handle(Geom_Circle) gc = (Handle(Geom_Circle)&) extCurve;
236 gp_Ax3 ax(gc->Position());
237 isOnPlane = ax.IsCoplanar(aPlane->Pln().Position(),
238 Precision::Confusion(),
239 Precision::Angular());
246 Handle(Geom_Curve) aGeomCurve = GeomProjLib::ProjectOnPlane(aCurve,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
247 aCurve = aGeomCurve ;
249 // aCurve = (Handle(Geom_Curve)&) GeomProjLib::ProjectOnPlane(aCurve,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
252 if (aCurve->IsInstance(STANDARD_TYPE(Geom_Line))) {
254 // const Handle(Geom_Line)& line = (Handle(Geom_Line)&) aCurve;
255 Handle(Geom_Line) line = (Handle(Geom_Line)&) aCurve;
258 FirstPnt = ElCLib::Value(first,line->Lin());
259 LastPnt = ElCLib::Value(last,line->Lin());
262 else if (aCurve->IsInstance(STANDARD_TYPE(Geom_Circle))) {
264 // const Handle(Geom_Circle)& circ = (Handle(Geom_Circle)&) aCurve;
265 Handle(Geom_Circle) circ = (Handle(Geom_Circle)&) aCurve;
267 FirstPnt = ElCLib::Value(first,circ->Circ());
268 LastPnt = ElCLib::Value(last,circ->Circ());
271 else if (aCurve->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
273 Handle(Geom_Ellipse) ell = (Handle(Geom_Ellipse)&) aCurve;
274 FirstPnt = ElCLib::Value(first,ell->Elips());
275 LastPnt = ElCLib::Value(last,ell->Elips());
277 // jfa 10/10/2000 end
278 else return Standard_False;
279 return Standard_True;
282 //=======================================================================
283 //function : ComputeGeometry
285 //=======================================================================
287 Standard_Boolean AIS::ComputeGeometry(const TopoDS_Edge& anEdge1,
288 const TopoDS_Edge& anEdge2,
289 Handle(Geom_Curve)& aCurve1,
290 Handle(Geom_Curve)& aCurve2,
295 const Handle(Geom_Plane)& aPlane)
297 if (aPlane.IsNull()) return Standard_False;
299 TopLoc_Location loc_edge1,loc_edge2;
300 Standard_Real first1,last1,first2,last2;
302 aCurve1 = BRep_Tool::Curve(anEdge1,loc_edge1,first1,last1);
303 aCurve2 = BRep_Tool::Curve(anEdge2,loc_edge2,first2,last2);
305 if (aCurve1.IsNull()) return Standard_False;
306 if (aCurve2.IsNull()) return Standard_False;
308 if (!loc_edge1.IsIdentity()) {
310 Handle(Geom_Geometry) aGeomGeometry = aCurve1->Transformed(loc_edge1.Transformation());
311 aCurve1 = (Handle(Geom_Curve)&) aGeomGeometry ;
313 // aCurve1 = (Handle(Geom_Curve)&) aCurve1->Transformed(loc_edge1.Transformation());
316 if (!loc_edge2.IsIdentity()) {
318 Handle(Geom_Geometry) aGeomGeometry = aCurve2->Transformed(loc_edge2.Transformation());
319 aCurve2 = (Handle(Geom_Curve)&) aGeomGeometry ;
321 // aCurve2 = (Handle(Geom_Curve)&) aCurve2->Transformed(loc_edge2.Transformation());
326 Handle(Geom_Curve) aGeomCurve = GeomProjLib::ProjectOnPlane(aCurve1,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
327 aCurve1 = aGeomCurve ;
329 // aCurve1 = (Handle(Geom_Curve)&) GeomProjLib::ProjectOnPlane(aCurve1,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
332 aGeomCurve = GeomProjLib::ProjectOnPlane(aCurve2,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
333 aCurve2 = aGeomCurve;
335 // aCurve2 = (Handle(Geom_Curve)&) GeomProjLib::ProjectOnPlane(aCurve2,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
338 if (aCurve1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
339 aCurve1 = ((Handle(Geom_TrimmedCurve)&) aCurve1)->BasisCurve();
341 if (aCurve2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
342 aCurve2 = ((Handle(Geom_TrimmedCurve)&) aCurve2)->BasisCurve();
345 if (aCurve1->IsInstance(STANDARD_TYPE(Geom_Line))) {
347 // const Handle(Geom_Line)& line = (Handle(Geom_Line)&) aCurve1;
348 Handle(Geom_Line) line = (Handle(Geom_Line)&) aCurve1;
350 FirstPnt1 = ElCLib::Value(first1,line->Lin());
351 LastPnt1 = ElCLib::Value(last1,line->Lin());
353 else if (aCurve1->IsInstance(STANDARD_TYPE(Geom_Circle))) {
355 // const Handle(Geom_Circle)& circ = (Handle(Geom_Circle)&) aCurve1;
356 Handle(Geom_Circle) circ = (Handle(Geom_Circle)&) aCurve1;
358 FirstPnt1 = ElCLib::Value(first1,circ->Circ());
359 LastPnt1 = ElCLib::Value(last1,circ->Circ());
361 else return Standard_False;
363 if (aCurve2->IsInstance(STANDARD_TYPE(Geom_Line))) {
365 // const Handle(Geom_Line)& line = (Handle(Geom_Line)&) aCurve2;
366 Handle(Geom_Line) line = (Handle(Geom_Line)&) aCurve2;
368 FirstPnt2 = ElCLib::Value(first2,line->Lin());
369 LastPnt2 = ElCLib::Value(last2,line->Lin());
371 else if (aCurve2->IsInstance(STANDARD_TYPE(Geom_Circle))) {
373 // const Handle(Geom_Circle)& circ = (Handle(Geom_Circle)&) aCurve2;
374 Handle(Geom_Circle) circ = (Handle(Geom_Circle)&) aCurve2;
376 FirstPnt2 = ElCLib::Value(first2,circ->Circ());
377 LastPnt2 = ElCLib::Value(last2,circ->Circ());
379 else return Standard_False;
381 return Standard_True;
384 //=======================================================================
385 //function : ComputeGeometry
386 //purpose : Computes the geometry of the 2 edges in the current wp
387 // and the 'right' geometry of the edges if one doesn't
388 // belong to the current working plane.
389 // There may be only one curve that can't belong to the
390 // current working plane ( attachement constraint)
391 // if the 2 edges belong to the current WP, <WhatProj> = 0
393 // indexExt = 0 2 edges are in the current wp
394 // indexExt = 1 first edge is not in the current wp
395 // indexExt = 2 second edge is not in the current wp
396 // if none of the two edges is in the current wp ,
397 // it returns Standard_False
398 //=======================================================================
400 Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& anEdge1,
401 const TopoDS_Edge& anEdge2,
402 Standard_Integer& indexExt,
403 Handle(Geom_Curve)& aCurve1,
404 Handle(Geom_Curve)& aCurve2,
409 Handle(Geom_Curve)& extCurve,
410 Standard_Boolean& isInfinite1,
411 Standard_Boolean& isInfinite2,
412 const Handle(Geom_Plane)& aPlane)
414 if (aPlane.IsNull()) return Standard_False;
418 Standard_Real first1,last1,first2,last2;
419 isInfinite1 = isInfinite2 = Standard_False;
421 BRepAdaptor_Curve brepCurv1(anEdge1);
422 BRepAdaptor_Curve brepCurv2(anEdge2);
423 aCurve1 = Handle(Geom_Curve)::DownCast(brepCurv1.Curve().Curve()->Transformed(brepCurv1.Trsf()));
424 aCurve2 = Handle(Geom_Curve)::DownCast(brepCurv2.Curve().Curve()->Transformed(brepCurv2.Trsf()));
425 if (aCurve1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
426 aCurve1 = ((Handle(Geom_TrimmedCurve)&) aCurve1)->BasisCurve();
428 if (aCurve2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
429 aCurve2 = ((Handle(Geom_TrimmedCurve)&) aCurve2)->BasisCurve();
432 first1 = brepCurv1.FirstParameter();
433 last1 = brepCurv1.LastParameter();
434 first2 = brepCurv2.FirstParameter();
435 last2 = brepCurv2.LastParameter();
437 if (aCurve1.IsNull()) return Standard_False;
438 if (aCurve2.IsNull()) return Standard_False;
440 Handle(Geom_Curve) aSov1 = aCurve1;
441 Handle(Geom_Curve) aSov2 = aCurve2;
443 // Checks that the projcurve is not in the plane
444 Standard_Boolean isOnPlanC1,isOnPlanC2;
445 if ((!ComputeGeomCurve(aCurve1,first1,last1,FirstPnt1,LastPnt1,aPlane,isOnPlanC1))
446 || (!ComputeGeomCurve(aCurve2,first2,last2,FirstPnt2,LastPnt2,aPlane,isOnPlanC2)))
447 return Standard_False;
449 if (Precision::IsInfinite(first1) || Precision::IsInfinite(last1)) {
450 isInfinite1 = Standard_True;
453 if (Precision::IsInfinite(first2) || Precision::IsInfinite(last2)) {
454 isInfinite2 = Standard_True;
457 if (isInfinite1 && isInfinite2) indexExt = 0; //New
459 if (isInfinite1 || isInfinite2) {
460 if (aCurve1->DynamicType() == aCurve2->DynamicType()) {
462 // const gp_Lin& lin1 = ((Handle(Geom_Line)&) aCurve1)->Lin();
463 // const gp_Lin& lin2 = ((Handle(Geom_Line)&) aCurve2)->Lin();
464 gp_Lin lin1 = ((Handle(Geom_Line)&) aCurve1)->Lin();
465 gp_Lin lin2 = ((Handle(Geom_Line)&) aCurve2)->Lin();
468 FirstPnt1 = ElCLib::Value(ElCLib::Parameter(lin2,FirstPnt2),lin1);
469 LastPnt1 = ElCLib::Value(ElCLib::Parameter(lin2,LastPnt2),lin1);
471 else if (indexExt == 2) {
472 FirstPnt2 = ElCLib::Value(ElCLib::Parameter(lin1,FirstPnt1),lin2);
473 LastPnt2 = ElCLib::Value(ElCLib::Parameter(lin1,LastPnt1),lin2);
478 if (isOnPlanC1 && isOnPlanC2) return Standard_True;
480 if (!isOnPlanC1 && isOnPlanC2) {// curve 2 only in the plane
484 else if (isOnPlanC1 && !isOnPlanC2) {// curve 1 only in the plane
489 return Standard_False;
491 return Standard_True;
497 //=======================================================================
498 //function : ComputeGeomCurve
499 //purpose : Checks if aCurve belongs to aPlane; if not, projects aCurve in aPlane
500 // and returns aCurveproj;
502 //=======================================================================
504 Standard_Boolean AIS::ComputeGeomCurve(Handle(Geom_Curve)& aCurve,
505 const Standard_Real first1,
506 const Standard_Real last1,
509 const Handle(Geom_Plane)& aPlane,
510 Standard_Boolean& isOnPlane)
512 isOnPlane = Standard_True;
514 const Standard_Integer NodeNumber = 20;
515 Standard_Real Delta = (last1 - first1) / (NodeNumber - 1);
516 if (Delta <= Precision::PConfusion())
517 Delta = last1 - first1;
518 gp_Pnt CurPnt(0.0,0.0,0.0);
519 Standard_Real CurPar = first1;
520 for (Standard_Integer i = 1; i <= NodeNumber; i++)
522 CurPnt = aCurve->Value( CurPar );
523 if (aPlane->Pln().SquareDistance( CurPnt ) > SquareTolerance)
525 isOnPlane = Standard_False;
531 if (! Precision::IsInfinite(first1) && ! Precision::IsInfinite(last1))
533 FirstPnt1 = aCurve->Value( first1 );
534 LastPnt1 = aCurve->Value( last1 );
538 Handle( Geom_Curve ) aGeomCurve = GeomProjLib::ProjectOnPlane( aCurve,
540 aPlane->Pln().Axis().Direction(),
542 aCurve = aGeomCurve ;
544 // aCurve = (Handle( Geom_Curve )&) GeomProjLib::ProjectOnPlane( aCurve,
546 // aPlane->Pln().Axis().Direction(),
549 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
550 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
552 if (! Precision::IsInfinite(first1) && ! Precision::IsInfinite(last1)) {
553 FirstPnt1 = AIS::ProjectPointOnPlane( FirstPnt1, aPlane->Pln() );
554 LastPnt1 = AIS::ProjectPointOnPlane( LastPnt1, aPlane->Pln() );
557 return Standard_True;
561 //=======================================================================
562 //function : ComputeGeometry
563 //purpose : computes the point corresponding to the vertex <aVertex>
564 // in the plane <aPlane>. If the vertex is already in the plane
565 // <isOnPlane>, <isOnPlane> = true.
566 // <point> is the projected vertex in the plane.
567 //=======================================================================
569 Standard_Boolean AIS::ComputeGeometry(const TopoDS_Vertex& aVertex,
571 const Handle(Geom_Plane)& aPlane,
572 Standard_Boolean& isOnPlane)
574 point = BRep_Tool::Pnt(aVertex);
575 isOnPlane = aPlane->Pln().Contains(point, Precision::Confusion());
577 point = AIS::ProjectPointOnPlane( point, aPlane->Pln() );
579 return Standard_True;
582 //=======================================================================
583 //function : GetPlaneFromFace
585 // Returns type of surface which can be Plane or OtherSurface
586 //=======================================================================
588 Standard_Boolean AIS::GetPlaneFromFace( const TopoDS_Face& aFace,
590 Handle( Geom_Surface )& aSurf,
591 AIS_KindOfSurface & aSurfType,
592 Standard_Real & Offset )
595 Standard_Boolean Result = Standard_False;
596 BRepAdaptor_Surface surf1( aFace );
597 Handle( Adaptor3d_HSurface ) surf2;
598 //gp_Vec OffsetVec( 1.0e0, 0.0e0, 0.0e0 );
599 Standard_Boolean isOffset = Standard_False;
601 if (surf1.GetType() == GeomAbs_OffsetSurface)
603 // Extracting Basis Surface
604 surf2 = surf1.BasisSurface();
605 isOffset = Standard_True;
608 surf2 = new BRepAdaptor_HSurface( surf1 );
610 aSurf = surf1.Surface().Surface();
611 // aSurf->Transform(surf1.Trsf()) ;
612 aSurf = Handle( Geom_Surface )::DownCast( aSurf->Transformed( surf1.Trsf() ) );
614 if (surf2->GetType() == GeomAbs_Plane)
616 aPlane = surf2->Plane();
617 aSurfType = AIS_KOS_Plane;
619 Result = Standard_True;
622 else if (surf2->GetType() == GeomAbs_SurfaceOfExtrusion)
624 Handle( Adaptor3d_HCurve ) BasisCurve = surf2->BasisCurve();
625 gp_Dir ExtrusionDir = surf2->Direction();
626 if (BasisCurve->GetType() == GeomAbs_Line)
628 gp_Lin BasisLine = BasisCurve->Line();
629 gp_Dir LineDir = BasisLine.Direction();
630 gp_Pnt LinePos = BasisLine.Location();
631 gp_Pln thePlane( LinePos, LineDir ^ ExtrusionDir);
633 aSurfType = AIS_KOS_Plane;
635 Result = Standard_True;
639 if (Result == Standard_True && isOffset)
641 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
642 aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln();
644 Handle( Geom_OffsetSurface ) OffsetSurf = Handle( Geom_OffsetSurface )::DownCast( aSurf );
647 OffsetSurf->D1( 0, 0, PointOnPlane, D1u, D1v );
650 OffsetVec = D1u ^ D1v;
651 aPlane.Translate( OffsetValue * OffsetVec );
655 if (Result == Standard_False)
659 Handle( Standard_Type ) TheType = aSurf->DynamicType();
660 if (TheType == STANDARD_TYPE(Geom_CylindricalSurface) ||
661 TheType == STANDARD_TYPE(Geom_ConicalSurface) ||
662 TheType == STANDARD_TYPE(Geom_SphericalSurface) ||
663 TheType == STANDARD_TYPE(Geom_ToroidalSurface))
665 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
670 Offset = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Offset();
671 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->BasisSurface();
674 Handle( Standard_Type ) TheType = aSurf->DynamicType();
675 if (TheType == STANDARD_TYPE(Geom_CylindricalSurface))
676 aSurfType = AIS_KOS_Cylinder;
677 else if (TheType == STANDARD_TYPE(Geom_ConicalSurface))
678 aSurfType = AIS_KOS_Cone;
679 else if (TheType == STANDARD_TYPE(Geom_SphericalSurface))
680 aSurfType = AIS_KOS_Sphere;
681 else if (TheType == STANDARD_TYPE(Geom_ToroidalSurface))
682 aSurfType = AIS_KOS_Torus;
683 else if (TheType == STANDARD_TYPE(Geom_SurfaceOfRevolution))
684 aSurfType = AIS_KOS_Revolution;
685 else if (TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
686 aSurfType = AIS_KOS_Extrusion;
688 aSurfType = AIS_KOS_OtherSurface;
694 //=======================================================================
695 //function : ProjectPointOnPlane
697 //=======================================================================
699 gp_Pnt AIS::ProjectPointOnPlane( const gp_Pnt & aPoint, const gp_Pln & aPlane )
701 gp_Vec aVec( aPlane.Location(), aPoint );
702 gp_Vec Normal = aPlane.Axis().Direction();
703 Normal = (aVec * Normal) * Normal;
705 return ( aPoint.Translated( -Normal ) );
708 //=======================================================================
709 //function : ProjectPointOnLine
711 //=======================================================================
713 gp_Pnt AIS::ProjectPointOnLine( const gp_Pnt & aPoint, const gp_Lin & aLine )
715 gp_XYZ LinLoc = aLine.Location().XYZ();
716 gp_XYZ LinDir = aLine.Direction().XYZ();
717 Standard_Real Parameter = (aPoint.XYZ() - LinLoc) * LinDir;
718 gp_Pnt Result( LinLoc + Parameter * LinDir );
723 //=======================================================================
724 //function : InitFaceLength
726 //=======================================================================
728 void AIS::InitFaceLength( const TopoDS_Face& aFace,
730 Handle(Geom_Surface) & aSurface,
731 AIS_KindOfSurface & aSurfaceType,
732 Standard_Real & anOffset)
734 AIS::GetPlaneFromFace( aFace, aPlane, aSurface, aSurfaceType, anOffset );
736 if (Abs( anOffset ) > Precision::Confusion())
738 aSurface = new Geom_OffsetSurface( aSurface, anOffset );
744 //=======================================================================
745 //function : ComputeLengthBetweenPlanarFaces
747 //=======================================================================
749 void AIS::ComputeLengthBetweenPlanarFaces( const TopoDS_Face & FirstFace,
750 const TopoDS_Face & SecondFace,
751 const gp_Pln & Plane1,
752 const gp_Pln & Plane2,
753 Standard_Real & Value,
754 gp_Pnt & FirstAttach,
755 gp_Pnt & SecondAttach,
757 const Standard_Boolean AutomaticPos,
760 TopExp_Explorer aExp( FirstFace, TopAbs_VERTEX );
761 // case of infinite planes. SMO.
763 FirstAttach = Plane1.Location();
765 FirstAttach = BRep_Tool::Pnt( TopoDS::Vertex( aExp.Current() ) );
766 SecondAttach = AIS::ProjectPointOnPlane( FirstAttach, Plane2 );
768 Value = FirstAttach.Distance( SecondAttach );
770 gp_Dir LengthDir = Plane1.Axis().Direction();
772 if (Value > Precision::Confusion())
773 LengthDir = gp_Dir( gp_Vec( FirstAttach, SecondAttach ) );
775 DirAttach = Plane1.Position().XDirection();
778 Position.SetXYZ((FirstAttach.XYZ() + SecondAttach.XYZ())/2.0e0) ;
780 else // position is given
782 FirstAttach = AIS::Nearest( FirstFace, Position );
783 SecondAttach = AIS::ProjectPointOnPlane( FirstAttach, Plane2 );
786 Quantity_Parameter U, V ;
787 ElSLib::Parameters( Plane2, SecondAttach, U, V );
788 BRepTopAdaptor_FClass2d aClassifier( SecondFace, Precision::Confusion() );
789 TopAbs_State State = aClassifier.Perform( gp_Pnt2d( U, V ), Standard_False );
790 if (State == TopAbs_OUT || State == TopAbs_UNKNOWN)
792 SecondAttach = AIS::Nearest( SecondFace, Position );
793 if (Value > Precision::Confusion())
795 gp_Vec aVector = gp_Vec( FirstAttach, SecondAttach ) ^ LengthDir;
796 if (aVector.SquareMagnitude() > SquareTolerance)
797 DirAttach = aVector ^ LengthDir;
801 gp_Vec DirVec( FirstAttach, SecondAttach );
802 if (DirVec.SquareMagnitude() > SquareTolerance)
803 DirAttach = gp_Dir( DirVec );
808 gp_Pln PlaneOfDim( FirstAttach, DirAttach ^ LengthDir );
809 Position = AIS::ProjectPointOnPlane( Position, PlaneOfDim );
814 // Purpose: Return the point from <aFace> wich is the more distant
816 static gp_Pnt FindFarPoint (const gp_Ax1 & anAxis,
817 const TopoDS_Face & aFace )
819 gp_Pnt ResPnt(0.0,0.0,0.0);
820 Standard_Real MaxDist = 0.e0, curdist2;
822 gp_Lin Line (anAxis);
824 TopExp_Explorer Explo (aFace, TopAbs_VERTEX);
827 // Case of infinite planes (no Vertex, no edge)
829 Handle( Geom_Surface ) aSurf;
830 AIS_KindOfSurface KOS;
831 Standard_Real offset;
832 AIS::GetPlaneFromFace (aFace,plane,aSurf,KOS,offset );
833 gp_Pnt aPoint = plane.Location();
834 MaxDist = Line.SquareDistance (aPoint);
835 if (MaxDist <= SquareTolerance) {
837 gp_Dir DMove = plane.Axis().Direction()^anAxis.Direction();
838 gp_Vec VMove (DMove.XYZ()*100);
839 ResPnt = aPoint.Translated (VMove);
843 for (; Explo.More(); Explo.Next())
846 // const TopoDS_Vertex & aVertex = TopoDS::Vertex( Explo.Current() );
847 TopoDS_Vertex aVertex = TopoDS::Vertex( Explo.Current() );
849 gp_Pnt aPoint = BRep_Tool::Pnt( aVertex );
850 curdist2 = Line.SquareDistance( aPoint );
851 if (curdist2 > MaxDist)
858 if (MaxDist <= SquareTolerance)
860 const Standard_Integer NodeNumber = 20;
861 Explo.Init( aFace, TopAbs_EDGE );
862 for (; Explo.More(); Explo.Next())
865 // const TopoDS_Edge & anEdge = TopoDS::Edge( Explo.Current() );
866 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
868 BRepAdaptor_Curve aCurve( anEdge );
869 Standard_Real FirstPar = aCurve.FirstParameter();
870 Standard_Real LastPar = aCurve.LastParameter();
871 Standard_Real Delta = (LastPar - FirstPar) / (NodeNumber - 1);
872 for (Standard_Integer i = 0; i < NodeNumber; i++)
874 gp_Pnt aPoint(0.0,0.0,0.0);
875 aCurve.D0( FirstPar, aPoint );
876 curdist2 = Line.SquareDistance( aPoint );
877 if (curdist2 > MaxDist)
884 if (MaxDist > SquareTolerance) break;
887 if (MaxDist <= SquareTolerance)
888 Standard_ConstructionError::Raise("AIS:: problem attach point") ;
892 void AIS::ComputeAngleBetweenPlanarFaces( const TopoDS_Face & FirstFace,
893 const TopoDS_Face & SecondFace,
894 const Handle( Geom_Surface )& Surf2,
896 const Standard_Real Value,
897 const Standard_Boolean AutomaticPos,
900 gp_Pnt & FirstAttach,
901 gp_Pnt & SecondAttach,
905 FirstAttach = FindFarPoint( Axis, FirstFace );
906 Center = AIS::ProjectPointOnLine( FirstAttach, gp_Lin( Axis ) );
907 gp_Dir aDir1( gp_Vec( Center, FirstAttach ) );
909 SecondAttach = FirstAttach.Rotated( Axis, Value );
910 gp_Dir aDir2( gp_Vec( Center, SecondAttach ) );
913 GeomAPI_ProjectPointOnSurf aProjPnt( SecondAttach,
915 //SecondAttach = aProjPnt.Point(1) ;
916 Quantity_Parameter U,V ;
917 aProjPnt.Parameters(1,U,V) ;
918 BRepTopAdaptor_FClass2d aClassifier(SecondFace,
919 Precision::Confusion());
920 if (aClassifier.Perform(gp_Pnt2d(U,V),Standard_False) == TopAbs_OUT ||
921 aClassifier.Perform(gp_Pnt2d(U,V),Standard_False) == TopAbs_UNKNOWN)
922 SecondAttach = FindFarPoint( Axis, SecondFace );
925 Position = FirstAttach.Rotated( Axis, Value*0.5 );
928 gp_Pln PlaneOfDim( Center, Axis.Direction() );
929 Position = AIS::ProjectPointOnPlane( Position, PlaneOfDim );
934 void AIS::ComputeAngleBetweenCurvilinearFaces( const TopoDS_Face & FirstFace,
935 const TopoDS_Face & SecondFace,
936 const Handle( Geom_Surface )& FirstSurf,
937 const Handle( Geom_Surface )& SecondSurf,
938 const AIS_KindOfSurface FirstSurfType,
939 const AIS_KindOfSurface SecondSurfType,
941 const Standard_Real Value,
942 const Standard_Boolean AutomaticPos,
945 gp_Pnt & FirstAttach,
946 gp_Pnt & SecondAttach,
949 Handle( Geom_Plane ) & Plane )
952 // even if it is not AutomaticPosition do not assume the Automatic
953 // case has saved the values in the AIS_AngleDimension class : this
954 // is not always the case
956 gp_Pnt SavedPosition = Position ;
957 FirstAttach = FindFarPoint( Axis, FirstFace );
958 Plane = new Geom_Plane( Axis.Location(),
959 gp_Dir( gp_Vec( Axis.Location(), FirstAttach ) ^
960 gp_Vec( Axis.Direction() ) ) );
962 Handle( Geom_Line ) FirstLine, SecondLine;
963 Standard_Real FirstU, FirstV;
964 if (FirstSurfType == AIS_KOS_Cylinder)
965 ElSLib::Parameters( Handle( Geom_CylindricalSurface )::DownCast( FirstSurf )->Cylinder(),
969 ElSLib::Parameters( Handle( Geom_ConicalSurface )::DownCast( FirstSurf )->Cone(),
972 FirstLine = Handle( Geom_Line )::DownCast( FirstSurf->UIso( FirstU ) );
974 if (SecondSurfType == AIS_KOS_Cylinder)
976 Handle( Geom_CylindricalSurface ) Cylinder2 =
977 Handle( Geom_CylindricalSurface )::DownCast( SecondSurf );
978 Standard_Real SecondU = Cylinder2->Cylinder().XAxis().Direction().Angle(
979 gp_Dir( gp_Vec( ProjectPointOnLine( FirstAttach, gp_Lin( Cylinder2->Cylinder().Axis() ) ),
982 SecondLine = Handle( Geom_Line )::DownCast( Cylinder2->UIso( SecondU ) );
987 Handle( Geom_ConicalSurface ) Cone2 = Handle( Geom_ConicalSurface )::DownCast( SecondSurf );
988 gp_Dir Xdirection = Cone2->Cone().XAxis().Direction() ;
989 gp_Dir ToFirstAttach = gp_Dir( gp_Vec(
990 ProjectPointOnLine( FirstAttach, gp_Lin( Cone2->Cone().Axis() )),
993 Standard_Real SecondU = Xdirection.Angle( ToFirstAttach );
995 if (! Xdirection.IsEqual( ToFirstAttach, Precision::Angular() ) &&
996 ! Xdirection.IsOpposite( ToFirstAttach, Precision::Angular() ) &&
997 (Xdirection ^ ToFirstAttach) * Cone2->Cone().Axis().Direction() < 0.0e0)
998 SecondU = 2*M_PI - SecondU ;
1000 SecondLine = Handle( Geom_Line )::DownCast( Cone2->UIso( SecondU ) );
1003 if (! (FirstLine->Lin().Direction().IsEqual( SecondLine->Lin().Direction(), Precision::Angular() )) &&
1004 ! (FirstLine->Lin().Direction().IsOpposite( SecondLine->Lin().Direction(), Precision::Angular() )))
1006 GeomAPI_ExtremaCurveCurve Intersection( FirstLine, SecondLine );
1007 Intersection.Points( 1, Center, Center );
1009 if (Center.SquareDistance( FirstAttach ) <= SquareTolerance)
1011 FirstAttach = AIS::Farest( FirstFace, Center );
1013 if (FirstSurfType == AIS_KOS_Cylinder)
1015 ElSLib::Parameters ( (Handle( Geom_CylindricalSurface )::DownCast( FirstSurf ))->Cylinder(),
1018 FirstAttach = ElSLib::Value( FirstU, V,
1019 (Handle( Geom_CylindricalSurface )::DownCast( FirstSurf ))
1024 ElSLib::Parameters ( (Handle( Geom_ConicalSurface )::DownCast( FirstSurf ))->Cone(),
1027 FirstAttach = ElSLib::Value( FirstU, V,
1028 (Handle( Geom_ConicalSurface )::DownCast( FirstSurf ))
1032 gp_Vec FirstVec( Center, FirstAttach );
1033 FirstDir = gp_Dir( FirstVec );
1035 gp_Ax1 AxisOfRotation( Center, Plane->Pln().Axis().Direction() );
1036 SecondAttach = FirstAttach.Rotated( AxisOfRotation, Value );
1037 if (! SecondLine->Lin().Contains( SecondAttach, Precision::Confusion() ))
1039 AxisOfRotation.Reverse();
1040 SecondAttach = FirstAttach.Rotated( AxisOfRotation, Value );
1043 Position = FirstAttach.Rotated( AxisOfRotation, Value/2 );
1045 gp_Vec SecondVec( Center, SecondAttach );
1046 SecondDir = gp_Dir( SecondVec );
1049 else // FirstLine and SecondLine are coincident
1051 Position = SecondAttach = FirstAttach;
1052 FirstDir = FirstLine->Lin().Direction();
1053 SecondDir = FirstDir;
1054 Center = Position.Translated( gp_Vec( -FirstDir ) );
1055 //Position.Translate( gp_Vec( FirstDir ) );
1058 GeomAPI_ProjectPointOnSurf aProjPnt( SecondAttach, SecondSurf ) ;
1059 Quantity_Parameter U, V;
1060 aProjPnt.LowerDistanceParameters( U, V ) ;
1061 BRepTopAdaptor_FClass2d aClassifier2( SecondFace, Precision::Confusion());
1062 TopAbs_State State = aClassifier2.Perform( gp_Pnt2d( U, V ), Standard_True );
1063 if (State == TopAbs_OUT || State == TopAbs_UNKNOWN)
1065 Standard_Real MinDist2 = RealLast();
1066 Standard_Real curdist2;
1067 gp_Pnt curpnt(0.0,0.0,0.0);
1068 gp_Pnt Result(0.0,0.0,0.0);
1069 TopExp_Explorer Explo( SecondFace, TopAbs_VERTEX );
1070 for (; Explo.More(); Explo.Next())
1072 curpnt = BRep_Tool::Pnt( TopoDS::Vertex( Explo.Current() ) );
1073 curdist2 = SecondAttach.SquareDistance( curpnt ) ;
1074 if (curpnt.SquareDistance( Center ) > SquareTolerance && curdist2 < MinDist2)
1077 MinDist2 = curdist2;
1080 SecondAttach = Result;
1084 { // protection in case this is created using the manual position
1087 Position = AIS::ProjectPointOnPlane( SavedPosition, Plane->Pln() );
1092 void AIS::ComputeLengthBetweenCurvilinearFaces( const TopoDS_Face & FirstFace,
1093 const TopoDS_Face & SecondFace,
1094 Handle( Geom_Surface )& FirstSurf,
1095 Handle( Geom_Surface )& SecondSurf,
1096 const Standard_Boolean AutomaticPos,
1097 Standard_Real & Value,
1099 gp_Pnt & FirstAttach,
1100 gp_Pnt & SecondAttach,
1101 gp_Dir & DirAttach )
1103 GeomAPI_ProjectPointOnSurf aProjector;
1104 Quantity_Parameter U, V;
1105 TopAbs_State State = TopAbs_UNKNOWN;
1108 TopExp_Explorer Explo( FirstFace, TopAbs_VERTEX );
1109 FirstAttach = BRep_Tool::Pnt( TopoDS::Vertex( Explo.Current() ) );
1110 aProjector.Init(FirstAttach , FirstSurf );
1111 FirstAttach = aProjector.NearestPoint();
1112 aProjector.LowerDistanceParameters( U, V );
1114 else // posiiton is given
1116 aProjector.Init( Position, FirstSurf );
1117 FirstAttach = aProjector.NearestPoint();
1119 aProjector.LowerDistanceParameters( U, V );
1120 BRepTopAdaptor_FClass2d aClassifier( FirstFace, Precision::Confusion() );
1121 State = aClassifier.Perform( gp_Pnt2d( U, V ), ( (FirstSurf->IsUPeriodic() || FirstSurf->IsVPeriodic())?
1123 : Standard_False ) );
1124 if (State == TopAbs_OUT || State == TopAbs_UNKNOWN)
1126 FirstAttach = AIS::Nearest( FirstFace, Position );
1127 aProjector.Init( FirstAttach, FirstSurf );
1128 aProjector.LowerDistanceParameters( U, V );
1133 FirstSurf->D1( U, V, FirstAttach, D1U, D1V );
1134 if (D1U.SquareMagnitude() <= SquareTolerance || D1V.SquareMagnitude() <= SquareTolerance)
1136 FirstAttach = AIS::Farest( FirstFace, FirstAttach );
1137 aProjector.Init( FirstAttach, FirstSurf );
1138 aProjector.LowerDistanceParameters( U, V );
1139 FirstSurf->D1( U, V, FirstAttach, D1U, D1V );
1143 DirAttach = gp_Dir( D1U ^ D1V );
1145 aProjector.Init( FirstAttach, SecondSurf );
1146 Standard_Integer Index = 0;
1147 Quantity_Length MinDist = RealLast();
1149 for (Standard_Integer i = 1; i <= aProjector.NbPoints(); i++)
1151 aProjector.Parameters( i, U, V );
1153 SecondSurf->D1( U, V, SecondAttach, D1U, D1V );
1154 if (D1U.SquareMagnitude() <= SquareTolerance || D1V.SquareMagnitude() <= SquareTolerance)
1155 LocalDir = gp_Dir( gp_Vec( FirstAttach, aProjector.Point( i ) ) );
1157 LocalDir = gp_Dir( D1U ^ D1V );
1158 if (DirAttach.IsParallel( LocalDir, Precision::Angular() ) && aProjector.Distance( i ) < MinDist)
1161 MinDist = aProjector.Distance( i );
1165 SecondAttach = FirstAttach;
1167 SecondAttach = aProjector.Point( Index );
1168 aProjector.Parameters( Index, U, V );
1170 Value = FirstAttach.Distance( SecondAttach );
1171 if (Value > Precision::Confusion())
1172 DirAttach = gp_Dir( gp_Vec( FirstAttach, SecondAttach ) );
1175 Position.SetXYZ( (FirstAttach.XYZ() + SecondAttach.XYZ()) / 2 );
1176 else if (State == TopAbs_OUT || State == TopAbs_UNKNOWN)
1177 Position = AIS::ProjectPointOnLine( Position, gp_Lin( FirstAttach, DirAttach ) );
1179 // Now there is projection of FirstAttach onto SecondSurf in aProjector
1180 BRepTopAdaptor_FClass2d aClassifier( SecondFace, Precision::Confusion() );
1181 State = aClassifier.Perform( gp_Pnt2d( U, V ), ( (SecondSurf->IsUPeriodic() || SecondSurf->IsVPeriodic())?
1183 : Standard_False ) );
1184 if (State == TopAbs_OUT || State == TopAbs_UNKNOWN)
1185 SecondAttach = AIS::Nearest( SecondFace, SecondAttach );
1188 gp_Pnt AIS::TranslatePointToBound( const gp_Pnt & aPoint, const gp_Dir & aDir, const Bnd_Box & aBndBox )
1190 if (aBndBox.IsOut( aPoint ))
1194 gp_Pnt Result(0.0,0.0,0.0);
1195 TColStd_Array2OfReal Bound( 1, 3, 1, 2 );
1196 TColStd_Array1OfReal Origin( 1, 3 );
1197 TColStd_Array1OfReal Dir( 1, 3 );
1200 aBndBox.Get( Bound(1,1), Bound(2,1), Bound(3,1), Bound(1,2), Bound(2,2), Bound(3,2) );
1201 aPoint.Coord( Origin(1), Origin(2), Origin(3) );
1202 aDir.Coord( Dir(1), Dir(2), Dir(3) );
1204 Bnd_Box EnlargedBox = aBndBox;
1205 EnlargedBox.Enlarge( aBndBox.GetGap() + Precision::Confusion() );
1207 Standard_Boolean IsFound = Standard_False;
1208 for (Standard_Integer i = 1; i <= 3; i++)
1210 if (Abs( Dir( i ) ) <= gp::Resolution())
1212 for (Standard_Integer j = 1; j <= 2; j++)
1214 t = (Bound( i, j ) - Origin( i )) / Dir( i );
1217 Result = aPoint.Translated( gp_Vec( aDir ) * t );
1218 if (! EnlargedBox.IsOut( Result ))
1220 IsFound = Standard_True;
1231 //=======================================================================
1232 //function : InDomain
1234 //=======================================================================
1236 Standard_Boolean AIS::InDomain(const Standard_Real fpar,
1237 const Standard_Real lpar,
1238 const Standard_Real para)
1242 return ((para >= fpar) && (para <= lpar));
1243 else { // fpar > lpar
1244 Standard_Real delta = 2*M_PI-fpar;
1245 Standard_Real lp, par, fp;
1248 while(lp > 2*M_PI) lp-=2*M_PI;
1249 while(par > 2*M_PI) par-=2*M_PI;
1251 return ((par >= fp) && (par <= lp));
1255 if (para >= (fpar+2*M_PI)) return Standard_True;
1256 if (para <= lpar) return Standard_True;
1257 return Standard_False;
1260 //=======================================================================
1261 //function : DistanceFromApex
1262 //purpose : calculates parametric length arc of ellipse
1263 //=======================================================================
1265 Standard_Real AIS::DistanceFromApex(const gp_Elips & elips,
1266 const gp_Pnt & Apex,
1267 const Standard_Real par)
1270 Standard_Real parApex = ElCLib::Parameter ( elips, Apex );
1271 if(parApex == 0.0 || parApex == M_PI)
1273 if(parApex == 0.0) //pos Apex
1274 dist = (par < M_PI) ? par : (2*M_PI - par);
1276 dist = (par < M_PI) ? ( M_PI - par) : ( par - M_PI );
1280 if(parApex == M_PI / 2) //pos Apex
1282 if(par <= parApex + M_PI && par > parApex) // 3/2*M_PI < par < M_PI/2
1283 dist = par - parApex;
1286 if(par > parApex + M_PI) // 3/2*M_PI < par < 2*M_PI
1287 dist = 2*M_PI - par + parApex;
1289 dist = parApex - par;
1292 else //neg Apex == 3/2*M_PI
1294 if(par <= parApex && par >= M_PI/2) // M_PI/2 < par < 3/2*M_PI
1295 dist = parApex - par;
1298 if(par > parApex) // 3/2*M_PI < par < 2*M_PI
1299 dist = par - parApex;
1301 dist = par + M_PI/2; // 0 < par < M_PI/2
1308 //=======================================================================
1309 //function : NearestApex
1311 //=======================================================================
1313 gp_Pnt AIS::NearestApex(const gp_Elips & elips,
1314 const gp_Pnt & pApex,
1315 const gp_Pnt & nApex,
1316 const Standard_Real fpara,
1317 const Standard_Real lpara,
1318 Standard_Boolean & IsInDomain)
1320 Standard_Real parP, parN;
1321 gp_Pnt EndOfArrow(0.0,0.0,0.0);
1322 IsInDomain = Standard_True;
1323 parP = ElCLib::Parameter ( elips, pApex );
1324 if(InDomain(fpara, lpara, parP)) EndOfArrow = pApex;
1327 parN = ElCLib::Parameter ( elips, nApex );
1328 if(InDomain(fpara, lpara, parN)) EndOfArrow = nApex;
1330 IsInDomain = Standard_False;
1331 Standard_Real posd = Min(DistanceFromApex (elips,pApex, fpara),
1332 DistanceFromApex (elips,pApex, lpara));
1333 Standard_Real negd = Min(DistanceFromApex (elips,nApex, fpara),
1334 DistanceFromApex (elips,nApex, lpara));
1344 //=======================================================================
1345 //function : ComputeProjEdgePresentation
1347 //=======================================================================
1349 void AIS::ComputeProjEdgePresentation( const Handle( Prs3d_Presentation )& aPresentation,
1350 const Handle( AIS_Drawer )& aDrawer,
1351 const TopoDS_Edge& anEdge,
1352 const Handle( Geom_Curve )& ProjCurve,
1353 const gp_Pnt& FirstP,
1354 const gp_Pnt& LastP,
1355 const Quantity_NameOfColor aColor,
1356 const Standard_Real aWidth,
1357 const Aspect_TypeOfLine aProjTOL,
1358 const Aspect_TypeOfLine aCallTOL )
1360 if (!aDrawer->HasWireAspect()){
1361 aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aProjTOL,2.));}
1364 // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect();
1365 Handle(Prs3d_LineAspect) li = aDrawer->WireAspect();
1367 li->SetColor(aColor);
1368 li->SetTypeOfLine(aProjTOL);
1369 li->SetWidth(aWidth);
1372 Standard_Real pf, pl;
1373 TopLoc_Location loc;
1374 Handle(Geom_Curve) curve;
1375 Standard_Boolean isInfinite;
1376 curve = BRep_Tool::Curve(anEdge,loc,pf,pl);
1377 isInfinite = (Precision::IsInfinite(pf) || Precision::IsInfinite(pl));
1381 // Calculate presentation of the edge
1382 if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
1384 // const Handle(Geom_Line) & gl = (Handle(Geom_Line)&) ProjCurve;
1385 Handle(Geom_Line) gl = (Handle(Geom_Line)&) ProjCurve;
1388 pf = ElCLib::Parameter(gl->Lin(),FirstP);
1389 pl = ElCLib::Parameter(gl->Lin(),LastP);
1390 BRepBuilderAPI_MakeEdge MakEd(gl->Lin(), pf, pl);
1394 BRepBuilderAPI_MakeEdge MakEd(gl->Lin());
1398 else if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
1400 // const Handle(Geom_Circle) & gc = (Handle(Geom_Circle)&) ProjCurve;
1401 Handle(Geom_Circle) gc = (Handle(Geom_Circle)&) ProjCurve;
1403 pf = ElCLib::Parameter(gc->Circ(),FirstP);
1404 pl = ElCLib::Parameter(gc->Circ(),LastP);
1405 BRepBuilderAPI_MakeEdge MakEd(gc->Circ(),pf, pl);
1408 StdPrs_WFDeflectionShape::Add(aPresentation, E, aDrawer);
1410 //Calculate the presentation of line connections
1411 aDrawer->WireAspect()->SetTypeOfLine(aCallTOL);
1413 gp_Pnt ppf(0.0,0.0,0.0), ppl(0.0,0.0,0.0);
1414 ppf = BRep_Tool::Pnt( TopExp::FirstVertex(TopoDS::Edge(anEdge)));
1415 ppl = BRep_Tool::Pnt( TopExp::LastVertex(TopoDS::Edge(anEdge)));
1418 if (FirstP.SquareDistance( ppf ) > SquareTolerance)
1420 BRepBuilderAPI_MakeEdge MakEd1(FirstP, ppf);
1421 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd1.Edge(), aDrawer);
1425 BRepBuilderAPI_MakeVertex MakVert1( FirstP );
1426 StdPrs_WFDeflectionShape::Add(aPresentation, MakVert1.Vertex(), aDrawer);
1428 if (LastP.SquareDistance( ppl ) > SquareTolerance)
1430 BRepBuilderAPI_MakeEdge MakEd2(LastP, ppl);
1431 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd2.Edge(), aDrawer);
1435 BRepBuilderAPI_MakeVertex MakVert2( LastP );
1436 StdPrs_WFDeflectionShape::Add(aPresentation, MakVert2.Vertex(), aDrawer);
1439 BRepBuilderAPI_MakeEdge MakEd1(FirstP, ppf);
1440 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd1.Edge(), aDrawer);
1441 BRepBuilderAPI_MakeEdge MakEd2(LastP, ppl);
1442 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd2.Edge(), aDrawer);
1447 //=======================================================================
1448 //function : ComputeProjVertexPresentation
1450 //=======================================================================
1452 void AIS::ComputeProjVertexPresentation( const Handle( Prs3d_Presentation )& aPresentation,
1453 const Handle( AIS_Drawer )& aDrawer,
1454 const TopoDS_Vertex& aVertex,
1455 const gp_Pnt& ProjPoint,
1456 const Quantity_NameOfColor aColor,
1457 const Standard_Real aWidth,
1458 const Aspect_TypeOfMarker aProjTOM,
1459 const Aspect_TypeOfLine aCallTOL )
1461 if (!aDrawer->HasPointAspect()){
1462 aDrawer->SetPointAspect(new Prs3d_PointAspect(aProjTOM, aColor,1));}
1465 // const Handle(Prs3d_PointAspect)& pa = aDrawer->PointAspect();
1466 Handle(Prs3d_PointAspect) pa = aDrawer->PointAspect();
1468 pa->SetColor(aColor);
1469 pa->SetTypeOfMarker(aProjTOM);
1472 // calculate the projection
1473 StdPrs_Point::Add(aPresentation, new Geom_CartesianPoint(ProjPoint), aDrawer);
1475 if (!aDrawer->HasWireAspect()){
1476 aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aCallTOL,2.));}
1479 // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect();
1480 Handle(Prs3d_LineAspect) li = aDrawer->WireAspect();
1482 li->SetColor(aColor);
1483 li->SetTypeOfLine(aCallTOL);
1484 li->SetWidth(aWidth);
1487 // If the points are not mixed...
1488 if (!ProjPoint.IsEqual (BRep_Tool::Pnt(aVertex),Precision::Confusion())) {
1489 // calculate the lines of recall
1490 BRepBuilderAPI_MakeEdge MakEd(ProjPoint,BRep_Tool::Pnt(aVertex));
1491 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd.Edge(), aDrawer);