Integration of OCCT 6.5.0 from SVN
[occt.git] / src / AIS / AIS_AngleDimension.cxx
CommitLineData
7fd59977 1// File: AIS_AngleDimension.cdl
2// Created: Tue Dec 5 15:09:04 1996
3// Author: Arnaud BOUZY/Odile Olivier
4// <ODL>
5
6#define BUC60655 //GG 22/03/00 Enable to compute correctly
7// the arrow size at object creation time.
8
9#define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
10// if any in all dimensions.
11
12#include <Standard_NotImplemented.hxx>
13
14#include <AIS_AngleDimension.ixx>
15
16#include <AIS.hxx>
17#include <AIS_DimensionOwner.hxx>
18#include <AIS_Drawer.hxx>
19
20#include <BRepBuilderAPI_MakeFace.hxx>
21#include <BRepAdaptor_Curve.hxx>
22#include <BRepAdaptor_Surface.hxx>
23#include <BRep_Tool.hxx>
24
25#include <DsgPrs.hxx>
26#include <DsgPrs_AnglePresentation.hxx>
27
28#include <ElCLib.hxx>
29#include <ElSLib.hxx>
30
31#include <Geom2d_Circle.hxx>
32#include <Geom2d_Curve.hxx>
33#include <Geom2d_Line.hxx>
34#include <GeomAPI.hxx>
35#include <Geom_Circle.hxx>
36#include <Geom_Line.hxx>
37#include <Geom_Plane.hxx>
38#include <Geom_TrimmedCurve.hxx>
39#include <Geom_Surface.hxx>
40#include <Geom_CylindricalSurface.hxx>
41#include <Geom_ConicalSurface.hxx>
42#include <Geom_SurfaceOfRevolution.hxx>
43#include <Geom_SurfaceOfLinearExtrusion.hxx>
44#include <Geom_OffsetSurface.hxx>
45
46#include <IntAna2d_AnaIntersection.hxx>
47#include <IntAna2d_IntPoint.hxx>
48#include <IntAna_QuadQuadGeo.hxx>
49#include <IntAna_ResultType.hxx>
50
51#include <Precision.hxx>
52
53#include <ProjLib.hxx>
54
55#include <Prs3d_AngleAspect.hxx>
56#include <Prs3d_ArrowAspect.hxx>
57#include <Prs3d_Drawer.hxx>
58
59#include <Select3D_SensitiveCurve.hxx>
60#include <Select3D_SensitiveSegment.hxx>
61#include <Select3D_SensitiveBox.hxx>
62#include <SelectMgr_EntityOwner.hxx>
63
64#include <TColStd_Array1OfReal.hxx>
65
66#include <TopExp.hxx>
67#include <TopExp_Explorer.hxx>
68#include <TopoDS.hxx>
69#include <TopoDS_Shape.hxx>
70#include <TopoDS_Vertex.hxx>
71
72#include <UnitsAPI.hxx>
73
74#include <gp.hxx>
75#include <gp_Ax1.hxx>
76#include <gp_Lin.hxx>
77#include <gp_Cone.hxx>
78#include <gp_Pln.hxx>
79#include <gp_Pnt.hxx>
80#include <gp_Pnt2d.hxx>
81#include <gp_Vec.hxx>
82#include <gp_XYZ.hxx>
83
84#include <GC_MakeCircle.hxx>
85#include <GC_MakeConicalSurface.hxx>
86#include <gce_MakePln.hxx>
87#include <gce_MakeCone.hxx>
88#include <Graphic3d_Array1OfVertex.hxx>
89
90//=======================================================================
91//function : Constructor
92//purpose : ConeAngle dimension
93//=======================================================================
94
95AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aCone,
96 const Standard_Real aVal,
97 const TCollection_ExtendedString& aText,
98 const gp_Pnt& aPosition,
99 const DsgPrs_ArrowSide /*aSymbolPrs*/,
100 const Standard_Real anArrowSize):
101myNbShape(1)
102{
103 myCone = aCone;
104 myVal = aVal;
105 myText = aText;
106 myPosition = aPosition;
107 mySymbolPrs = DsgPrs_AS_BOTHAR;
108 myAutomaticPosition = Standard_True;
109#ifdef BUC60915
110 SetArrowSize( anArrowSize );
111#else
112 myArrowSize = anArrowSize;
113#endif
114}
115
116//=======================================================================
117//function : Constructor
118//purpose : ConeAngle dimension
119//=======================================================================
120
121AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aCone,
122 const Standard_Real aVal,
123 const TCollection_ExtendedString& aText):
124myNbShape(1)
125{
126//#ifdef DEB
127 cout << "Call new AngleDimension for cone's angle" << endl;
128//#endif
129
130 gp_Pnt tmpPnt(0., 0., 0.);
131
132 myCone = aCone;
133 myVal = aVal;
134 myText = aText;
135 myPosition = tmpPnt;
136 mySymbolPrs = DsgPrs_AS_BOTHAR;
137 myAutomaticPosition = Standard_True;
138
139 myArrowSize = 0.0;
140
141}
142
143
144//=======================================================================
145//function : Constructor
146//purpose : TwoEdgesAngle dimension
147//=======================================================================
148
149
150AIS_AngleDimension::AIS_AngleDimension(const TopoDS_Edge& aFirstEdge,
151 const TopoDS_Edge& aSecondEdge,
152 const Handle (Geom_Plane)& aPlane,
153 const Standard_Real aVal,
154 const TCollection_ExtendedString& aText)
155:AIS_Relation(),
156 myNbShape(2)
157{
158#ifdef DEB
159 cout << endl << "Call new AngleDimension for edges, default" << endl;
160#endif
161
162 myFShape = aFirstEdge;
163 mySShape = aSecondEdge;
164 myVal = aVal;
165 myPlane = aPlane;
166 myText = aText;
167 mySymbolPrs = DsgPrs_AS_BOTHAR;
168 myAutomaticPosition = Standard_True;
169
170 myArrowSize = myVal / 100.;
171}
172
173//=======================================================================
174//function : Constructor
175//purpose : TwoEdgesAngle dimension (avec position et texte)
176//=======================================================================
177
178AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Edge& aFirstEdge,
179 const TopoDS_Edge& aSecondEdge,
180 const Handle (Geom_Plane)& aPlane,
181 const Standard_Real aVal,
182 const TCollection_ExtendedString& aText,
183 const gp_Pnt& aPosition,
184 const DsgPrs_ArrowSide aSymbolPrs,
185 const Standard_Real anArrowSize):
186myNbShape(2)
187{
188#ifdef DEB
189 cout << endl << "Call new AngleDimension for edges" << endl;
190#endif
191
192 myFShape = aFirstEdge;
193 mySShape = aSecondEdge;
194 myVal = aVal;
195 myPlane = aPlane;
196 myText = aText;
197 mySymbolPrs = aSymbolPrs;
198 myAutomaticPosition = Standard_False;
199#ifdef BUC60915
200 SetArrowSize( anArrowSize );
201#else
202 myArrowSize = anArrowSize;
203#endif
204 myPosition = aPosition;
205
206}
207
208//=======================================================================
209//function : Constructor
210//purpose : TwoPlanarFacesAngle dimension
211//=======================================================================
212
213AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFirstFace,
214 const TopoDS_Face& aSecondFace,
215 const gp_Ax1& anAxis,
216 const Standard_Real aVal,
217 const TCollection_ExtendedString& aText):
218myNbShape(2),
219myAxis(anAxis)
220{
221#ifdef DEB
222 cout << endl << "Call new AngleDimension for planar faces, default" << endl;
223#endif
224
225 myFShape = aFirstFace;
226 mySShape = aSecondFace;
227
228 AIS::GetPlaneFromFace( aFirstFace, myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
229 AIS::GetPlaneFromFace( aSecondFace, mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );
230
231//POP init champ myPlane
232 myPlane = new Geom_Plane(myFirstPlane);
233
234 myVal = aVal;
235 myText = aText;
236 mySymbolPrs = DsgPrs_AS_BOTHAR;
237 myAutomaticPosition = Standard_True;
238
239 myArrowSize = myVal / 100.;
240}
241
242//=======================================================================
243//function : Constructor
244//purpose : TwoPlanarFacesAngle dimension (avec position et texte)
245//=======================================================================
246
247AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFirstFace,
248 const TopoDS_Face& aSecondFace,
249 const gp_Ax1& anAxis,
250 const Standard_Real aVal,
251 const TCollection_ExtendedString& aText,
252 const gp_Pnt& aPosition,
253 const DsgPrs_ArrowSide aSymbolPrs,
254 const Standard_Real anArrowSize):
255myNbShape(2),
256myAxis(anAxis)
257{
258#ifdef DEB
259 cout << endl << "Call new AngleDimension for planar faces" << endl;
260#endif
261
262 myFShape = aFirstFace;
263 mySShape = aSecondFace;
264
265 AIS::GetPlaneFromFace( aFirstFace, myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
266 AIS::GetPlaneFromFace( aSecondFace, mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );
267
268//POP init champ myPlane
269 myPlane = new Geom_Plane(myFirstPlane);
270
271 myVal = aVal;
272 myText = aText;
273 mySymbolPrs = aSymbolPrs;
274 myAutomaticPosition = Standard_False;
275#ifdef BUC60915
276 SetArrowSize( anArrowSize );
277#else
278 myArrowSize = anArrowSize;
279#endif
280 myPosition = aPosition;
281}
282
283
284//=======================================================================
285//function : AIS_AngleDimension
286//purpose : Two curvilinear faces dimension
287//=======================================================================
288
289AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFFace,
290 const TopoDS_Face& aSFace,
291 const Standard_Real aVal,
292 const TCollection_ExtendedString& aText ):
293myNbShape(2)
294{
295#ifdef DEB
296 cout << endl << "Call new AngleDimension for curvilinear faces, default" << endl;
297#endif
298
299 SetFirstShape( aFFace );
300 SetSecondShape( aSFace );
301 myVal = aVal;
302
303 myText = aText;
304 mySymbolPrs = DsgPrs_AS_BOTHAR;
305 myAutomaticPosition = Standard_True;
306
307 myArrowSize = myVal / 100.;
308}
309
310//=======================================================================
311//function : AIS_AngleDimension
312//purpose :
313//=======================================================================
314
315AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFFace,
316 const TopoDS_Face& aSFace,
317 const Standard_Real aVal,
318 const TCollection_ExtendedString& aText,
319 const gp_Pnt& aPosition,
320 const DsgPrs_ArrowSide aSymbolPrs,
321 const Standard_Real anArrowSize):
322myNbShape(2)
323{
324#ifdef DEB
325 cout << endl << "Call new AngleDimension for curvilinear faces" << endl;
326#endif
327
328 SetFirstShape( aFFace );
329 SetSecondShape( aSFace );
330 myVal = aVal;
331
332 myText = aText;
333 mySymbolPrs = DsgPrs_AS_BOTHAR;
334 myAutomaticPosition = Standard_True;
335
336 mySymbolPrs = aSymbolPrs;
337 myAutomaticPosition = Standard_False;
338#ifdef BUC60915
339 SetArrowSize( anArrowSize );
340#else
341 myArrowSize = anArrowSize;
342#endif
343 myPosition = aPosition;
344}
345
346
347//=======================================================================
348//function : SetConeFace
349//purpose :
350//=======================================================================
351
352void AIS_AngleDimension::SetConeFace( const TopoDS_Face& aConeFace )
353{
354 myCone = aConeFace;
355 myAutomaticPosition = Standard_True;
356}
357
358
359//=======================================================================
360//function : SetFirstShape
361//purpose :
362//=======================================================================
363
364void AIS_AngleDimension::SetFirstShape( const TopoDS_Shape& aFShape )
365{
366 myFShape = aFShape;
367
368 if (myFShape.ShapeType() == TopAbs_FACE)
369 {
370 AIS::GetPlaneFromFace( TopoDS::Face( myFShape ),
371 myFirstPlane,
372 myFirstBasisSurf,
373 myFirstSurfType,
374 myFirstOffset );
375
376 if (myFirstSurfType == AIS_KOS_Cylinder)
377 myAxis = (Handle( Geom_CylindricalSurface )::DownCast( myFirstBasisSurf ))->Cylinder().Axis();
378 else if (myFirstSurfType == AIS_KOS_Cone)
379 myAxis = (Handle( Geom_ConicalSurface )::DownCast( myFirstBasisSurf ))->Cone().Axis();
380 else if (myFirstSurfType == AIS_KOS_Revolution)
381 myAxis = (Handle( Geom_SurfaceOfRevolution )::DownCast( myFirstBasisSurf ))->Axis();
382 else if (myFirstSurfType == AIS_KOS_Extrusion)
383 {
384 myAxis.SetDirection((Handle( Geom_SurfaceOfLinearExtrusion )::DownCast( myFirstBasisSurf ))
385 ->Direction() );
386 //myAxis.SetLocation( ??? );
387 }
388 }
389}
390
391//=======================================================================
392//function : SetSecondShape
393//purpose :
394//=======================================================================
395
396void AIS_AngleDimension::SetSecondShape( const TopoDS_Shape& aSShape )
397{
398 mySShape = aSShape;
399
400 if (myFShape.ShapeType() == TopAbs_FACE)
401 AIS::GetPlaneFromFace( TopoDS::Face( mySShape ),
402 mySecondPlane,
403 mySecondBasisSurf,
404 mySecondSurfType,
405 mySecondOffset );
406}
407
408
409
410
411///=======================================================================
412//function : Compute
413//purpose :
414//=======================================================================
415
416void AIS_AngleDimension::Compute(const Handle(PrsMgr_PresentationManager3d)&,
417 const Handle(Prs3d_Presentation)& aPresentation,
418 const Standard_Integer)
419{
420 aPresentation->Clear();
421
422 if( myNbShape == 1 )
423 {
424 // cout << "Computing for cone' angle " << endl;
425 ComputeConeAngle(aPresentation);
426 return;
427 }
428 switch (myFShape.ShapeType()) {
429 case TopAbs_FACE :
430 {
431 // cas angle entre deux faces
432 ComputeTwoFacesAngle(aPresentation);
433 }
434 break;
435 case TopAbs_EDGE :
436 {
437 // cas angle entre deux edges
438 ComputeTwoEdgesAngle(aPresentation);
439 }
440 break;
441 default:
442 break;
443 }
444
445}
446
447//=======================================================================
448//function : Compute
449//purpose : : to avoid warning
450//=======================================================================
451
452void AIS_AngleDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
453 const Handle(Prs3d_Presentation)& aPresentation)
454{
455// Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
456 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
457}
458
459//=======================================================================
460//function : Compute
461//purpose : : to avoid warning
462//=======================================================================
463
464void AIS_AngleDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
465 const Handle(Graphic2d_GraphicObject)& aGraphicObject,
466 const Standard_Integer anInteger)
467{
468// Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
469 PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
470}
471
472void AIS_AngleDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
473{
474// Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
475 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
476}
477
478//=======================================================================
479//function : ComputeSelection
480//purpose :
481//=======================================================================
482
483void AIS_AngleDimension::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
484 const Standard_Integer)
485{
486
487 if ( myNbShape == 1 )
488 {
489 // cout << "Computing selection for cone's angle " << endl;
490 ComputeConeAngleSelection(aSelection);
491 return;
492 }
493
494
495 if (myFShape.IsNull()) return;
496
497 if (myFShape.ShapeType() == TopAbs_FACE )
498 Compute3DSelection(aSelection);
499 else
500 Compute2DSelection(aSelection);
501
502 // Text
503 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
504 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
505 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
506 myPosition.X(),
507 myPosition.Y(),
508 myPosition.Z(),
509 myPosition.X() + size,
510 myPosition.Y() + size,
511 myPosition.Z() + size);
512 aSelection->Add(box);
513}
514
515//=======================================================================
516//function : ComputeConeAngle
517//purpose :
518//=======================================================================
519
520void AIS_AngleDimension::ComputeConeAngle(const Handle(Prs3d_Presentation)& aPresentation)
521{
522 if( myCone.IsNull() ) return;
523
524 gp_Pln aPln;
525 gp_Cone aCone;
526 gp_Circ myCircle;
527 gp_Pnt Apex;
528 Handle( Geom_Surface ) aSurf; //a surface from the Face
529 Handle( Geom_OffsetSurface ) aOffsetSurf;
530 Handle( Geom_ConicalSurface ) aConicalSurf;
531 Handle( Geom_SurfaceOfRevolution ) aRevSurf;
532 Handle( Geom_Line ) aLine;
533 BRepAdaptor_Surface tmpSurf(myCone);
534 TopoDS_Face aFace;
535 AIS_KindOfSurface aSurfType;
536 Standard_Real Offset = 0. ;
537 Handle( Standard_Type ) aType;
538
539 Standard_Real maxV = tmpSurf.FirstVParameter();
540 Standard_Real minV = tmpSurf.LastVParameter();
541
542
543 AIS::GetPlaneFromFace( myCone, aPln, aSurf, aSurfType, Offset );
544
545 if ( aSurfType == AIS_KOS_Revolution ) { //surface of revolution
546
547 aRevSurf = Handle( Geom_SurfaceOfRevolution )::DownCast( aSurf );
548 gp_Lin ln( aRevSurf->Axis() );
549 Handle( Geom_Curve ) tmpCrv = aRevSurf->BasisCurve();
550 if ( tmpCrv ->DynamicType() != STANDARD_TYPE(Geom_Line) ) return; //Must be a part of line
551
552 Standard_Real par;
553 gp_Pnt fst = tmpSurf.Value(0., minV);
554 gp_Pnt lst = tmpSurf.Value(0., maxV);
555
556 gp_Vec vec1(fst, lst);
557
558 par = ElCLib::Parameter( ln, fst );
559 gp_Pnt fst2 = ElCLib::Value( par, ln ); //projection fst on ln
560 par = ElCLib::Parameter( ln, lst );
561 gp_Pnt lst2 = ElCLib::Value( par, ln ); //projection lst on ln
562
563 gp_Vec vec2(fst2, lst2);
564
565 // Check if two parts of revolution are parallel ( it's a cylinder ) or normal (it's a circle )
566 if( vec1.IsParallel( vec2,Precision::Angular() ) || vec1.IsNormal( vec2,Precision::Angular() ) ) return;
567
568 gce_MakeCone mkCone(aRevSurf->Axis(), fst, lst);
569 aCone = mkCone.Value();
570 Apex = aCone.Apex();
571 }
572 else {
573 aType = aSurf->DynamicType();
574 if ( aType == STANDARD_TYPE(Geom_OffsetSurface) || Offset > 0.01 ) { //offset surface
575 aOffsetSurf = new Geom_OffsetSurface (aSurf, Offset);
576 aSurf = aOffsetSurf->Surface();
577 BRepBuilderAPI_MakeFace mkFace(aSurf);
578 mkFace.Build();
579 if( !mkFace.IsDone() ) return;
580 tmpSurf.Initialize( mkFace.Face() );
581 }
582
583 aCone = tmpSurf.Cone();
584 aConicalSurf = Handle( Geom_ConicalSurface)::DownCast( aSurf );
585 Apex = aConicalSurf->Apex();
586 }
587
588 Handle(Geom_Curve) aCurve; //A circle where the angle is drawn
589 if ( myAutomaticPosition ) {
590 Standard_Real midV = ( minV + maxV ) / 2.5;
591
592 aCurve = aSurf->VIso(midV);
593 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
594
595 myPosition = ElCLib::Value(Standard_PI/2.0, myCircle);
596 myAutomaticPosition = Standard_False;
597 }
598 else {
599 Standard_Real U, V;
600 ElSLib::Parameters(aCone, myPosition, U, V);
601 aCurve = aSurf->VIso(V);
602 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
603 }
604
605 //__________________________________________________________________
606 aCurve = aSurf->VIso(maxV);
607 gp_Circ CircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
608 aCurve = aSurf->VIso(minV);
609 gp_Circ CircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
610 //__________________________________________________________________
611
612 if( CircVmax.Radius() < CircVmin.Radius() ) {
613 gp_Circ tmpCirc = CircVmax;
614 CircVmax = CircVmin;
615 CircVmin = tmpCirc;
616 }
617
618 DsgPrs_AnglePresentation::Add(aPresentation, myDrawer, myVal,
619 myText, myCircle, myPosition, Apex, CircVmin, CircVmax, myArrowSize);
620// cout << "ComputeConeAngle is over" << endl;
621}
622
623
624//=======================================================================
625//function : ComputeTwoFacesAngle
626//purpose :
627//=======================================================================
628
629void AIS_AngleDimension::ComputeTwoFacesAngle(const Handle(Prs3d_Presentation)& aPresentation)
630{
631 if (myFirstSurfType == AIS_KOS_Plane)
632 ComputeTwoPlanarFacesAngle( aPresentation );
633 else
634 ComputeTwoCurvilinearFacesAngle( aPresentation );
635}
636
637//=======================================================================
638//function : ComputeTwoCurvilinearFacesAngle
639//purpose :
640//=======================================================================
641
642void AIS_AngleDimension::ComputeTwoCurvilinearFacesAngle(const Handle(Prs3d_Presentation)& aPresentation)
643{
644 AIS::ComputeAngleBetweenCurvilinearFaces( TopoDS::Face( myFShape ),
645 TopoDS::Face( mySShape ),
646 myFirstBasisSurf,
647 mySecondBasisSurf,
648 myFirstSurfType,
649 mySecondSurfType,
650 myAxis,
651 myVal,
652 myAutomaticPosition,
653 myPosition,
654 myCenter,
655 myFAttach,
656 mySAttach,
657 myFDir,
658 mySDir,
659 myPlane );
660 if (myAutomaticPosition && myIsSetBndBox)
661 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCenter, myPosition ) ), myBndBox );
662
663 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
664 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
665#ifdef BUC60915
666 if( !myArrowSizeIsDefined ) {
667#endif
668 Standard_Real arrsize = myCenter.Distance( myPosition );
669
670 if ( (myArrowSize-arrsize) < 0.1 ) arrsize = myArrowSize;
671 if (arrsize == 0.) arrsize = 1.;
672#ifdef BUC60915
673 myArrowSize = arrsize;
674 }
675 arr->SetLength( myArrowSize );
676#else
677 arr->SetLength(arrsize);
678#endif
679
680
681 if (myVal <= Precision::Angular() || Abs( PI-myVal ) <= Precision::Angular())
682 DsgPrs_AnglePresentation::Add(aPresentation,
683 myDrawer,
684 myVal,
685 myText,
686 myCenter,
687 myFAttach,
688 mySAttach,
689 myFDir,
690 mySDir,
691 myPlane->Pln().Axis().Direction(),
692 Standard_False, // not plane
693 myAxis,
694 myPosition,
695 mySymbolPrs);
696 else
697 DsgPrs_AnglePresentation::Add(aPresentation,
698 myDrawer,
699 myVal,
700 myText,
701 myCenter,
702 myFAttach,
703 mySAttach,
704 myFDir,
705 mySDir,
706 myFDir ^ mySDir,
707 Standard_False, // not plane
708 myAxis,
709 myPosition,
710 mySymbolPrs);
711}
712
713//=======================================================================
714//function : ComputeTwoPlanarFacesAngle
715//purpose :
716//=======================================================================
717
718void AIS_AngleDimension::ComputeTwoPlanarFacesAngle( const Handle( Prs3d_Presentation )& aPresentation )
719{
720 AIS::ComputeAngleBetweenPlanarFaces( TopoDS::Face( myFShape ),
721 TopoDS::Face( mySShape ),
722 mySecondBasisSurf,
723 myAxis,
724 myVal,
725 myAutomaticPosition,
726 myPosition,
727 myCenter,
728 myFAttach,
729 mySAttach,
730 myFDir,
731 mySDir );
732 if (myAutomaticPosition && myIsSetBndBox)
733 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCenter, myPosition ) ), myBndBox );
734
735 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
736 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
737#ifdef BUC60915
738 if( !myArrowSizeIsDefined ) {
739#endif
740 Standard_Real arrsize = myCenter.Distance( myPosition );
741
742 if ( (myArrowSize-arrsize) < 0.1 ) arrsize = myArrowSize;
743 if (arrsize == 0.) arrsize = 1.;
744#ifdef BUC60915
745 myArrowSize = arrsize;
746 }
747 arr->SetLength( myArrowSize );
748#else
749 arr->SetLength(arrsize);
750#endif
751
752
753 DsgPrs_AnglePresentation::Add(aPresentation,
754 myDrawer,
755 myVal,
756 myText,
757 myCenter,
758 myFAttach,
759 mySAttach,
760 myFDir,
761 mySDir,
762 myAxis.Direction(),
763 Standard_True,
764 myAxis,
765 myPosition,
766 mySymbolPrs);
767
768}
769
770//=======================================================================
771//function : ComputeTwoEdgesAngle
772//purpose :
773//=======================================================================
774
775void AIS_AngleDimension::ComputeTwoEdgesAngle(const Handle(Prs3d_Presentation)& aPresentation)
776{
777 BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
778 BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
779 if ((cu1.GetType() != GeomAbs_Line) || (cu2.GetType() != GeomAbs_Line)) return;
780
781 // current face
782 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
783 TopoDS_Face face(makeface.Face());
784 BRepAdaptor_Surface adp(makeface.Face());
785
786 // 3d lines
787 Handle(Geom_Line) geom_lin1,geom_lin2;
788 gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
789 Standard_Boolean isInfinite1,isInfinite2;
790 Handle(Geom_Curve) extCurv;
791 Standard_Integer copyOfMyExtShape = myExtShape;
792 if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),
793 TopoDS::Edge(mySShape),
794 myExtShape,
795 geom_lin1,
796 geom_lin2,
797 ptat11,
798 ptat12,
799 ptat21,
800 ptat22,
801 extCurv,
802 isInfinite1,
803 isInfinite2,
804 myPlane)) {
805 return;
806 }
807 // Temporary: computation of myVal
808 // myVal = Abs(geom_lin1->Lin().Angle( geom_lin2->Lin())); // Pb avec les angles JPR
809
810 if (copyOfMyExtShape != 0) myExtShape = copyOfMyExtShape;
811
812 // 2d lines => projection of 3d on current plane
813
814//POP pour NT
815 Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(geom_lin1,myPlane->Pln());
816 Handle(Geom2d_Line) lin1_2d = *((Handle(Geom2d_Line)*)& geoC1);
817 Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(geom_lin2,myPlane->Pln());
818 Handle(Geom2d_Line) lin2_2d = *((Handle(Geom2d_Line)*)& geoC2);
819
820#ifdef BUC60915
821 if( !myArrowSizeIsDefined ) {
822#endif
823 Standard_Real arrSize1(myArrowSize),arrSize2(myArrowSize);
824 if (!isInfinite1) arrSize1 = ptat11.Distance(ptat12)/100.;
825 if (!isInfinite2) arrSize2 = ptat21.Distance(ptat22)/100.;
826#ifdef BUC60655
827 myArrowSize = Min(myArrowSize,Max(arrSize1,arrSize2));
828#else
829 myArrowSize = Min(myArrowSize,Min(arrSize1,arrSize2));
830#endif
831#ifdef BUC60915
832 }
833#endif
834
835
836 // Traitement du cas ou les 2 droites sont paralleles
837 if (lin1_2d->Lin2d().Direction()
838 .IsParallel(lin2_2d->Lin2d().Direction(),Precision::Angular())) {
839 ComputeTwoEdgesNullAngle(aPresentation,
840 geom_lin1,
841 geom_lin2,
842 ptat11,ptat12,
843 ptat21,ptat22,
844 isInfinite1,isInfinite2);
845 }
846
847 // Traitement du cas ou les 2 droites ne sont pas paralleles
848 else {
849 ComputeTwoEdgesNotNullAngle(aPresentation,
850 geom_lin1,
851 geom_lin2,
852 ptat11,
853 ptat12,
854 ptat21,
855 ptat22,
856 isInfinite1,isInfinite2);
857 }
858 if ( (myExtShape != 0) && !extCurv.IsNull()) {
859 gp_Pnt pf, pl;
860 if ( myExtShape == 1 ) {
861 if (!isInfinite1) {
862 pf = ptat11;
863 pl = ptat12;
864 }
865 aPresentation->SetInfiniteState(isInfinite1);
866 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(myFShape),geom_lin1,pf,pl);
867 }
868 else {
869 if (!isInfinite2) {
870 pf = ptat21;
871 pl = ptat22;
872 }
873 aPresentation->SetInfiniteState(isInfinite2);
874 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(mySShape),geom_lin2,pf,pl);
875 }
876 }
877}
878
879
880//=======================================================================
881//function : ComputeTwoEdgesNotNullAngle
882//purpose :
883//=======================================================================
884
885void AIS_AngleDimension::ComputeTwoEdgesNotNullAngle(const Handle(Prs3d_Presentation)& aPresentation,
886 const Handle(Geom_Line)& l1,
887 const Handle(Geom_Line)& l2,
888 const gp_Pnt& ptat11,
889 const gp_Pnt& ptat12,
890 const gp_Pnt& ptat21,
891 const gp_Pnt& ptat22,
892 const Standard_Boolean isInfinite1,
893 const Standard_Boolean isInfinite2)
894{
895 // current face
896 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
897 TopoDS_Face face(makeface.Face());
898 BRepAdaptor_Surface adp(makeface.Face());
899 // 2d lines => projection of 3d on current plane
900 Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(l1,myPlane->Pln());
901 const Handle(Geom2d_Line)& l1_2d = *((Handle(Geom2d_Line)*)& geoC1);
902 Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(l2,myPlane->Pln());
903 const Handle(Geom2d_Line)& l2_2d = *((Handle(Geom2d_Line)*)& geoC2);
904
905 //----------------------------------------------------------
906 // Computation of myCenter
907 //----------------------------------------------------------
908 IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),l2_2d->Lin2d());
909 if (!inter.IsDone()) return;
910 if (!inter.NbPoints()) return;
911
912 gp_Pnt2d pint(inter.Point(1).Value());
913 myCenter = adp.Value(pint.X(),pint.Y());
914
915 //----------------------------------------------------------
916 // Computation of the 2 directions
917 //----------------------------------------------------------
918 gp_Dir d1,d2;
919 if (!isInfinite1) {
920 if (myCenter.SquareDistance(ptat11) > myCenter.SquareDistance(ptat12)) d1 = gp_Dir(gp_Vec(myCenter,ptat11));
921 else d1 = gp_Dir(gp_Vec(myCenter,ptat12));
922 }
923 else d1 = l1->Lin().Direction();
924
925 if (!isInfinite2) {
926 if (myCenter.SquareDistance(ptat21) > myCenter.SquareDistance(ptat22)) d2 = gp_Dir(gp_Vec(myCenter,ptat21));
927 else d2 = gp_Dir(gp_Vec(myCenter,ptat22));
928 }
929 else d2 = l2->Lin().Direction();
930 if (!isInfinite1) {
931 Standard_Boolean In1(Standard_False);
932 Standard_Boolean In2(Standard_False);
933 if ( !(Abs(d1.Angle(d2) - Abs(myVal)) <= Precision::Confusion())
934 && (Abs(myVal) < PI) ) {
935 Standard_Real parcent1 = ElCLib::Parameter(l1->Lin(), myCenter);
936 Standard_Real par11 = ElCLib::Parameter(l1->Lin(), ptat11);
937 Standard_Real par12 = ElCLib::Parameter(l1->Lin(), ptat12);
938 if ( par11 < par12) {
939 if ( ( parcent1> par11) && (parcent1< par12)) {
940 In1 = Standard_True;
941 d1.Reverse();
942 }
943 }
944 else {
945 if ( ( parcent1> par12) && (parcent1< par11)) {
946 In1 = Standard_True;
947 d1.Reverse();
948 }
949 }
950 if ( !In1) {
951 In2 = Standard_True;
952 d2.Reverse();
953 }
954 }
955 }
956
957 myFDir = d1;
958 mySDir = d2;
959 gp_Lin theaxis;
960 gp_Lin gpl1 = l1->Lin();
961 gp_Lin gpl2 = l2->Lin();
962 theaxis = gp_Lin(myCenter,myFDir^mySDir);
963
964 if (myVal > PI) {
965 theaxis.Reverse();
966 }
967
968 gp_Pnt curpos;
969 TColStd_Array1OfReal tabdist(1,4);
970 if (!isInfinite1) {
971 tabdist(1) = theaxis.Distance(ptat11);
972 tabdist(2) = theaxis.Distance(ptat12);
973 }
974 else {
975 tabdist(1) = tabdist(2) = 0.;
976 }
977
978 if (!isInfinite2) {
979 tabdist(3) = theaxis.Distance(ptat21);
980 tabdist(4) = theaxis.Distance(ptat22);
981 }
982 else {
983 tabdist(3) = tabdist(4) = 0.;
984 }
985
986 if (myAutomaticPosition) {
987 Standard_Real length_1(RealLast());
988 if (!isInfinite1) length_1 = .75*Abs(tabdist(2)-tabdist(1))+Min(tabdist(1),tabdist(2));
989
990 Standard_Real length_2(RealLast());
991 if (!isInfinite2) length_2 = .75*Abs(tabdist(4)-tabdist(3))+Min(tabdist(3),tabdist(4));
992 Standard_Real theLength(Min(length_1,length_2));
993 if (Precision::IsInfinite(theLength)) theLength = 50.;
994
995 myFAttach = myCenter.Translated(gp_Vec(d1)*theLength);
996 mySAttach = myCenter.Translated(gp_Vec(d2)*theLength);
997
998 if (!isInfinite1) {
999 Standard_Real par_p1_attach(ElCLib::Parameter(gpl1,myFAttach));
1000 Standard_Real par11 = ElCLib::Parameter(gpl1,ptat11);
1001 Standard_Real par12 = ElCLib::Parameter(gpl1,ptat12);
1002 if (par_p1_attach > par11 && par_p1_attach > par12) {
1003 par_p1_attach = Max(par11,par12);
1004 myFAttach = ElCLib::Value(par_p1_attach,gpl1);
1005 }
1006 else if (par_p1_attach < par11 && par_p1_attach < par12) {
1007 par_p1_attach = Min(par11,par12);
1008 myFAttach = ElCLib::Value(par_p1_attach,gpl1);
1009 }
1010 }
1011
1012 if (!isInfinite2) {
1013 Standard_Real par_p2_attach(ElCLib::Parameter(gpl2,mySAttach));
1014 Standard_Real par21 = ElCLib::Parameter(gpl2,ptat21);
1015 Standard_Real par22 = ElCLib::Parameter(gpl2,ptat22);
1016 if (par_p2_attach > par21 && par_p2_attach > par22) {
1017 par_p2_attach = Max(par21,par22);
1018 mySAttach = ElCLib::Value(par_p2_attach,gpl2);
1019 }
1020 else if (par_p2_attach < par21 && par_p2_attach < par22) {
1021 par_p2_attach = Min(par21,par22);
1022 mySAttach = ElCLib::Value(par_p2_attach,gpl2);
1023 }
1024 }
1025 if ( myVal < PI) curpos.SetXYZ(.5*(myFAttach.XYZ()+mySAttach.XYZ()));
1026 else {
1027 curpos.SetXYZ(.5*(myFAttach.XYZ()+mySAttach.XYZ()));
1028 gp_Vec transl(curpos, myCenter);
1029 transl*= 2;
1030 curpos.Translate(transl);
1031 }
1032
1033 gp_Ax2 ax(myCenter,myFDir.Crossed(mySDir),myFDir);
1034 gp_Circ circle(ax,theLength);
1035 Standard_Real par = ElCLib::Parameter(circle,curpos);
1036 curpos = ElCLib::Value(par,circle);
1037
1038 // un petit offset comme LengthDimension
1039 gp_Vec transl(myCenter, curpos);
1040 transl*= 0.3;
1041 curpos.Translate(transl);
1042
1043 if (myIsSetBndBox)
1044 curpos = AIS::TranslatePointToBound( curpos, gp_Dir( gp_Vec( myCenter, curpos ) ), myBndBox );
1045
1046 myPosition = curpos;
1047 myAutomaticPosition = Standard_True;
1048 }
1049
1050 else {
1051 // on projette le point dans le plan
1052 gp_Pnt2d pointOnPln(ProjLib::Project(myPlane->Pln(),myPosition));
1053 myPosition = BRepAdaptor_Surface(BRepBuilderAPI_MakeFace(myPlane->Pln()).Face()).Value(pointOnPln.X(),pointOnPln.Y());
1054 curpos = myPosition;
1055 Standard_Real dist(curpos.Distance(myCenter));
1056 if (dist<=Precision::Confusion()) {
1057 gp_XYZ delta(1.,1.,1.);
1058 curpos.SetXYZ(curpos.XYZ()+delta);
1059 dist = curpos.Distance(myCenter);
1060 }
1061 // Pour savoir si on doit prendre la distance -dist ou non
1062 // il faut savoir si on est dans le secteur oppose a l'angle
1063 // ou non : on est dans le secteur oppose si les coordonnees
1064 // de curpos dans le repere (d1,d2) sont negatives
1065 gp_Ax2 ax(myCenter,myFDir.Crossed(mySDir),myFDir);
1066 gp_Circ circle(ax,dist);
1067#ifdef DEB
1068// gp_Pnt p1(myCenter.Translated(gp_Vec(d1)*dist));
1069#endif
1070 gp_Pnt p2(myCenter.Translated(gp_Vec(d2)*dist));
1071 Standard_Real uc1 = 0;
1072 Standard_Real uc2 = ElCLib::Parameter(circle, p2 );
1073 Standard_Real uco = ElCLib::Parameter(circle, curpos );
1074 Standard_Real udeb = uc1;
1075 Standard_Real ufin = uc2;
1076 if (uco > ufin) {
1077 if (Abs(myVal)<PI) {
1078 // test si uco est dans le secteur oppose
1079 if (uco > udeb+PI && uco < ufin+PI){
1080 dist = -dist;
1081 }
1082 }
1083 }
1084
1085 gp_Pnt p1_attach(myCenter.Translated(gp_Vec(d1)*dist));
1086 gp_Pnt p2_attach(myCenter.Translated(gp_Vec(d2)*dist));
1087
1088 if (!isInfinite1) {
1089 Standard_Real par_p1_attach(ElCLib::Parameter(gpl1,p1_attach));
1090 Standard_Real par11 = ElCLib::Parameter(gpl1,ptat11);
1091 Standard_Real par12 = ElCLib::Parameter(gpl1,ptat12);
1092 if (par_p1_attach > par11 && par_p1_attach > par12) {
1093 par_p1_attach = Max(par11,par12);
1094 p1_attach = ElCLib::Value(par_p1_attach,gpl1);
1095 }
1096 else if (par_p1_attach < par11 && par_p1_attach < par12) {
1097 par_p1_attach = Min(par11,par12);
1098 p1_attach = ElCLib::Value(par_p1_attach,gpl1);
1099 }
1100 }
1101 myFAttach = p1_attach;
1102
1103 if (!isInfinite2) {
1104 Standard_Real par_p2_attach(ElCLib::Parameter(gpl2,p2_attach));
1105 Standard_Real par21 = ElCLib::Parameter(gpl2,ptat21);
1106 Standard_Real par22 = ElCLib::Parameter(gpl2,ptat22);
1107 if (par_p2_attach > par21 && par_p2_attach > par22) {
1108 par_p2_attach = Max(par21,par22);
1109 p2_attach = ElCLib::Value(par_p2_attach,gpl2);
1110 }
1111 else if (par_p2_attach < par21 && par_p2_attach < par22) {
1112 par_p2_attach = Min(par21,par22);
1113 p2_attach = ElCLib::Value(par_p2_attach,gpl2);
1114 }
1115 }
1116 mySAttach = p2_attach;
1117 }
1118 myAxis = theaxis.Position();
1119
1120 //--------------------------------------------------------
1121 // Computation of the presentation
1122 //--------------------------------------------------------
1123 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
1124 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
1125
1126 arr->SetLength(myArrowSize);
1127
1128 DsgPrs_AnglePresentation::Add(aPresentation,
1129 myDrawer,
1130 myVal,
1131 myText,
1132 myCenter,
1133 myFAttach,
1134 mySAttach,
1135 myFDir,
1136 mySDir,
1137 curpos,
1138 mySymbolPrs);
1139}
1140
1141
1142
1143//=======================================================================
1144//function : ComputeTwoEdgesNullAngle
1145//purpose : compute the presentation of a angle dimension if it's null.
1146// -> the aim of the computation is to have a constant radius
1147// during the dimension moving : the radius is independant
1148// of the cursor position, it's equal to a arbitrary value
1149//=======================================================================
1150
1151void AIS_AngleDimension::ComputeTwoEdgesNullAngle(const Handle(Prs3d_Presentation)& aPresentation,
1152 const Handle(Geom_Line)& l1,
1153 const Handle(Geom_Line)& l2,
1154 const gp_Pnt& ptat11,
1155 const gp_Pnt& ptat12,
1156 const gp_Pnt& ptat21,
1157 const gp_Pnt& ptat22,
1158 const Standard_Boolean isInfinite1,
1159 const Standard_Boolean isInfinite2)
1160{
1161 // current face
1162 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
1163 TopoDS_Face face(makeface.Face());
1164 BRepAdaptor_Surface adp(makeface.Face());
1165 // 2d lines => projection of 3d on current plane
1166 Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(l1,myPlane->Pln());
1167 Handle(Geom2d_Line) l1_2d = *((Handle(Geom2d_Line)*)& geoC1);
1168 Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(l2,myPlane->Pln());
1169 Handle(Geom2d_Line) l2_2d = *((Handle(Geom2d_Line)*)& geoC2);
1170
1171 gp_Lin gpl1 = l1->Lin();
1172 gp_Lin gpl2 = l2->Lin();
1173
1174 //------------------------------------------------------------
1175 // Calcul de myCenter
1176 // -> Point situe sur la ligne mediane des 2 droites,
1177 // calcule comme etant le milieu des 2 points les plus
1178 // proches de chaque droite.
1179 //-----------------------------------------------------------
1180 // theLength : rayon du futur cercle
1181 Standard_Real theLength = gpl1.Distance(gpl2.Location());
1182 // traitement du cas particulier ou les 2 droites sont confondues
1183 Standard_Boolean SameLines(Standard_False);
1184 if ( theLength <= Precision::Confusion()) {
1185 SameLines = Standard_True;
1186 if (!isInfinite1) {
1187 if (!isInfinite2) theLength = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1188 else theLength = 0.75*ptat11.Distance(ptat12);
1189 }
1190 else {
1191 if (!isInfinite2) theLength = 0.75*ptat21.Distance(ptat22);
1192 else theLength = 50.;
1193 }
1194 }
1195 else theLength = theLength*8/10;
1196
1197 gp_Pnt pmin1 ,pmin2;
1198 if (!isInfinite1 && !isInfinite2) {
1199 pmin1 = ptat11; pmin2 = ptat21;
1200 Standard_Real dis = ptat11.Distance(ptat21);
1201 Standard_Real dis2 = ptat11.Distance(ptat22);
1202 if ( dis2 < dis) {
1203 pmin1 = ptat11;
1204 pmin2 = ptat22;
1205 dis = dis2;
1206 }
1207 dis2 = ptat12.Distance(ptat22);
1208 if ( dis2 < dis) {
1209 pmin1 = ptat12;
1210 pmin2 = ptat22;
1211 dis = dis2;
1212 }
1213 dis2 = ptat12.Distance(ptat21);
1214 if ( dis2 < dis) {
1215 pmin1 = ptat12;
1216 pmin2 = ptat21;
1217 dis = dis2;
1218 }
1219 myCenter.SetXYZ( (pmin1.XYZ() + pmin2.XYZ()) / 2. );
1220 }
1221 else {
1222 gp_Pnt pntOnl1 = gpl1.Location();
1223 gp_Pnt pntOnl2 = ElCLib::Value(ElCLib::Parameter(gpl1,pntOnl1),gpl2);
1224 myCenter.SetXYZ( (pntOnl1.XYZ() + pntOnl2.XYZ()) / 2. );
1225 }
1226
1227
1228 // directions
1229 gp_Dir d1,d2;
1230 if (!isInfinite1) {
1231 if (myCenter.SquareDistance(ptat11) > myCenter.SquareDistance(ptat12)) d1 = gp_Dir(gp_Vec(myCenter,ptat11));
1232 else d1 = gp_Dir(gp_Vec(myCenter,ptat12));
1233 }
1234 else d1 = gpl1.Direction();
1235
1236 if (!isInfinite2) {
1237 if (myCenter.SquareDistance(ptat21) > myCenter.SquareDistance(ptat22)) d2 = gp_Dir(gp_Vec(myCenter,ptat21));
1238 else d2 = gp_Dir(gp_Vec(myCenter,ptat22));
1239 }
1240 else d2 = gpl2.Direction();
1241
1242 gp_Dir theaxis;
1243 if ( SameLines ) theaxis = myPlane->Pln().Axis().Direction();
1244 else {
1245 theaxis = gp_Dir(d1^d2);
1246 gp_Vec V1(d1); gp_Vec V2(d2);
1247 if ( V1.CrossMagnitude(V2) < 0 ) theaxis.Reverse();
1248 }
1249
1250 gp_Pnt curpos; // position du curseur
1251 TColStd_Array1OfReal tabdist(1,4);
1252 gp_Pnt P1, P2; // points d'intersection du cercle avec les 2 droites
1253
1254 if (myAutomaticPosition) {
1255 if (!isInfinite1) {
1256 tabdist(1) = myCenter.Distance(ptat11);
1257 tabdist(2) = myCenter.Distance(ptat12);
1258 }
1259 else {
1260 tabdist(1) = tabdist(2) = 0.;
1261 }
1262 if (!isInfinite2) {
1263 tabdist(3) = myCenter.Distance(ptat21);
1264 tabdist(4) = myCenter.Distance(ptat22);
1265 }
1266 else {
1267 tabdist(3) = tabdist(4) = 0.;
1268 }
1269 if ( SameLines ) {
1270 Standard_Real dist1(RealLast());
1271 if (!isInfinite1) dist1 = Max(tabdist(1),tabdist(2));
1272 Standard_Real dist2(RealLast());
1273 if (!isInfinite2) dist2 = Max(tabdist(3),tabdist(4));
1274
1275 myFAttach = myCenter;
1276 mySAttach = myCenter;
1277 P1 = myFAttach;
1278 P2 = mySAttach;
1279
1280 myCenter.Translate(gp_Vec(d1)*theLength);
1281
1282 // calcul des points d'attache de la cote
1283 // -> ils sont != des points d'intersection si les
1284 // intersection sont en dehors des limites des edges
1285 Standard_Real pparam = ElCLib::Parameter(gpl1,myFAttach);
1286 Standard_Real pparam1 = ElCLib::Parameter(gpl1,ptat11);
1287 Standard_Real pparam2 = ElCLib::Parameter(gpl1,ptat12);
1288 if (!isInfinite1) {
1289 if ( pparam1 < pparam2 ) {
1290 if ( pparam < pparam1 ) myFAttach = ptat11;
1291 else if ( pparam > pparam2) myFAttach = ptat12;
1292 }
1293 else {
1294 if ( pparam < pparam2) myFAttach = ptat12;
1295 else if ( pparam > pparam1) myFAttach = ptat11;
1296 }
1297 }
1298 if (!isInfinite2) {
1299 pparam = ElCLib::Parameter(gpl2,myFAttach);
1300 pparam1 = ElCLib::Parameter(gpl2,ptat21);
1301 pparam2 = ElCLib::Parameter(gpl2,ptat22);
1302 if ( pparam1 < pparam2 ) {
1303 if ( pparam < pparam1 ) mySAttach = ptat21;
1304 else if ( pparam > pparam2) mySAttach = ptat22;
1305 }
1306 else {
1307 if ( pparam < pparam2) mySAttach = ptat22;
1308 else if ( pparam > pparam1) mySAttach = ptat21;
1309 }
1310 }
1311 }
1312 // Case of disconneted lines
1313 else {
1314 gp_Ax2 AX(myCenter,theaxis,d1);
1315 Handle(Geom_Circle) circle = new Geom_Circle(AX,theLength);
1316 Handle(Geom2d_Curve) geoCurve = GeomAPI::To2d(circle,myPlane->Pln());
1317 Handle(Geom2d_Circle) c2d = *((Handle(Geom2d_Circle)*)& geoCurve);
1318 // calcul du point d'intersection du cercle avec l1
1319 Standard_Real pparam; // parametre du point d'intersection sur l1
1320 IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),c2d->Circ2d());
1321 gp_Pnt2d pint1(inter.Point(1).Value());
1322 gp_Pnt2d pint2(inter.Point(2).Value());
1323
1324 gp_Pnt Int1 = adp.Value(pint1.X(),pint1.Y());
1325 gp_Pnt Int2 = adp.Value(pint2.X(),pint2.Y());
1326 gp_Dir I1I2(gp_Vec(Int1,Int2));
1327 if ( d1*I1I2 > 0 ) {
1328 myFAttach = Int2;
1329 pparam = inter.Point(2).ParamOnFirst();
1330 }
1331 else {
1332 myFAttach = Int1;
1333 pparam = inter.Point(1).ParamOnFirst();
1334 }
1335 P1 = myFAttach;
1336
1337 Standard_Real pparam1;
1338 Standard_Real pparam2;
1339 if (!isInfinite1) {
1340 pparam1 = ElCLib::Parameter(gpl1,ptat11);
1341 pparam2 = ElCLib::Parameter(gpl1,ptat12);
1342 if ( pparam1 < pparam2 ) {
1343 if ( pparam < pparam1 ) myFAttach = ptat11;
1344 else if ( pparam > pparam2) myFAttach = ptat12;
1345 }
1346 else {
1347 if ( pparam < pparam2) myFAttach = ptat12;
1348 else if ( pparam > pparam1) myFAttach = ptat11;
1349 }
1350 }
1351 pparam = ElCLib::Parameter(gpl2,P1);
1352 mySAttach = ElCLib::Value(pparam, gpl2);
1353 P2 = mySAttach;
1354
1355 if (!isInfinite2) {
1356 pparam1 = ElCLib::Parameter(gpl2,ptat21);
1357 pparam2 = ElCLib::Parameter(gpl2,ptat22);
1358 if ( pparam1 < pparam2 ) {
1359 if ( pparam < pparam1 ) mySAttach = ptat21;
1360 else if ( pparam > pparam2) mySAttach = ptat22;
1361 }
1362 else {
1363 if ( pparam < pparam2) mySAttach = ptat22;
1364 else if ( pparam > pparam1) mySAttach = ptat21;
1365 }
1366 }
1367 }
1368 curpos.SetXYZ(.5*(P1.XYZ()+P2.XYZ()));
1369
1370 gp_Ax2 ax(myCenter,theaxis,d1);
1371 gp_Circ circle(ax,theLength);
1372 Standard_Real par = ElCLib::Parameter(circle,curpos);
1373 curpos = ElCLib::Value(par,circle);
1374
1375 if (myIsSetBndBox)
1376 curpos = AIS::TranslatePointToBound( curpos, gp_Dir( gp_Vec( myCenter, curpos ) ), myBndBox );
1377 myPosition =curpos;
1378 myAutomaticPosition = Standard_True;
1379 }
1380 else {
1381 curpos = myPosition;
1382 gp_Lin Media(myCenter, gpl1.Direction());
1383 Standard_Real pcurpos = ElCLib::Parameter(Media, curpos);
1384 myCenter = ElCLib::Value(pcurpos, Media);
1385 // on translate le centre de facon a avoir un rayon constant!
1386 myCenter.Translate(-theLength*gp_Vec(gpl1.Direction()));
1387 gp_Ax2 AX(myCenter,theaxis,gpl1.Direction());
1388 Handle(Geom_Circle) circle = new Geom_Circle(AX,theLength);
1389
1390 // remise a jour de curpos
1391 pcurpos = ElCLib::Parameter(circle->Circ(), curpos);
1392 curpos = ElCLib::Value(pcurpos, circle->Circ());
1393
1394 Handle(Geom2d_Curve) geoCurve = GeomAPI::To2d(circle,myPlane->Pln());
1395 Handle(Geom2d_Circle) c2d = *((Handle(Geom2d_Circle)*)& geoCurve);
1396 // calcul du point d'intersection du cercle avec l1
1397 IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),c2d->Circ2d());
1398 gp_Pnt2d pint1(inter.Point(1).Value());
1399 gp_Pnt2d pint2(inter.Point(2).Value());
1400 gp_Pnt Int1 = adp.Value(pint1.X(),pint1.Y());
1401 gp_Pnt Int2 = adp.Value(pint2.X(),pint2.Y());
1402 if ( curpos.SquareDistance(Int1) < curpos.SquareDistance(Int2)) myFAttach = Int1;
1403 else myFAttach = Int2;
1404 P1 = myFAttach;
1405
1406 // calcul du point d'intersection du cercle avec l2
1407 // -> c'est la projection car le cercle a son centre
1408 // au milieu de l1 et l2
1409 Standard_Real pparam = ElCLib::Parameter(gpl2,myFAttach);
1410 mySAttach = ElCLib::Value(pparam, gpl2);
1411
1412 P2 = mySAttach;
1413
1414 Standard_Real par_attach(ElCLib::Parameter(gpl1,myFAttach));
1415 Standard_Real par1,par2;
1416 if (!isInfinite1) {
1417 par1 = ElCLib::Parameter(gpl1,ptat11);
1418 par2 = ElCLib::Parameter(gpl1,ptat12);
1419 if (par1 < par2) {
1420 if ( par_attach < par1 ) myFAttach = ptat11;
1421 else if ( par_attach > par2) myFAttach = ptat12;
1422 }
1423 else {
1424 if ( par_attach < par2 ) myFAttach = ptat12;
1425 else if ( par_attach > par1) myFAttach = ptat11;
1426 }
1427 }
1428 par_attach = ElCLib::Parameter(gpl2,mySAttach);
1429 if (!isInfinite2) {
1430 par1 = ElCLib::Parameter(gpl2,ptat21);
1431 par2 = ElCLib::Parameter(gpl2,ptat22);
1432 if (par1 < par2) {
1433 if ( par_attach < par1 ) mySAttach = ptat21;
1434 else if ( par_attach > par2) mySAttach = ptat22;
1435 }
1436 else {
1437 if ( par_attach < par2 ) mySAttach = ptat22;
1438 else if ( par_attach > par1) mySAttach = ptat21;
1439 }
1440 }
1441 }
1442
1443 myFDir = gp_Dir(gp_Vec(myCenter,P1));
1444 mySDir = gp_Dir(gp_Vec(myCenter,P2));
1445
1446 //--------------------------------------------------------
1447 // Computation of the presentation
1448 //--------------------------------------------------------
1449 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
1450 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
1451
1452 arr->SetLength(myArrowSize);
1453
1454 if (SameLines)
1455 DsgPrs_AnglePresentation::Add(aPresentation,
1456 myDrawer,
1457 myVal,
1458 myText,
1459 myCenter,
1460 myFAttach,
1461 mySAttach,
1462 myFDir,
1463 mySDir,
1464 theaxis,
1465 Standard_True,
1466 myAxis,
1467 curpos,
1468 DsgPrs_AS_NONE);
1469 else
1470 DsgPrs_AnglePresentation::Add(aPresentation,
1471 myDrawer,
1472 myVal,
1473 myText,
1474 myCenter,
1475 myFAttach,
1476 mySAttach,
1477 myFDir,
1478 mySDir,
1479 curpos,
1480 mySymbolPrs);
1481}
1482
1483
1484//=======================================================================
1485//function : Compute3DSelection
1486// purpose : compute the zones of selection for an angle dimension
1487// between 2 faces
1488//=======================================================================
1489
1490void AIS_AngleDimension::Compute3DSelection( const Handle( SelectMgr_Selection )& aSelection )
1491{
1492 gp_Circ AngleCirc, AttachCirc;
1493 Standard_Real FirstParAngleCirc, LastParAngleCirc, FirstParAttachCirc, LastParAttachCirc;
1494 gp_Pnt EndOfArrow1, EndOfArrow2, ProjAttachPoint2;
1495 gp_Dir DirOfArrow1, DirOfArrow2;
1496 gp_Dir axisdir = (myVal <= Precision::Angular() || Abs( PI-myVal ) <= Precision::Angular())?
1497 myPlane->Pln().Axis().Direction() : (myFDir ^ mySDir);
1498 Standard_Boolean isPlane = (myFirstSurfType == AIS_KOS_Plane)? Standard_True : Standard_False;
1499
1500 Standard_Real ArrowLength = myDrawer->AngleAspect()->ArrowAspect()->Length();
1501 DsgPrs::ComputeFacesAnglePresentation( ArrowLength,
1502 myVal,
1503 myCenter,
1504 myFAttach,
1505 mySAttach,
1506 myFDir,
1507 mySDir,
1508 axisdir,
1509 isPlane,
1510 myAxis,
1511 myPosition,
1512 AngleCirc,
1513 FirstParAngleCirc,
1514 LastParAngleCirc,
1515 EndOfArrow1,
1516 EndOfArrow2,
1517 DirOfArrow1,
1518 DirOfArrow2,
1519 ProjAttachPoint2,
1520 AttachCirc,
1521 FirstParAttachCirc,
1522 LastParAttachCirc );
1523
1524 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
1525 Handle( Select3D_SensitiveSegment ) seg;
1526 Handle( Geom_TrimmedCurve ) curve;
1527 Handle( Select3D_SensitiveCurve ) SensCurve;
1528
1529 // Angle's arc or line
1530 if (myVal > Precision::Angular() && Abs( PI-myVal ) > Precision::Angular())
1531 {
1532 curve = new Geom_TrimmedCurve( new Geom_Circle( AngleCirc ), FirstParAngleCirc, LastParAngleCirc );
1533 SensCurve = new Select3D_SensitiveCurve( own, curve );
1534 aSelection->Add( SensCurve );
1535 }
1536 else // angle's line
1537 {
1538 gp_Vec ArrowVec( DirOfArrow1 );
1539 ArrowVec *= ArrowLength;
1540 gp_Pnt FirstPoint, LastPoint;
1541
1542 if (myPosition.Distance( EndOfArrow1 ) > ArrowLength)
1543 {
1544 FirstPoint = myPosition;
1545 LastPoint = EndOfArrow1.Translated( ArrowVec );
1546 if (myPosition.SquareDistance( LastPoint ) < myPosition.SquareDistance( EndOfArrow1 ))
1547 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1548 }
1549 else
1550 {
1551 FirstPoint = EndOfArrow1.Translated( ArrowVec );
1552 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1553 }
1554 seg = new Select3D_SensitiveSegment( own, FirstPoint, LastPoint );
1555 aSelection->Add( seg );
1556 }
1557
1558 if (! myFAttach.IsEqual( EndOfArrow1, Precision::Confusion() ))
1559 {
1560 seg = new Select3D_SensitiveSegment( own, myFAttach, EndOfArrow1 );
1561 aSelection->Add( seg );
1562 }
1563 if (! ProjAttachPoint2.IsEqual( EndOfArrow2, Precision::Confusion() ))
1564 {
1565 seg = new Select3D_SensitiveSegment( own, ProjAttachPoint2, EndOfArrow2 );
1566 aSelection->Add( seg );
1567 }
1568
1569 // Line or arc from mySAttach to its "projection"
1570 if (! mySAttach.IsEqual( ProjAttachPoint2, Precision::Confusion() ))
1571 {
1572 if (isPlane)
1573 {
1574 seg = new Select3D_SensitiveSegment( own, mySAttach, ProjAttachPoint2 );
1575 aSelection->Add( seg );
1576 }
1577 else
1578 {
1579 curve = new Geom_TrimmedCurve( new Geom_Circle( AttachCirc ),
1580 FirstParAttachCirc,
1581 LastParAttachCirc );
1582 SensCurve = new Select3D_SensitiveCurve( own, curve );
1583 aSelection->Add( SensCurve );
1584 }
1585 }
1586
1587 // Text
1588 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
1589 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
1590 myPosition.X(),
1591 myPosition.Y(),
1592 myPosition.Z(),
1593 myPosition.X() + size,
1594 myPosition.Y() + size,
1595 myPosition.Z() + size);
1596 aSelection->Add(box);
1597}
1598
1599//=======================================================================
1600//function : Compute2DSelection
1601//purpose : calcule les zones de selection sur une cote d'angle entre 2
1602// edges
1603// Traitement particulier pour les angles nuls!
1604//=======================================================================
1605
1606void AIS_AngleDimension::Compute2DSelection(const Handle(SelectMgr_Selection)& aSelection)
1607{
1608 BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
1609 BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
1610
1611 gp_Lin l1(cu1.Line());
1612 gp_Lin l2(cu2.Line());
1613
1614 // it is patch!
1615 if (Abs( myVal ) <= Precision::Angular() || Abs( PI - myVal ) <= Precision::Angular())
1616/*
1617 //---------------------------------------------------------
1618 // Cas de droites paralleles ( <=> angle nul a PI pres)
1619 if ((Abs(l1.Angle(l2)) < Precision::Angular()) ||
1620 (Abs((l1.Angle(l2) - PI)) < Precision::Angular()) )
1621*/
1622 {
1623
1624 Standard_Real distLL= l1.Distance(l2);
1625 if ( Abs(distLL) <= Precision::Confusion() ) {
1626 gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
1627 gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
1628 gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
1629 gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
1630 distLL = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1631 ComputeNull2DSelection(aSelection, distLL);
1632 }
1633 else {
1634 ComputeNull2DSelection(aSelection, distLL*8/10);
1635 }
1636 }
1637
1638 //----------------------------------------------------------
1639 // Cas classique ( angle != 0 )
1640 else {
1641
1642 if (myFDir.IsParallel(mySDir,Precision::Angular())) {
1643 Standard_Real distLL= l1.Distance(l2);
1644 if ( Abs(distLL) <= Precision::Confusion() ) {
1645 gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
1646 gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
1647 gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
1648 gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
1649 distLL = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1650 ComputeNull2DSelection(aSelection, distLL*8/10);
1651 }
1652 }
1653 else {
1654 gp_Dir Norm = myFDir.Crossed(mySDir);
1655
1656 gp_Ax2 ax(myCenter,Norm,myFDir);
1657 gp_Circ cer(ax,myCenter.Distance(myPosition));
1658 gp_Vec vec1(myFDir);
1659
1660 Standard_Boolean nullrad(Standard_False);
1661 if (cer.Radius() == 0.) {
1662 cer.SetRadius(1.);
1663 nullrad = Standard_True;
1664 }
1665 vec1 *= cer.Radius();
1666 gp_Pnt p1 = myCenter.Translated(vec1);
1667 gp_Vec vec2(mySDir);
1668 vec2 *= cer.Radius();
1669 gp_Pnt p2 = myCenter.Translated(vec2);
1670
1671 Standard_Real uc1 = 0.;
1672 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
1673 Standard_Real uco;
1674 if (nullrad) uco = ElCLib::Parameter(cer,p1);
1675 else uco = ElCLib::Parameter(cer,myPosition);
1676
1677 Standard_Real udeb = uc1;
1678 Standard_Real ufin = uc2;
1679
1680 if (uco > ufin) {
1681 if (Abs(myVal)<PI) {
1682 // test si uco est dans le secteur oppose
1683 if (uco > udeb+PI && uco < ufin+PI){
1684 udeb = udeb + PI;
1685 ufin = ufin + PI;
1686 uc1 = udeb;
1687 uc2 = ufin;
1688 }
1689 }
1690 }
1691 if (uco > ufin) {
1692 if ((uco-uc2) < (uc1-uco+(2*PI))) ufin = uco;
1693 else udeb = uco - 2*PI;
1694 }
1695 p1 = ElCLib::Value(udeb,cer);
1696 p2 = ElCLib::Value(ufin,cer);
1697
1698 //Creation des 2 owners pour chaque partie de la fleche
1699 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1700 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1701 if (myExtShape != 0) {
1702 if (myExtShape == 1) {
1703 own1->SetShape(mySShape);
1704 own2->SetShape(mySShape);
1705 }
1706 else {
1707 own1->SetShape(myFShape);
1708 own2->SetShape(myFShape);
1709 }
1710 }
1711 else {
1712 own1->SetShape(myFShape);
1713 own2->SetShape(mySShape);
1714 }
1715
1716 Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
1717
1718 Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
1719 Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
1720
1721 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
1722 aSelection->Add(scurv);
1723 scurv = new Select3D_SensitiveCurve(own2,thecu2);
1724 aSelection->Add(scurv);
1725
1726 Handle(Select3D_SensitiveSegment) seg;
1727 if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
1728 seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
1729 aSelection->Add(seg);
1730 }
1731 if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
1732 seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
1733 aSelection->Add(seg);
1734 }
1735 }
1736 }
1737
1738}
1739//=======================================================================
1740//function : Compute2DNullSelection
1741//purpose : for dimension of null angle
1742//=======================================================================
1743
1744void AIS_AngleDimension::ComputeNull2DSelection(
1745 const Handle(SelectMgr_Selection)& aSelection,
1746 const Standard_Real distLL)
1747{
1748 gp_Dir Norm;
1749 if ( myFDir.IsParallel(mySDir, Precision::Angular()) ) {
1750 Norm = myPlane->Pln().Axis().Direction();
1751 }
1752 else
1753 Norm = myFDir.Crossed(mySDir);
1754
1755 gp_Ax2 ax(myCenter,Norm,myFDir);
1756 gp_Circ cer(ax,distLL);
1757
1758 gp_Vec vec1(myFDir);
1759 vec1 *= cer.Radius();
1760 gp_Pnt p1 = myCenter.Translated(vec1);
1761 gp_Vec vec2(mySDir);
1762 vec2 *= cer.Radius();
1763 gp_Pnt p2 = myCenter.Translated(vec2);
1764
1765 // calcul de parametres de debut et de fin des extremites de l'arc
1766 Standard_Real uc1 = 0.;
1767 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
1768 Standard_Real uco = ElCLib::Parameter(cer,myPosition);
1769
1770 Standard_Real udeb = uc1;
1771 Standard_Real ufin = uc2;
1772
1773 if (uco > ufin) {
1774 if (Abs(myVal)<PI) {
1775 // test si uco est dans le secteur oppose
1776 if (uco > udeb+PI && uco < ufin+PI){
1777 udeb = udeb + PI;
1778 ufin = ufin + PI;
1779 uc1 = udeb;
1780 uc2 = ufin;
1781 }
1782 }
1783 }
1784
1785 if (uco > ufin) {
1786 if ((uco-uc2) < (uc1-uco+(2*PI))) {
1787 ufin = uco;
1788 }
1789 else {
1790 udeb = uco - 2*PI;
1791 }
1792 }
1793
1794 //Creation des 2 owners pour chaque partie de la fleche
1795 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1796 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1797 if (myExtShape != 0) {
1798 if (myExtShape == 1) {
1799 own1->SetShape(mySShape);
1800 own2->SetShape(mySShape);
1801 }
1802 else {
1803 own1->SetShape(myFShape);
1804 own2->SetShape(myFShape);
1805 }
1806 }
1807 else {
1808 own1->SetShape(myFShape);
1809 own2->SetShape(mySShape);
1810 }
1811
1812 Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
1813
1814 if ( udeb != ufin ) {
1815 Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
1816 Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
1817
1818 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
1819 aSelection->Add(scurv);
1820 scurv = new Select3D_SensitiveCurve(own2,thecu2);
1821 aSelection->Add(scurv);
1822 }
1823 else {
1824 // on trace un bout de segment pour permettre la selection
1825 gp_Vec VTrans(myFDir.Crossed(Norm));
1826 Handle(Select3D_SensitiveSegment) seg1;
1827 seg1 = new Select3D_SensitiveSegment(own1,
1828 p1,
1829 p1.Translated( VTrans*distLL/10 ) );
1830 aSelection->Add(seg1);
1831 seg1 = new Select3D_SensitiveSegment(own2,
1832 p2,
1833 p2.Translated(-VTrans*distLL/10 ) );
1834 aSelection->Add(seg1);
1835 }
1836
1837 Handle(Select3D_SensitiveSegment) seg;
1838 if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
1839 seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
1840 aSelection->Add(seg);
1841 }
1842
1843 if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
1844 seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
1845 aSelection->Add(seg);
1846 }
1847}
1848
1849
1850//=======================================================================
1851//function : ComputeConeAngleSelection
1852//purpose : for cone angle
1853//=======================================================================
1854void AIS_AngleDimension::ComputeConeAngleSelection(const Handle(SelectMgr_Selection)& aSelection)
1855{
1856 if( myCone.IsNull() ) return;
1857
1858
1859 Handle( SelectMgr_EntityOwner ) owner = new SelectMgr_EntityOwner( this, 7 );
1860 Handle( Select3D_SensitiveSegment ) seg;
1861
1862 gp_Pln aPln;
1863 gp_Cone aCone;
1864 gp_Circ myCircle;
1865 gp_Pnt Apex;
1866 Handle( Geom_Surface ) aSurf; //a surface from the Face
1867 Handle( Geom_OffsetSurface ) aOffsetSurf;
1868 Handle( Geom_ConicalSurface ) aConicalSurf;
1869 Handle( Geom_SurfaceOfRevolution ) aRevSurf;
1870 Handle( Geom_Line ) aLine;
1871 BRepAdaptor_Surface tmpSurf(myCone);
1872 TopoDS_Face aFace;
1873 AIS_KindOfSurface aSurfType;
1874 Standard_Real Offset = 0. ;
1875 Handle( Standard_Type ) aType;
1876
1877 Standard_Real maxV = tmpSurf.FirstVParameter();
1878 Standard_Real minV = tmpSurf.LastVParameter();
1879
1880 AIS::GetPlaneFromFace( myCone, aPln, aSurf, aSurfType, Offset );
1881
1882 if ( aSurfType == AIS_KOS_Revolution ) { //surface of revolution
1883
1884 aRevSurf = Handle( Geom_SurfaceOfRevolution )::DownCast( aSurf );
1885 gp_Lin ln( aRevSurf->Axis() );
1886 Handle( Geom_Curve ) tmpCrv = aRevSurf->BasisCurve();
1887 if ( tmpCrv ->DynamicType() != STANDARD_TYPE(Geom_Line) ) return; //Must be a part of line
1888
1889 Standard_Real par;
1890 gp_Pnt fst = tmpSurf.Value(0., minV);
1891 gp_Pnt lst = tmpSurf.Value(0., maxV);
1892
1893 gp_Vec vec1(fst, lst);
1894
1895 par = ElCLib::Parameter( ln, fst );
1896 gp_Pnt fst2 = ElCLib::Value( par, ln ); //projection fst on ln
1897 par = ElCLib::Parameter( ln, lst );
1898 gp_Pnt lst2 = ElCLib::Value( par, ln ); //projection lst on ln
1899
1900 gp_Vec vec2(fst2, lst2);
1901
1902 // Check if two parts of revolution are parallel ( it's a cylinder ) or normal (it's a circle )
1903 if( vec1.IsParallel( vec2,Precision::Angular() ) || vec1.IsNormal( vec2,Precision::Angular() ) ) return;
1904
1905 gce_MakeCone mkCone(aRevSurf->Axis(), fst, lst);
1906 aCone = mkCone.Value();
1907 Apex = aCone.Apex();
1908 }
1909 else {
1910 aType = aSurf->DynamicType();
1911 if ( aType == STANDARD_TYPE(Geom_OffsetSurface) || Offset > 0.01 ) { //offset surface
1912 aOffsetSurf = new Geom_OffsetSurface (aSurf, Offset);
1913 aSurf = aOffsetSurf->Surface();
1914 BRepBuilderAPI_MakeFace mkFace(aSurf);
1915 mkFace.Build();
1916 if( !mkFace.IsDone() ) return;
1917 tmpSurf.Initialize( mkFace.Face() );
1918 }
1919
1920 aCone = tmpSurf.Cone();
1921 aConicalSurf = Handle( Geom_ConicalSurface)::DownCast( aSurf );
1922 Apex = aConicalSurf->Apex();
1923 }
1924
1925 Handle(Geom_Curve) aCurve; //A circle where the angle is drawn
1926
1927 if ( myAutomaticPosition ) {
1928 Standard_Real midV = ( minV + maxV ) / 2.5;
1929
1930 aCurve = aSurf->VIso(midV);
1931 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1932
1933 myPosition = ElCLib::Value(Standard_PI / 2.0, myCircle);
1934 myAutomaticPosition = Standard_False;
1935 }
1936 else {
1937 Standard_Real U, V;
1938 ElSLib::Parameters(aCone, myPosition, U, V);
1939 aCurve = aSurf->VIso(V);
1940 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1941 }
1942 //__________________________________________________________________
1943 aCurve = aSurf->VIso(maxV);
1944 gp_Circ CircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1945 aCurve = aSurf->VIso(minV);
1946 gp_Circ CircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1947 //__________________________________________________________________
1948
1949 if( CircVmax.Radius() < CircVmin.Radius() ) {
1950 gp_Circ tmpCirc = CircVmax;
1951 CircVmax = CircVmin;
1952 CircVmin = tmpCirc;
1953 }
1954
1955 Standard_Boolean IsArrowOut = Standard_True; //Is arrows inside or outside of the cone
1956 //Standard_Real PntOnMainAxis = 0; //Is projection of aPosition inside of the cone = 0, above = 1, or below = -1
1957 Standard_Boolean IsConeTrimmed = Standard_False;
1958
1959 if( CircVmin.Radius() > 0.01 ) IsConeTrimmed = Standard_True;
1960
1961 gp_Pnt AttachmentPnt;
1962 gp_Pnt OppositePnt;
1963 gp_Pnt aPnt, tmpPnt;
1964 Quantity_Length X,Y,Z;
1965
1966 Standard_Real param = ElCLib::Parameter(myCircle, myPosition);
1967
1968 aPnt = Apex;
1969 gp_Pnt P1 = ElCLib::Value(0., myCircle);
1970 gp_Pnt P2 = ElCLib::Value(Standard_PI, myCircle);
1971
1972 gce_MakePln mkPln(P1, P2, aPnt); // create a plane whitch defines plane for projection aPosition on it
1973
1974 aPnt = AIS::ProjectPointOnPlane(myPosition, mkPln.Value());
1975 tmpPnt = aPnt;
1976
1977 if( aPnt.Distance(P1) < aPnt.Distance(P2) ){
1978 AttachmentPnt = P1;
1979 OppositePnt = P2;
1980 }
1981 else {
1982 AttachmentPnt = P2;
1983 OppositePnt = P1;
1984 }
1985
1986 aPnt = AttachmentPnt ; // Creating of circle whitch defines a plane for a dimension arc
1987 gp_Vec Vec(AttachmentPnt, Apex); // Dimension arc is a part of the circle
1988 Vec.Scale(2);
1989 aPnt.Translate(Vec);
1990 GC_MakeCircle mkCirc(AttachmentPnt, OppositePnt, aPnt);
1991 gp_Circ aCircle2 = mkCirc.Value()->Circ();
1992
1993
1994 Standard_Integer i;
1995 Standard_Real AttParam = ElCLib::Parameter(aCircle2, AttachmentPnt);
1996 Standard_Real OppParam = ElCLib::Parameter(aCircle2, OppositePnt);
1997
1998 while ( AttParam >= 2*Standard_PI ) AttParam -= 2*Standard_PI;
1999 while ( OppParam >= 2*Standard_PI ) OppParam -= 2*Standard_PI;
2000
2001 if( myPosition.Distance( myCircle.Location() ) <= myCircle.Radius() )
2002 if( 2 * myCircle.Radius() > aCircle2.Radius() * 0.4 ) IsArrowOut = Standard_False; //four times more than an arrow size
2003
2004 Graphic3d_Array1OfVertex V(1, 12);
2005
2006 Standard_Real angle;
2007 param = ElCLib::Parameter(aCircle2, tmpPnt);
2008
2009 if(IsArrowOut) {
2010 angle = OppParam - AttParam + Standard_PI/6; //An angle between AttParam and OppParam + 30 degrees
2011 param = AttParam - Standard_PI/12; //out parts of dimension line are 15 degrees
2012
2013 while ( angle > 2*Standard_PI ) angle -= 2*Standard_PI;
2014 for( i = 0; i <= 11; i++ ) { //calculating of arc
2015 aPnt = ElCLib::Value(param + angle/11 * i, aCircle2);
2016 aPnt.Coord(X, Y, Z);
2017 V(i+1).SetCoord(X, Y, Z);
2018 }
2019
2020 }
2021 else {
2022 angle = OppParam - AttParam;
2023 param = AttParam;
2024 while ( angle > 2*Standard_PI ) angle -= 2*Standard_PI;
2025 for( i = 0; i <= 11; i++ ) { //calculating of arc
2026 aPnt = ElCLib::Value(param + angle/11 * i, aCircle2);
2027 aPnt.Coord(X, Y, Z);
2028 V(i+1).SetCoord(X, Y, Z);
2029 }
2030 }
2031
2032 for(i = 1; i<=11; i++) {
2033
2034 V(i).Coord(X, Y, Z);
2035 P1.SetCoord(X, Y, Z);
2036 V(i+1).Coord(X, Y, Z);
2037 P1.SetCoord(X, Y, Z);
2038
2039 seg = new Select3D_SensitiveSegment(owner, P1, P2);
2040 aSelection->Add(seg);
2041 }
2042
2043 tmpPnt = tmpPnt.Translated(gp_Vec(0, 0, -1)*2);
2044
2045 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
2046 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( owner,
2047 tmpPnt.X(),
2048 tmpPnt.Y(),
2049 tmpPnt.Z(),
2050 tmpPnt.X() + size,
2051 tmpPnt.Y() + size,
2052 tmpPnt.Z() + size);
2053 aSelection->Add(box);
2054}
2055
2056
2057