0024133: Development of improvement of dimensions implementation; new length, radius...
[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
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22
23#include <AIS.ixx>
24
25#include <Adaptor3d_HCurve.hxx>
26#include <Adaptor3d_HSurface.hxx>
27
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>
36
37#include <ElCLib.hxx>
38#include <ElSLib.hxx>
39
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>
68#include <TopExp.hxx>
69#include <TopExp_Explorer.hxx>
70#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
71#include <TopoDS.hxx>
72#include <gce_MakeLin.hxx>
73#include <gp_Ax1.hxx>
74#include <gp_Ax3.hxx>
75#include <gp_Dir.hxx>
76#include <gp_Elips.hxx>
77#include <gp_Lin.hxx>
78#include <gp_Pln.hxx>
79#include <gp_Pnt.hxx>
80#include <gp_Vec.hxx>
81#include <gp_XYZ.hxx>
82
08cd2f6b 83const Standard_Real SquareTolerance = Precision::SquareConfusion();
7fd59977 84
85//=======================================================================
86//function : Nearest
87//purpose :
88//=======================================================================
89
90gp_Pnt AIS::Nearest(const TopoDS_Shape& ashape, const gp_Pnt& apoint)
91{
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);
97 while (explo.More())
98 {
99 curpnt = BRep_Tool::Pnt(TopoDS::Vertex(explo.Current()));
100 curdist2 = apoint.SquareDistance(curpnt);
101 if (curdist2 < dist2)
102 {
103 result = curpnt;
104 dist2 = curdist2;
105 }
106 explo.Next();
107 }
108 return result;
109}
110
111//=======================================================================
112//function : Farest
113//purpose :
114//=======================================================================
115
116gp_Pnt AIS::Farest( const TopoDS_Shape& aShape, const gp_Pnt& aPoint )
117{
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())
123 {
124 curpnt = BRep_Tool::Pnt( TopoDS::Vertex( Explo.Current() ) );
125 curdist2 = aPoint.SquareDistance( curpnt );
126 if (curdist2 > MaxDist2)
127 {
128 MaxDist2 = curdist2;
129 Result = curpnt;
130 }
131 }
132 return Result;
133}
134
135
136//=======================================================================
137//function : ComputeGeometry
138//purpose : for line, circle, ellipse
139//=======================================================================
140
141Standard_Boolean AIS::ComputeGeometry(const TopoDS_Edge& anEdge,
142 Handle(Geom_Curve)& aCurve,
143 gp_Pnt& FirstPnt,
144 gp_Pnt& LastPnt)
145{
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()) {
151//#ifndef DEB
152 Handle(Geom_Geometry) aGeomGeometry = aCurve->Transformed(loc_edge.Transformation());
153 aCurve = (Handle(Geom_Curve)&) aGeomGeometry ;
154//#else
155// aCurve = (Handle(Geom_Curve)&) aCurve->Transformed(loc_edge.Transformation());
156//#endif
157 }
158 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
159 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
160 }
161
162 if (aCurve->IsInstance(STANDARD_TYPE(Geom_Line))) {
163 // CLE
164 // const Handle(Geom_Line)& line = (Handle(Geom_Line)&) aCurve;
165 Handle(Geom_Line) line = (Handle(Geom_Line)&) aCurve;
166 // ENDCLE
167
168 FirstPnt = ElCLib::Value(first,line->Lin());
169 LastPnt = ElCLib::Value(last,line->Lin());
170 }
171 else if (aCurve->IsInstance(STANDARD_TYPE(Geom_Circle))) {
172 // CLE
173 // const Handle(Geom_Circle)& circ = (Handle(Geom_Circle)&) aCurve;
174 Handle(Geom_Circle) circ = (Handle(Geom_Circle)&) aCurve;
175 // ENDCLE
176 FirstPnt = ElCLib::Value(first,circ->Circ());
177 LastPnt = ElCLib::Value(last,circ->Circ());
178 }
179 else if (aCurve->IsInstance(STANDARD_TYPE(Geom_Ellipse))) {
180 // CLE
181 // const Handle(Geom_Ellipse)& elips = (Handle(Geom_Ellipse)&) aCurve;
182 Handle(Geom_Ellipse) elips = (Handle(Geom_Ellipse)&) aCurve;
183 // ENDCLE
184 FirstPnt = ElCLib::Value(first, elips->Elips());
185 LastPnt = ElCLib::Value(last, elips->Elips());
186 }
187 else return Standard_False;
188 return Standard_True;
189}
190
191//=======================================================================
192//function : ComputeGeometry
193//purpose :
194//=======================================================================
195
196Standard_Boolean AIS::ComputeGeometry(const TopoDS_Edge& anEdge,
197 Handle(Geom_Curve)& aCurve,
198 gp_Pnt& FirstPnt,
199 gp_Pnt& LastPnt,
200 Handle(Geom_Curve)& extCurve,
201 Standard_Boolean& isInfinite,
202 Standard_Boolean& isOnPlane,
203 const Handle(Geom_Plane)& aPlane)
204{
205 if (aPlane.IsNull()) return Standard_False;
206
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();
212
213 if (aCurve.IsNull()) return Standard_False;
214
215 extCurve = aCurve;
216 isInfinite = (Precision::IsInfinite(first) || Precision::IsInfinite(last));
217
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();
222 }
223
224 if ( extCurve->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
225 // CLE
226 // const Handle(Geom_Line) & gl = (Handle(Geom_Line)&) extCurve;
227 Handle(Geom_Line) gl = (Handle(Geom_Line)&) extCurve;
228 // ENDCLE
229 isOnPlane = aPlane->Pln().Contains( gl->Lin(), Precision::Confusion(), Precision::Angular() );
230 }
231 else if (extCurve->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
232 // CLE
233 // const Handle(Geom_Circle) & gc = (Handle(Geom_Circle)&) extCurve;
234 Handle(Geom_Circle) gc = (Handle(Geom_Circle)&) extCurve;
235 // ENDCLE
236 gp_Ax3 ax(gc->Position());
237 isOnPlane = ax.IsCoplanar(aPlane->Pln().Position(),
238 Precision::Confusion(),
239 Precision::Angular());
240 }
241 if ( isOnPlane ) {
242 extCurve.Nullify();
243 }
244
245//#ifndef DEB
246 Handle(Geom_Curve) aGeomCurve = GeomProjLib::ProjectOnPlane(aCurve,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
247 aCurve = aGeomCurve ;
248//#else
249// aCurve = (Handle(Geom_Curve)&) GeomProjLib::ProjectOnPlane(aCurve,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
250//#endif
251
252 if (aCurve->IsInstance(STANDARD_TYPE(Geom_Line))) {
253 // CLE
254 // const Handle(Geom_Line)& line = (Handle(Geom_Line)&) aCurve;
255 Handle(Geom_Line) line = (Handle(Geom_Line)&) aCurve;
256 // EDNCLE
257 if (!isInfinite) {
258 FirstPnt = ElCLib::Value(first,line->Lin());
259 LastPnt = ElCLib::Value(last,line->Lin());
260 }
261 }
262 else if (aCurve->IsInstance(STANDARD_TYPE(Geom_Circle))) {
263 // CLE
264 // const Handle(Geom_Circle)& circ = (Handle(Geom_Circle)&) aCurve;
265 Handle(Geom_Circle) circ = (Handle(Geom_Circle)&) aCurve;
266 // ENDCLE
267 FirstPnt = ElCLib::Value(first,circ->Circ());
268 LastPnt = ElCLib::Value(last,circ->Circ());
269 }
270 // jfa 10/10/2000
271 else if (aCurve->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
272 {
273 Handle(Geom_Ellipse) ell = (Handle(Geom_Ellipse)&) aCurve;
274 FirstPnt = ElCLib::Value(first,ell->Elips());
275 LastPnt = ElCLib::Value(last,ell->Elips());
276 }
277 // jfa 10/10/2000 end
278 else return Standard_False;
279 return Standard_True;
280}
281
282//=======================================================================
283//function : ComputeGeometry
284//purpose :
285//=======================================================================
286
287Standard_Boolean AIS::ComputeGeometry(const TopoDS_Edge& anEdge1,
288 const TopoDS_Edge& anEdge2,
289 Handle(Geom_Curve)& aCurve1,
290 Handle(Geom_Curve)& aCurve2,
291 gp_Pnt& FirstPnt1,
292 gp_Pnt& LastPnt1,
293 gp_Pnt& FirstPnt2,
294 gp_Pnt& LastPnt2,
295 const Handle(Geom_Plane)& aPlane)
296{
297 if (aPlane.IsNull()) return Standard_False;
298
299 TopLoc_Location loc_edge1,loc_edge2;
300 Standard_Real first1,last1,first2,last2;
301
302 aCurve1 = BRep_Tool::Curve(anEdge1,loc_edge1,first1,last1);
303 aCurve2 = BRep_Tool::Curve(anEdge2,loc_edge2,first2,last2);
304
305 if (aCurve1.IsNull()) return Standard_False;
306 if (aCurve2.IsNull()) return Standard_False;
307
308 if (!loc_edge1.IsIdentity()) {
309//#ifndef DEB
310 Handle(Geom_Geometry) aGeomGeometry = aCurve1->Transformed(loc_edge1.Transformation());
311 aCurve1 = (Handle(Geom_Curve)&) aGeomGeometry ;
312//#else
313// aCurve1 = (Handle(Geom_Curve)&) aCurve1->Transformed(loc_edge1.Transformation());
314//#endif
315 }
316 if (!loc_edge2.IsIdentity()) {
317//#ifndef DEB
318 Handle(Geom_Geometry) aGeomGeometry = aCurve2->Transformed(loc_edge2.Transformation());
319 aCurve2 = (Handle(Geom_Curve)&) aGeomGeometry ;
320//#else
321// aCurve2 = (Handle(Geom_Curve)&) aCurve2->Transformed(loc_edge2.Transformation());
322//#endif
323 }
324
325//#ifndef DEB
326 Handle(Geom_Curve) aGeomCurve = GeomProjLib::ProjectOnPlane(aCurve1,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
327 aCurve1 = aGeomCurve ;
328//#else
329// aCurve1 = (Handle(Geom_Curve)&) GeomProjLib::ProjectOnPlane(aCurve1,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
330//#endif
331//#ifndef DEB
332 aGeomCurve = GeomProjLib::ProjectOnPlane(aCurve2,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
333 aCurve2 = aGeomCurve;
334//#else
335// aCurve2 = (Handle(Geom_Curve)&) GeomProjLib::ProjectOnPlane(aCurve2,aPlane,aPlane->Pln().Axis().Direction(),Standard_False);
336//#endif
337
338 if (aCurve1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
339 aCurve1 = ((Handle(Geom_TrimmedCurve)&) aCurve1)->BasisCurve();
340 }
341 if (aCurve2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
342 aCurve2 = ((Handle(Geom_TrimmedCurve)&) aCurve2)->BasisCurve();
343 }
344
345 if (aCurve1->IsInstance(STANDARD_TYPE(Geom_Line))) {
346 // CLE
347 // const Handle(Geom_Line)& line = (Handle(Geom_Line)&) aCurve1;
348 Handle(Geom_Line) line = (Handle(Geom_Line)&) aCurve1;
349 // ENDCLE
350 FirstPnt1 = ElCLib::Value(first1,line->Lin());
351 LastPnt1 = ElCLib::Value(last1,line->Lin());
352 }
353 else if (aCurve1->IsInstance(STANDARD_TYPE(Geom_Circle))) {
354 // CLE
355 // const Handle(Geom_Circle)& circ = (Handle(Geom_Circle)&) aCurve1;
356 Handle(Geom_Circle) circ = (Handle(Geom_Circle)&) aCurve1;
357 // ENDCLE
358 FirstPnt1 = ElCLib::Value(first1,circ->Circ());
359 LastPnt1 = ElCLib::Value(last1,circ->Circ());
360 }
361 else return Standard_False;
362
363 if (aCurve2->IsInstance(STANDARD_TYPE(Geom_Line))) {
364 // CLE
365 // const Handle(Geom_Line)& line = (Handle(Geom_Line)&) aCurve2;
366 Handle(Geom_Line) line = (Handle(Geom_Line)&) aCurve2;
367 // ENDCLE
368 FirstPnt2 = ElCLib::Value(first2,line->Lin());
369 LastPnt2 = ElCLib::Value(last2,line->Lin());
370 }
371 else if (aCurve2->IsInstance(STANDARD_TYPE(Geom_Circle))) {
372 // CLE
373 // const Handle(Geom_Circle)& circ = (Handle(Geom_Circle)&) aCurve2;
374 Handle(Geom_Circle) circ = (Handle(Geom_Circle)&) aCurve2;
375 // ENDCLE
376 FirstPnt2 = ElCLib::Value(first2,circ->Circ());
377 LastPnt2 = ElCLib::Value(last2,circ->Circ());
378 }
379 else return Standard_False;
380
381 return Standard_True;
382}
383
384//=======================================================================
385//function : ComputeGeometry
386//purpose : Computes the geometry of the 2 edges in the current wp
a6eb515f 387// and the 'right' geometry of the edges if one doesn't
388// belong to the current working plane.
7fd59977 389// There may be only one curve that can't belong to the
a6eb515f 390// current working plane ( attachement constraint)
7fd59977 391// if the 2 edges belong to the current WP, <WhatProj> = 0
392//
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//=======================================================================
399
a6eb515f 400Standard_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,
405 gp_Pnt& FirstPnt1,
406 gp_Pnt& LastPnt1,
407 gp_Pnt& FirstPnt2,
408 gp_Pnt& LastPnt2,
409 Handle(Geom_Curve)& extCurve,
410 Standard_Boolean& isInfinite1,
411 Standard_Boolean& isInfinite2,
412 const Handle(Geom_Plane)& aPlane)
7fd59977 413{
414 if (aPlane.IsNull()) return Standard_False;
415 extCurve.Nullify();
416 indexExt = 0;
417
418 Standard_Real first1,last1,first2,last2;
419 isInfinite1 = isInfinite2 = Standard_False;
420
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();
427 }
428 if (aCurve2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
429 aCurve2 = ((Handle(Geom_TrimmedCurve)&) aCurve2)->BasisCurve();
430 }
431
432 first1 = brepCurv1.FirstParameter();
433 last1 = brepCurv1.LastParameter();
434 first2 = brepCurv2.FirstParameter();
435 last2 = brepCurv2.LastParameter();
436
437 if (aCurve1.IsNull()) return Standard_False;
438 if (aCurve2.IsNull()) return Standard_False;
439
440 Handle(Geom_Curve) aSov1 = aCurve1;
441 Handle(Geom_Curve) aSov2 = aCurve2;
442
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;
448
449 if (Precision::IsInfinite(first1) || Precision::IsInfinite(last1)) {
450 isInfinite1 = Standard_True;
451 indexExt = 1;
452 }
453 if (Precision::IsInfinite(first2) || Precision::IsInfinite(last2)) {
454 isInfinite2 = Standard_True;
455 indexExt = 2;
456 }
457 if (isInfinite1 && isInfinite2) indexExt = 0; //New
458
459 if (isInfinite1 || isInfinite2) {
460 if (aCurve1->DynamicType() == aCurve2->DynamicType()) {
461 // CLE
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();
466 // ENDCLE
467 if (indexExt == 1) {
468 FirstPnt1 = ElCLib::Value(ElCLib::Parameter(lin2,FirstPnt2),lin1);
469 LastPnt1 = ElCLib::Value(ElCLib::Parameter(lin2,LastPnt2),lin1);
470 }
471 else if (indexExt == 2) {
472 FirstPnt2 = ElCLib::Value(ElCLib::Parameter(lin1,FirstPnt1),lin2);
473 LastPnt2 = ElCLib::Value(ElCLib::Parameter(lin1,LastPnt1),lin2);
474 }
475 }
476 }
477
478 if (isOnPlanC1 && isOnPlanC2) return Standard_True;
479
0d969553 480 if (!isOnPlanC1 && isOnPlanC2) {// curve 2 only in the plane
7fd59977 481 indexExt = 1;
482 extCurve = aSov1;
483 }
0d969553 484 else if (isOnPlanC1 && !isOnPlanC2) {// curve 1 only in the plane
7fd59977 485 indexExt = 2;
486 extCurve = aSov2;
487 }
488 else
489 return Standard_False;
490
491 return Standard_True;
492}
493
494
495// it is patch!
496
497//=======================================================================
498//function : ComputeGeomCurve
499//purpose : Checks if aCurve belongs to aPlane; if not, projects aCurve in aPlane
500// and returns aCurveproj;
501// Return TRUE if ok
502//=======================================================================
503
504Standard_Boolean AIS::ComputeGeomCurve(Handle(Geom_Curve)& aCurve,
505 const Standard_Real first1,
506 const Standard_Real last1,
507 gp_Pnt& FirstPnt1,
508 gp_Pnt& LastPnt1,
509 const Handle(Geom_Plane)& aPlane,
510 Standard_Boolean& isOnPlane)
511{
512 isOnPlane = Standard_True;
513
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++)
521 {
522 CurPnt = aCurve->Value( CurPar );
523 if (aPlane->Pln().SquareDistance( CurPnt ) > SquareTolerance)
524 {
525 isOnPlane = Standard_False;
526 break;
527 }
528 CurPar += Delta;
529 }
530
531 if (! Precision::IsInfinite(first1) && ! Precision::IsInfinite(last1))
532 {
533 FirstPnt1 = aCurve->Value( first1 );
534 LastPnt1 = aCurve->Value( last1 );
535 }
536 if (!isOnPlane) {
537//#ifndef DEB
538 Handle( Geom_Curve ) aGeomCurve = GeomProjLib::ProjectOnPlane( aCurve,
539 aPlane,
540 aPlane->Pln().Axis().Direction(),
541 Standard_False);
542 aCurve = aGeomCurve ;
543//#else
544// aCurve = (Handle( Geom_Curve )&) GeomProjLib::ProjectOnPlane( aCurve,
545// aPlane,
546// aPlane->Pln().Axis().Direction(),
547// Standard_False);
548//#endif
549 if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) {
550 aCurve = ((Handle(Geom_TrimmedCurve)&) aCurve)->BasisCurve();
551 }
552 if (! Precision::IsInfinite(first1) && ! Precision::IsInfinite(last1)) {
553 FirstPnt1 = AIS::ProjectPointOnPlane( FirstPnt1, aPlane->Pln() );
554 LastPnt1 = AIS::ProjectPointOnPlane( LastPnt1, aPlane->Pln() );
555 }
556 }
557 return Standard_True;
558}
559
560
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//=======================================================================
568
569Standard_Boolean AIS::ComputeGeometry(const TopoDS_Vertex& aVertex,
570 gp_Pnt& point,
571 const Handle(Geom_Plane)& aPlane,
572 Standard_Boolean& isOnPlane)
573{
574 point = BRep_Tool::Pnt(aVertex);
575 isOnPlane = aPlane->Pln().Contains(point, Precision::Confusion());
576 if ( !isOnPlane) {
577 point = AIS::ProjectPointOnPlane( point, aPlane->Pln() );
578 }
579 return Standard_True;
580}
581
582//=======================================================================
583//function : GetPlaneFromFace
584//purpose :
585// Returns type of surface which can be Plane or OtherSurface
586//=======================================================================
587
588Standard_Boolean AIS::GetPlaneFromFace( const TopoDS_Face& aFace,
589 gp_Pln & aPlane,
590 Handle( Geom_Surface )& aSurf,
591 AIS_KindOfSurface & aSurfType,
592 Standard_Real & Offset )
593
594{
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;
600
601 if (surf1.GetType() == GeomAbs_OffsetSurface)
602 {
603 // Extracting Basis Surface
604 surf2 = surf1.BasisSurface();
605 isOffset = Standard_True;
606 }
607 else
608 surf2 = new BRepAdaptor_HSurface( surf1 );
609
610 aSurf = surf1.Surface().Surface();
611 // aSurf->Transform(surf1.Trsf()) ;
612 aSurf = Handle( Geom_Surface )::DownCast( aSurf->Transformed( surf1.Trsf() ) );
613
614 if (surf2->GetType() == GeomAbs_Plane)
615 {
616 aPlane = surf2->Plane();
617 aSurfType = AIS_KOS_Plane;
618 Offset = 0.;
619 Result = Standard_True;
620 }
621
622 else if (surf2->GetType() == GeomAbs_SurfaceOfExtrusion)
623 {
624 Handle( Adaptor3d_HCurve ) BasisCurve = surf2->BasisCurve();
625 gp_Dir ExtrusionDir = surf2->Direction();
626 if (BasisCurve->GetType() == GeomAbs_Line)
627 {
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);
632 aPlane = thePlane;
633 aSurfType = AIS_KOS_Plane;
634 Offset = 0.;
635 Result = Standard_True;
636 }
637 }
638
639 if (Result == Standard_True && isOffset)
640 {
641 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
642 aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln();
643 /*
644 Handle( Geom_OffsetSurface ) OffsetSurf = Handle( Geom_OffsetSurface )::DownCast( aSurf );
645 gp_Pnt PointOnPlane;
646 gp_Vec D1u, D1v;
647 OffsetSurf->D1( 0, 0, PointOnPlane, D1u, D1v );
648 D1u.Normalize();
649 D1v.Normalize();
650 OffsetVec = D1u ^ D1v;
651 aPlane.Translate( OffsetValue * OffsetVec );
652 */
653 Offset = 0.0e0;
654 }
655 if (Result == Standard_False)
656 {
657 if (isOffset)
658 {
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))
664 {
665 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface();
666 Offset = 0.0e0;
667 }
668 else
669 {
670 Offset = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Offset();
671 aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->BasisSurface();
672 }
673 }
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;
687 else
688 aSurfType = AIS_KOS_OtherSurface;
689 }
690 return Result;
691}
692
693
694//=======================================================================
695//function : ProjectPointOnPlane
696//purpose :
697//=======================================================================
698
699gp_Pnt AIS::ProjectPointOnPlane( const gp_Pnt & aPoint, const gp_Pln & aPlane )
700{
701 gp_Vec aVec( aPlane.Location(), aPoint );
702 gp_Vec Normal = aPlane.Axis().Direction();
703 Normal = (aVec * Normal) * Normal;
704
705 return ( aPoint.Translated( -Normal ) );
706}
707
708//=======================================================================
709//function : ProjectPointOnLine
710//purpose :
711//=======================================================================
712
713gp_Pnt AIS::ProjectPointOnLine( const gp_Pnt & aPoint, const gp_Lin & aLine )
714{
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 );
719 return Result;
720}
721
722
723//=======================================================================
724//function : InitFaceLength
725//purpose :
726//=======================================================================
727
728void AIS::InitFaceLength( const TopoDS_Face& aFace,
729 gp_Pln & aPlane,
730 Handle(Geom_Surface) & aSurface,
731 AIS_KindOfSurface & aSurfaceType,
732 Standard_Real & anOffset)
733{
734 AIS::GetPlaneFromFace( aFace, aPlane, aSurface, aSurfaceType, anOffset );
735
736 if (Abs( anOffset ) > Precision::Confusion())
737 {
738 aSurface = new Geom_OffsetSurface( aSurface, anOffset );
739 anOffset = 0.0e0;
740 }
741
742}
743
744//=======================================================================
745//function : ComputeLengthBetweenPlanarFaces
746//purpose :
747//=======================================================================
748
749void 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,
756 gp_Dir & DirAttach,
757 const Standard_Boolean AutomaticPos,
758 gp_Pnt & Position )
759{
760 TopExp_Explorer aExp( FirstFace, TopAbs_VERTEX );
0d969553 761 // case of infinite planes. SMO.
7fd59977 762 if (!aExp.More())
763 FirstAttach = Plane1.Location();
764 else
765 FirstAttach = BRep_Tool::Pnt( TopoDS::Vertex( aExp.Current() ) );
766 SecondAttach = AIS::ProjectPointOnPlane( FirstAttach, Plane2 );
767
768 Value = FirstAttach.Distance( SecondAttach );
769
770 gp_Dir LengthDir = Plane1.Axis().Direction();
771 /*
772 if (Value > Precision::Confusion())
773 LengthDir = gp_Dir( gp_Vec( FirstAttach, SecondAttach ) );
774 */
775 DirAttach = Plane1.Position().XDirection();
776
777 if (AutomaticPos)
778 Position.SetXYZ((FirstAttach.XYZ() + SecondAttach.XYZ())/2.0e0) ;
779
780 else // position is given
781 {
782 FirstAttach = AIS::Nearest( FirstFace, Position );
783 SecondAttach = AIS::ProjectPointOnPlane( FirstAttach, Plane2 );
784 }
785
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)
791 {
792 SecondAttach = AIS::Nearest( SecondFace, Position );
793 if (Value > Precision::Confusion())
794 {
795 gp_Vec aVector = gp_Vec( FirstAttach, SecondAttach ) ^ LengthDir;
796 if (aVector.SquareMagnitude() > SquareTolerance)
797 DirAttach = aVector ^ LengthDir;
798 }
799 else
800 {
801 gp_Vec DirVec( FirstAttach, SecondAttach );
802 if (DirVec.SquareMagnitude() > SquareTolerance)
803 DirAttach = gp_Dir( DirVec );
804 }
805 }
806 if (!AutomaticPos)
807 {
808 gp_Pln PlaneOfDim( FirstAttach, DirAttach ^ LengthDir );
809 Position = AIS::ProjectPointOnPlane( Position, PlaneOfDim );
810 }
811}
812
813
814// Purpose: Return the point from <aFace> wich is the more distant
815// from <anAxis>
816static gp_Pnt FindFarPoint (const gp_Ax1 & anAxis,
817 const TopoDS_Face & aFace )
818{
819 gp_Pnt ResPnt(0.0,0.0,0.0);
820 Standard_Real MaxDist = 0.e0, curdist2;
821
822 gp_Lin Line (anAxis);
823
824 TopExp_Explorer Explo (aFace, TopAbs_VERTEX);
825
826 if (!Explo.More()) {
0d969553 827 // Case of infinite planes (no Vertex, no edge)
7fd59977 828 gp_Pln plane;
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) {
836 MaxDist = 100;
837 gp_Dir DMove = plane.Axis().Direction()^anAxis.Direction();
838 gp_Vec VMove (DMove.XYZ()*100);
839 ResPnt = aPoint.Translated (VMove);
840 }
841 }
842
843 for (; Explo.More(); Explo.Next())
844 {
845 // CLE
846 // const TopoDS_Vertex & aVertex = TopoDS::Vertex( Explo.Current() );
847 TopoDS_Vertex aVertex = TopoDS::Vertex( Explo.Current() );
848 // ENDCLE
849 gp_Pnt aPoint = BRep_Tool::Pnt( aVertex );
850 curdist2 = Line.SquareDistance( aPoint );
851 if (curdist2 > MaxDist)
852 {
853 MaxDist = curdist2;
854 ResPnt = aPoint;
855 }
856 }
857
858 if (MaxDist <= SquareTolerance)
859 {
860 const Standard_Integer NodeNumber = 20;
861 Explo.Init( aFace, TopAbs_EDGE );
862 for (; Explo.More(); Explo.Next())
863 {
864 // CLE
865 // const TopoDS_Edge & anEdge = TopoDS::Edge( Explo.Current() );
866 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
867 // ENDCLE
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++)
873 {
874 gp_Pnt aPoint(0.0,0.0,0.0);
875 aCurve.D0( FirstPar, aPoint );
876 curdist2 = Line.SquareDistance( aPoint );
877 if (curdist2 > MaxDist)
878 {
879 MaxDist = curdist2;
880 ResPnt = aPoint;
881 }
882 FirstPar += Delta;
883 }
884 if (MaxDist > SquareTolerance) break;
885 }
886 }
887 if (MaxDist <= SquareTolerance)
888 Standard_ConstructionError::Raise("AIS:: problem attach point") ;
889 return ResPnt;
890}
891
892void AIS::ComputeAngleBetweenPlanarFaces( const TopoDS_Face & FirstFace,
893 const TopoDS_Face & SecondFace,
894 const Handle( Geom_Surface )& Surf2,
895 const gp_Ax1 & Axis,
896 const Standard_Real Value,
897 const Standard_Boolean AutomaticPos,
898 gp_Pnt & Position,
899 gp_Pnt & Center,
900 gp_Pnt & FirstAttach,
901 gp_Pnt & SecondAttach,
902 gp_Dir & FirstDir,
903 gp_Dir & SecondDir )
904{
905 FirstAttach = FindFarPoint( Axis, FirstFace );
906 Center = AIS::ProjectPointOnLine( FirstAttach, gp_Lin( Axis ) );
907 gp_Dir aDir1( gp_Vec( Center, FirstAttach ) );
908 FirstDir = aDir1;
909 SecondAttach = FirstAttach.Rotated( Axis, Value );
910 gp_Dir aDir2( gp_Vec( Center, SecondAttach ) );
911 SecondDir = aDir2;
912
913 GeomAPI_ProjectPointOnSurf aProjPnt( SecondAttach,
914 Surf2 ) ;
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 );
923
924 if (AutomaticPos)
925 Position = FirstAttach.Rotated( Axis, Value*0.5 );
926 else
927 {
928 gp_Pln PlaneOfDim( Center, Axis.Direction() );
929 Position = AIS::ProjectPointOnPlane( Position, PlaneOfDim );
930 }
931}
932
933
934void 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,
940 const gp_Ax1 & Axis,
941 const Standard_Real Value,
942 const Standard_Boolean AutomaticPos,
943 gp_Pnt & Position,
944 gp_Pnt & Center,
945 gp_Pnt & FirstAttach,
946 gp_Pnt & SecondAttach,
947 gp_Dir & FirstDir,
948 gp_Dir & SecondDir,
949 Handle( Geom_Plane ) & Plane )
950{
951 //
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
955 //
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() ) ) );
961
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(),
966 FirstAttach,
967 FirstU, FirstV );
968 else // it is Cone
969 ElSLib::Parameters( Handle( Geom_ConicalSurface )::DownCast( FirstSurf )->Cone(),
970 FirstAttach,
971 FirstU, FirstV );
972 FirstLine = Handle( Geom_Line )::DownCast( FirstSurf->UIso( FirstU ) );
973
974 if (SecondSurfType == AIS_KOS_Cylinder)
975 {
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() ) ),
980 FirstAttach ) ) );
981
982 SecondLine = Handle( Geom_Line )::DownCast( Cylinder2->UIso( SecondU ) );
983 }
984
985 else // it is Cone
986 {
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() )),
991 FirstAttach ) );
992
993 Standard_Real SecondU = Xdirection.Angle( ToFirstAttach );
994 // check sign
995 if (! Xdirection.IsEqual( ToFirstAttach, Precision::Angular() ) &&
996 ! Xdirection.IsOpposite( ToFirstAttach, Precision::Angular() ) &&
997 (Xdirection ^ ToFirstAttach) * Cone2->Cone().Axis().Direction() < 0.0e0)
c6541a0c 998 SecondU = 2*M_PI - SecondU ;
7fd59977 999
1000 SecondLine = Handle( Geom_Line )::DownCast( Cone2->UIso( SecondU ) );
1001
1002 }
1003 if (! (FirstLine->Lin().Direction().IsEqual( SecondLine->Lin().Direction(), Precision::Angular() )) &&
1004 ! (FirstLine->Lin().Direction().IsOpposite( SecondLine->Lin().Direction(), Precision::Angular() )))
1005 {
1006 GeomAPI_ExtremaCurveCurve Intersection( FirstLine, SecondLine );
1007 Intersection.Points( 1, Center, Center );
1008
1009 if (Center.SquareDistance( FirstAttach ) <= SquareTolerance)
1010 {
1011 FirstAttach = AIS::Farest( FirstFace, Center );
1012 Standard_Real U, V;
1013 if (FirstSurfType == AIS_KOS_Cylinder)
1014 {
1015 ElSLib::Parameters ( (Handle( Geom_CylindricalSurface )::DownCast( FirstSurf ))->Cylinder(),
1016 FirstAttach,
1017 U, V );
1018 FirstAttach = ElSLib::Value( FirstU, V,
1019 (Handle( Geom_CylindricalSurface )::DownCast( FirstSurf ))
1020 ->Cylinder() );
1021 }
1022 else // it is Cone
1023 {
1024 ElSLib::Parameters ( (Handle( Geom_ConicalSurface )::DownCast( FirstSurf ))->Cone(),
1025 FirstAttach,
1026 U, V );
1027 FirstAttach = ElSLib::Value( FirstU, V,
1028 (Handle( Geom_ConicalSurface )::DownCast( FirstSurf ))
1029 ->Cone() );
1030 }
1031 }
1032 gp_Vec FirstVec( Center, FirstAttach );
1033 FirstDir = gp_Dir( FirstVec );
1034
1035 gp_Ax1 AxisOfRotation( Center, Plane->Pln().Axis().Direction() );
1036 SecondAttach = FirstAttach.Rotated( AxisOfRotation, Value );
1037 if (! SecondLine->Lin().Contains( SecondAttach, Precision::Confusion() ))
1038 {
1039 AxisOfRotation.Reverse();
1040 SecondAttach = FirstAttach.Rotated( AxisOfRotation, Value );
1041 }
1042
1043 Position = FirstAttach.Rotated( AxisOfRotation, Value/2 );
1044
1045 gp_Vec SecondVec( Center, SecondAttach );
1046 SecondDir = gp_Dir( SecondVec );
1047
1048 }
1049 else // FirstLine and SecondLine are coincident
1050 {
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 ) );
1056 }
1057
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)
1064 {
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())
1071 {
1072 curpnt = BRep_Tool::Pnt( TopoDS::Vertex( Explo.Current() ) );
1073 curdist2 = SecondAttach.SquareDistance( curpnt ) ;
1074 if (curpnt.SquareDistance( Center ) > SquareTolerance && curdist2 < MinDist2)
1075 {
1076 Result = curpnt;
1077 MinDist2 = curdist2;
1078 }
1079 }
1080 SecondAttach = Result;
1081 }
1082
1083 if (! AutomaticPos)
1084 { // protection in case this is created using the manual position
1085
1086
1087 Position = AIS::ProjectPointOnPlane( SavedPosition, Plane->Pln() );
1088 }
1089}
1090
1091
1092void 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,
1098 gp_Pnt & Position,
1099 gp_Pnt & FirstAttach,
1100 gp_Pnt & SecondAttach,
1101 gp_Dir & DirAttach )
1102{
1103 GeomAPI_ProjectPointOnSurf aProjector;
1104 Quantity_Parameter U, V;
7fd59977 1105 TopAbs_State State = TopAbs_UNKNOWN;
7fd59977 1106 if (AutomaticPos)
1107 {
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 );
1113 }
1114 else // posiiton is given
1115 {
1116 aProjector.Init( Position, FirstSurf );
1117 FirstAttach = aProjector.NearestPoint();
1118
1119 aProjector.LowerDistanceParameters( U, V );
1120 BRepTopAdaptor_FClass2d aClassifier( FirstFace, Precision::Confusion() );
1121 State = aClassifier.Perform( gp_Pnt2d( U, V ), ( (FirstSurf->IsUPeriodic() || FirstSurf->IsVPeriodic())?
1122 Standard_True
1123 : Standard_False ) );
1124 if (State == TopAbs_OUT || State == TopAbs_UNKNOWN)
1125 {
1126 FirstAttach = AIS::Nearest( FirstFace, Position );
1127 aProjector.Init( FirstAttach, FirstSurf );
1128 aProjector.LowerDistanceParameters( U, V );
1129 }
1130 }
1131
1132 gp_Vec D1U, D1V;
1133 FirstSurf->D1( U, V, FirstAttach, D1U, D1V );
1134 if (D1U.SquareMagnitude() <= SquareTolerance || D1V.SquareMagnitude() <= SquareTolerance)
1135 {
1136 FirstAttach = AIS::Farest( FirstFace, FirstAttach );
1137 aProjector.Init( FirstAttach, FirstSurf );
1138 aProjector.LowerDistanceParameters( U, V );
1139 FirstSurf->D1( U, V, FirstAttach, D1U, D1V );
1140 }
1141 D1U.Normalize();
1142 D1V.Normalize();
1143 DirAttach = gp_Dir( D1U ^ D1V );
1144
1145 aProjector.Init( FirstAttach, SecondSurf );
7fd59977 1146 Standard_Integer Index = 0;
7fd59977 1147 Quantity_Length MinDist = RealLast();
1148 gp_Dir LocalDir;
1149 for (Standard_Integer i = 1; i <= aProjector.NbPoints(); i++)
1150 {
1151 aProjector.Parameters( i, U, V );
1152
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 ) ) );
1156 else
1157 LocalDir = gp_Dir( D1U ^ D1V );
1158 if (DirAttach.IsParallel( LocalDir, Precision::Angular() ) && aProjector.Distance( i ) < MinDist)
1159 {
1160 Index = i;
1161 MinDist = aProjector.Distance( i );
1162 }
1163 }
1164if (Index == 0) {
1165 SecondAttach = FirstAttach;
1166} else {
1167 SecondAttach = aProjector.Point( Index );
1168 aProjector.Parameters( Index, U, V );
1169
1170 Value = FirstAttach.Distance( SecondAttach );
1171 if (Value > Precision::Confusion())
1172 DirAttach = gp_Dir( gp_Vec( FirstAttach, SecondAttach ) );
1173
1174 if (AutomaticPos)
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 ) );
1178
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())?
1182 Standard_True
1183 : Standard_False ) );
1184 if (State == TopAbs_OUT || State == TopAbs_UNKNOWN)
1185 SecondAttach = AIS::Nearest( SecondFace, SecondAttach );
1186}
1187}
1188gp_Pnt AIS::TranslatePointToBound( const gp_Pnt & aPoint, const gp_Dir & aDir, const Bnd_Box & aBndBox )
1189{
1190 if (aBndBox.IsOut( aPoint ))
1191 return aPoint;
1192 else
1193 {
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 );
1198 Standard_Real t;
1199
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) );
1203
1204 Bnd_Box EnlargedBox = aBndBox;
1205 EnlargedBox.Enlarge( aBndBox.GetGap() + Precision::Confusion() );
1206
1207 Standard_Boolean IsFound = Standard_False;
1208 for (Standard_Integer i = 1; i <= 3; i++)
1209 {
1210 if (Abs( Dir( i ) ) <= gp::Resolution())
1211 continue;
1212 for (Standard_Integer j = 1; j <= 2; j++)
1213 {
1214 t = (Bound( i, j ) - Origin( i )) / Dir( i );
1215 if (t < 0.0e0)
1216 continue;
1217 Result = aPoint.Translated( gp_Vec( aDir ) * t );
1218 if (! EnlargedBox.IsOut( Result ))
1219 {
1220 IsFound = Standard_True;
1221 break;
1222 }
1223 }
1224 if (IsFound) break;
1225 }
1226 return Result;
1227 }
1228}
1229
1230
1231//=======================================================================
1232//function : InDomain
1233//purpose :
1234//=======================================================================
1235
1236Standard_Boolean AIS::InDomain(const Standard_Real fpar,
1237 const Standard_Real lpar,
1238 const Standard_Real para)
1239{
1240 if (fpar >= 0.) {
1241 if(lpar > fpar)
1242 return ((para >= fpar) && (para <= lpar));
1243 else { // fpar > lpar
c6541a0c 1244 Standard_Real delta = 2*M_PI-fpar;
7fd59977 1245 Standard_Real lp, par, fp;
1246 lp = lpar + delta;
1247 par = para + delta;
c6541a0c
D
1248 while(lp > 2*M_PI) lp-=2*M_PI;
1249 while(par > 2*M_PI) par-=2*M_PI;
7fd59977 1250 fp = 0.;
1251 return ((par >= fp) && (par <= lp));
1252 }
1253
1254 }
c6541a0c 1255 if (para >= (fpar+2*M_PI)) return Standard_True;
7fd59977 1256 if (para <= lpar) return Standard_True;
1257 return Standard_False;
1258}
1259
1260//=======================================================================
1261//function : DistanceFromApex
1262//purpose : calculates parametric length arc of ellipse
1263//=======================================================================
1264
1265Standard_Real AIS::DistanceFromApex(const gp_Elips & elips,
1266 const gp_Pnt & Apex,
1267 const Standard_Real par)
1268{
1269 Standard_Real dist;
1270 Standard_Real parApex = ElCLib::Parameter ( elips, Apex );
c6541a0c 1271 if(parApex == 0.0 || parApex == M_PI)
7fd59977 1272 {//Major case
1273 if(parApex == 0.0) //pos Apex
c6541a0c 1274 dist = (par < M_PI) ? par : (2*M_PI - par);
7fd59977 1275 else //neg Apex
c6541a0c 1276 dist = (par < M_PI) ? ( M_PI - par) : ( par - M_PI );
7fd59977 1277 }
1278 else
1279 {// Minor case
c6541a0c 1280 if(parApex == M_PI / 2) //pos Apex
7fd59977 1281 {
c6541a0c 1282 if(par <= parApex + M_PI && par > parApex) // 3/2*M_PI < par < M_PI/2
7fd59977 1283 dist = par - parApex;
1284 else
1285 {
c6541a0c
D
1286 if(par > parApex + M_PI) // 3/2*M_PI < par < 2*M_PI
1287 dist = 2*M_PI - par + parApex;
7fd59977 1288 else
1289 dist = parApex - par;
1290 }
1291 }
c6541a0c 1292 else //neg Apex == 3/2*M_PI
7fd59977 1293 {
c6541a0c 1294 if(par <= parApex && par >= M_PI/2) // M_PI/2 < par < 3/2*M_PI
7fd59977 1295 dist = parApex - par;
1296 else
1297 {
c6541a0c 1298 if(par > parApex) // 3/2*M_PI < par < 2*M_PI
7fd59977 1299 dist = par - parApex;
1300 else
c6541a0c 1301 dist = par + M_PI/2; // 0 < par < M_PI/2
7fd59977 1302 }
1303 }
1304 }
1305 return dist;
1306}
1307
1308//=======================================================================
1309//function : NearestApex
1310//purpose :
1311//=======================================================================
1312
1313gp_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)
1319{
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;
1325 else
1326 {
1327 parN = ElCLib::Parameter ( elips, nApex );
1328 if(InDomain(fpara, lpara, parN)) EndOfArrow = nApex;
1329 else {
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));
1335 if( posd < negd )
1336 EndOfArrow = pApex;
1337 else
1338 EndOfArrow = nApex;
1339 }
1340 }
1341 return EndOfArrow;
1342}
1343
1344//=======================================================================
1345//function : ComputeProjEdgePresentation
1346//purpose :
1347//=======================================================================
1348
1349void 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 )
1359{
1360 if (!aDrawer->HasWireAspect()){
1361 aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aProjTOL,2.));}
1362 else {
1363 // CLE
1364 // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect();
1365 Handle(Prs3d_LineAspect) li = aDrawer->WireAspect();
1366 // ENDCLE
1367 li->SetColor(aColor);
1368 li->SetTypeOfLine(aProjTOL);
1369 li->SetWidth(aWidth);
1370 }
1371
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));
1378
1379 TopoDS_Edge E;
1380
0d969553 1381 // Calculate presentation of the edge
7fd59977 1382 if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
1383 // CLE
1384 // const Handle(Geom_Line) & gl = (Handle(Geom_Line)&) ProjCurve;
1385 Handle(Geom_Line) gl = (Handle(Geom_Line)&) ProjCurve;
1386 // ENDCLE
1387 if ( !isInfinite) {
1388 pf = ElCLib::Parameter(gl->Lin(),FirstP);
1389 pl = ElCLib::Parameter(gl->Lin(),LastP);
1390 BRepBuilderAPI_MakeEdge MakEd(gl->Lin(), pf, pl);
1391 E = MakEd.Edge();
1392 }
1393 else {
1394 BRepBuilderAPI_MakeEdge MakEd(gl->Lin());
1395 E = MakEd.Edge();
1396 }
1397 }
1398 else if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
1399 // CLE
1400 // const Handle(Geom_Circle) & gc = (Handle(Geom_Circle)&) ProjCurve;
1401 Handle(Geom_Circle) gc = (Handle(Geom_Circle)&) ProjCurve;
1402 // ENDCLE
1403 pf = ElCLib::Parameter(gc->Circ(),FirstP);
1404 pl = ElCLib::Parameter(gc->Circ(),LastP);
1405 BRepBuilderAPI_MakeEdge MakEd(gc->Circ(),pf, pl);
1406 E = MakEd.Edge();
1407 }
1408 StdPrs_WFDeflectionShape::Add(aPresentation, E, aDrawer);
1409
0d969553 1410 //Calculate the presentation of line connections
7fd59977 1411 aDrawer->WireAspect()->SetTypeOfLine(aCallTOL);
1412 if (!isInfinite) {
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)));
1416
1417 // it is patch!
1418 if (FirstP.SquareDistance( ppf ) > SquareTolerance)
1419 {
1420 BRepBuilderAPI_MakeEdge MakEd1(FirstP, ppf);
1421 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd1.Edge(), aDrawer);
1422 }
1423 else
1424 {
1425 BRepBuilderAPI_MakeVertex MakVert1( FirstP );
1426 StdPrs_WFDeflectionShape::Add(aPresentation, MakVert1.Vertex(), aDrawer);
1427 }
1428 if (LastP.SquareDistance( ppl ) > SquareTolerance)
1429 {
1430 BRepBuilderAPI_MakeEdge MakEd2(LastP, ppl);
1431 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd2.Edge(), aDrawer);
1432 }
1433 else
1434 {
1435 BRepBuilderAPI_MakeVertex MakVert2( LastP );
1436 StdPrs_WFDeflectionShape::Add(aPresentation, MakVert2.Vertex(), aDrawer);
1437 }
1438/*
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);
1443*/
1444 }
1445}
1446
1447//=======================================================================
1448//function : ComputeProjVertexPresentation
1449//purpose :
1450//=======================================================================
1451
1452void 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 )
1460{
1461 if (!aDrawer->HasPointAspect()){
1462 aDrawer->SetPointAspect(new Prs3d_PointAspect(aProjTOM, aColor,1));}
1463 else {
1464 // CLE
1465 // const Handle(Prs3d_PointAspect)& pa = aDrawer->PointAspect();
1466 Handle(Prs3d_PointAspect) pa = aDrawer->PointAspect();
1467 // ENDCLE
1468 pa->SetColor(aColor);
1469 pa->SetTypeOfMarker(aProjTOM);
1470 }
1471
0d969553 1472 // calculate the projection
7fd59977 1473 StdPrs_Point::Add(aPresentation, new Geom_CartesianPoint(ProjPoint), aDrawer);
1474
1475 if (!aDrawer->HasWireAspect()){
1476 aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aCallTOL,2.));}
1477 else {
1478 // CLE
1479 // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect();
1480 Handle(Prs3d_LineAspect) li = aDrawer->WireAspect();
1481 // ENDCLE
1482 li->SetColor(aColor);
1483 li->SetTypeOfLine(aCallTOL);
1484 li->SetWidth(aWidth);
1485 }
1486
0d969553 1487 // If the points are not mixed...
7fd59977 1488 if (!ProjPoint.IsEqual (BRep_Tool::Pnt(aVertex),Precision::Confusion())) {
0d969553 1489 // calculate the lines of recall
7fd59977 1490 BRepBuilderAPI_MakeEdge MakEd(ProjPoint,BRep_Tool::Pnt(aVertex));
1491 StdPrs_WFDeflectionShape::Add(aPresentation, MakEd.Edge(), aDrawer);
1492 }
1493}