0022627: Change OCCT memory management defaults
[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();
1c72dff6 577 BRepBuilderAPI_MakeFace mkFace(aSurf, Precision::Confusion());
7fd59977 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
c6541a0c 595 myPosition = ElCLib::Value(M_PI / 2.0, myCircle);
7fd59977 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
c6541a0c 681 if (myVal <= Precision::Angular() || Abs( M_PI-myVal ) <= Precision::Angular())
7fd59977 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
81bba717 808 // myVal = Abs(geom_lin1->Lin().Angle( geom_lin2->Lin())); // Pb with angles JPR
7fd59977 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
81bba717 836 // Processing in case of 2 parallel straight lines
7fd59977 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
81bba717 847 // Processing in case of 2 non-parallel straight lines
7fd59977 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())
c6541a0c 934 && (Abs(myVal) < M_PI) ) {
7fd59977 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
c6541a0c 964 if (myVal > M_PI) {
7fd59977 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 }
c6541a0c 1025 if ( myVal < M_PI) curpos.SetXYZ(.5*(myFAttach.XYZ()+mySAttach.XYZ()));
7fd59977 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
81bba717 1038 // small offset like in LengthDimension
7fd59977 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 {
81bba717 1051 // point is projected on the plane
7fd59977 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 }
81bba717 1061 // To learn if it is necessary to take distance -dist or not
1062 // it is necessary to know if we are in the sector opposite to the angle
1063 // if not : we are in the opposite sector if the coordinates
1064 // of curpos in point (d1,d2) are negative
7fd59977 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) {
c6541a0c 1077 if (Abs(myVal)<M_PI) {
81bba717 1078 // test if uco is in the opposite sector
c6541a0c 1079 if (uco > udeb+M_PI && uco < ufin+M_PI){
7fd59977 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 //------------------------------------------------------------
81bba717 1175 // Computation of myCenter
1176 // -> Point located on the median of 2 straight lines,
1177 // is calculated as located between 2 closest points
1178 // of each straight line.
7fd59977 1179 //-----------------------------------------------------------
81bba717 1180 // theLength : radius of the future circle
7fd59977 1181 Standard_Real theLength = gpl1.Distance(gpl2.Location());
81bba717 1182 // processing of the particular case when 2 straight lines are coincident
7fd59977 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
81bba717 1250 gp_Pnt curpos; // cursor position
7fd59977 1251 TColStd_Array1OfReal tabdist(1,4);
81bba717 1252 gp_Pnt P1, P2; // points at intersection of the circle with 2 straight lines
7fd59977 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
81bba717 1282 // calculate attachments of the face
1283 // -> they are points of intersection if
1284 // intersection is outside of the edges
7fd59977 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);
81bba717 1318 // calculate the intersection of circle with l1
1319 Standard_Real pparam; // parameter of the point of intersection on l1
7fd59977 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);
81bba717 1385 // the centre is translated to avoid a constant radius!
7fd59977 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
81bba717 1390 // re-update curpos
7fd59977 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);
81bba717 1396 // calculate the point of intersection of circle with l1
7fd59977 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
81bba717 1406 // calculate the point of intersection of circle with l2
1407 // -> this is the projection because the centre of circle
1408 // is in the middle of l1 and l2
7fd59977 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;
c6541a0c 1496 gp_Dir axisdir = (myVal <= Precision::Angular() || Abs( M_PI-myVal ) <= Precision::Angular())?
7fd59977 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
c6541a0c 1530 if (myVal > Precision::Angular() && Abs( M_PI-myVal ) > Precision::Angular())
7fd59977 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
81bba717 1601//purpose : compute zones of selection on a side of angle between 2 edges
1602// Special processing of zero angles!
7fd59977 1603//=======================================================================
1604
1605void AIS_AngleDimension::Compute2DSelection(const Handle(SelectMgr_Selection)& aSelection)
1606{
1607 BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
1608 BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
1609
1610 gp_Lin l1(cu1.Line());
1611 gp_Lin l2(cu2.Line());
1612
1613 // it is patch!
c6541a0c 1614 if (Abs( myVal ) <= Precision::Angular() || Abs( M_PI - myVal ) <= Precision::Angular())
7fd59977 1615/*
1616 //---------------------------------------------------------
c6541a0c 1617 // Cas de droites paralleles ( <=> angle nul a M_PI pres)
7fd59977 1618 if ((Abs(l1.Angle(l2)) < Precision::Angular()) ||
c6541a0c 1619 (Abs((l1.Angle(l2) - M_PI)) < Precision::Angular()) )
7fd59977 1620*/
1621 {
1622
1623 Standard_Real distLL= l1.Distance(l2);
1624 if ( Abs(distLL) <= Precision::Confusion() ) {
1625 gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
1626 gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
1627 gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
1628 gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
1629 distLL = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1630 ComputeNull2DSelection(aSelection, distLL);
1631 }
1632 else {
1633 ComputeNull2DSelection(aSelection, distLL*8/10);
1634 }
1635 }
1636
1637 //----------------------------------------------------------
81bba717 1638 // Classic case ( angle != 0 )
7fd59977 1639 else {
1640
1641 if (myFDir.IsParallel(mySDir,Precision::Angular())) {
1642 Standard_Real distLL= l1.Distance(l2);
1643 if ( Abs(distLL) <= Precision::Confusion() ) {
1644 gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
1645 gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
1646 gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
1647 gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
1648 distLL = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1649 ComputeNull2DSelection(aSelection, distLL*8/10);
1650 }
1651 }
1652 else {
1653 gp_Dir Norm = myFDir.Crossed(mySDir);
1654
1655 gp_Ax2 ax(myCenter,Norm,myFDir);
1656 gp_Circ cer(ax,myCenter.Distance(myPosition));
1657 gp_Vec vec1(myFDir);
1658
1659 Standard_Boolean nullrad(Standard_False);
1660 if (cer.Radius() == 0.) {
1661 cer.SetRadius(1.);
1662 nullrad = Standard_True;
1663 }
1664 vec1 *= cer.Radius();
1665 gp_Pnt p1 = myCenter.Translated(vec1);
1666 gp_Vec vec2(mySDir);
1667 vec2 *= cer.Radius();
1668 gp_Pnt p2 = myCenter.Translated(vec2);
1669
1670 Standard_Real uc1 = 0.;
1671 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
1672 Standard_Real uco;
1673 if (nullrad) uco = ElCLib::Parameter(cer,p1);
1674 else uco = ElCLib::Parameter(cer,myPosition);
1675
1676 Standard_Real udeb = uc1;
1677 Standard_Real ufin = uc2;
1678
1679 if (uco > ufin) {
c6541a0c 1680 if (Abs(myVal)<M_PI) {
81bba717 1681 // test if uco is in the opposing sector
c6541a0c
D
1682 if (uco > udeb+M_PI && uco < ufin+M_PI){
1683 udeb = udeb + M_PI;
1684 ufin = ufin + M_PI;
7fd59977 1685 uc1 = udeb;
1686 uc2 = ufin;
1687 }
1688 }
1689 }
1690 if (uco > ufin) {
c6541a0c
D
1691 if ((uco-uc2) < (uc1-uco+(2*M_PI))) ufin = uco;
1692 else udeb = uco - 2*M_PI;
7fd59977 1693 }
1694 p1 = ElCLib::Value(udeb,cer);
1695 p2 = ElCLib::Value(ufin,cer);
1696
81bba717 1697 //Create 2 owners for each part of the arrow
7fd59977 1698 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1699 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1700 if (myExtShape != 0) {
1701 if (myExtShape == 1) {
1702 own1->SetShape(mySShape);
1703 own2->SetShape(mySShape);
1704 }
1705 else {
1706 own1->SetShape(myFShape);
1707 own2->SetShape(myFShape);
1708 }
1709 }
1710 else {
1711 own1->SetShape(myFShape);
1712 own2->SetShape(mySShape);
1713 }
1714
1715 Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
1716
1717 Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
1718 Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
1719
1720 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
1721 aSelection->Add(scurv);
1722 scurv = new Select3D_SensitiveCurve(own2,thecu2);
1723 aSelection->Add(scurv);
1724
1725 Handle(Select3D_SensitiveSegment) seg;
1726 if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
1727 seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
1728 aSelection->Add(seg);
1729 }
1730 if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
1731 seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
1732 aSelection->Add(seg);
1733 }
1734 }
1735 }
1736
1737}
1738//=======================================================================
1739//function : Compute2DNullSelection
1740//purpose : for dimension of null angle
1741//=======================================================================
1742
1743void AIS_AngleDimension::ComputeNull2DSelection(
1744 const Handle(SelectMgr_Selection)& aSelection,
1745 const Standard_Real distLL)
1746{
1747 gp_Dir Norm;
1748 if ( myFDir.IsParallel(mySDir, Precision::Angular()) ) {
1749 Norm = myPlane->Pln().Axis().Direction();
1750 }
1751 else
1752 Norm = myFDir.Crossed(mySDir);
1753
1754 gp_Ax2 ax(myCenter,Norm,myFDir);
1755 gp_Circ cer(ax,distLL);
1756
1757 gp_Vec vec1(myFDir);
1758 vec1 *= cer.Radius();
1759 gp_Pnt p1 = myCenter.Translated(vec1);
1760 gp_Vec vec2(mySDir);
1761 vec2 *= cer.Radius();
1762 gp_Pnt p2 = myCenter.Translated(vec2);
1763
1764 // calcul de parametres de debut et de fin des extremites de l'arc
1765 Standard_Real uc1 = 0.;
1766 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
1767 Standard_Real uco = ElCLib::Parameter(cer,myPosition);
1768
1769 Standard_Real udeb = uc1;
1770 Standard_Real ufin = uc2;
1771
1772 if (uco > ufin) {
c6541a0c 1773 if (Abs(myVal)<M_PI) {
81bba717 1774 // test if uco is in the opposing sector
c6541a0c
D
1775 if (uco > udeb+M_PI && uco < ufin+M_PI){
1776 udeb = udeb + M_PI;
1777 ufin = ufin + M_PI;
7fd59977 1778 uc1 = udeb;
1779 uc2 = ufin;
1780 }
1781 }
1782 }
1783
1784 if (uco > ufin) {
c6541a0c 1785 if ((uco-uc2) < (uc1-uco+(2*M_PI))) {
7fd59977 1786 ufin = uco;
1787 }
1788 else {
c6541a0c 1789 udeb = uco - 2*M_PI;
7fd59977 1790 }
1791 }
1792
81bba717 1793 //Create 2 owners for each part of the arrow
7fd59977 1794 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1795 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1796 if (myExtShape != 0) {
1797 if (myExtShape == 1) {
1798 own1->SetShape(mySShape);
1799 own2->SetShape(mySShape);
1800 }
1801 else {
1802 own1->SetShape(myFShape);
1803 own2->SetShape(myFShape);
1804 }
1805 }
1806 else {
1807 own1->SetShape(myFShape);
1808 own2->SetShape(mySShape);
1809 }
1810
1811 Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
1812
1813 if ( udeb != ufin ) {
1814 Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
1815 Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
1816
1817 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
1818 aSelection->Add(scurv);
1819 scurv = new Select3D_SensitiveCurve(own2,thecu2);
1820 aSelection->Add(scurv);
1821 }
1822 else {
81bba717 1823 // find end of segment to allow selection
7fd59977 1824 gp_Vec VTrans(myFDir.Crossed(Norm));
1825 Handle(Select3D_SensitiveSegment) seg1;
1826 seg1 = new Select3D_SensitiveSegment(own1,
1827 p1,
1828 p1.Translated( VTrans*distLL/10 ) );
1829 aSelection->Add(seg1);
1830 seg1 = new Select3D_SensitiveSegment(own2,
1831 p2,
1832 p2.Translated(-VTrans*distLL/10 ) );
1833 aSelection->Add(seg1);
1834 }
1835
1836 Handle(Select3D_SensitiveSegment) seg;
1837 if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
1838 seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
1839 aSelection->Add(seg);
1840 }
1841
1842 if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
1843 seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
1844 aSelection->Add(seg);
1845 }
1846}
1847
1848
1849//=======================================================================
1850//function : ComputeConeAngleSelection
1851//purpose : for cone angle
1852//=======================================================================
1853void AIS_AngleDimension::ComputeConeAngleSelection(const Handle(SelectMgr_Selection)& aSelection)
1854{
1855 if( myCone.IsNull() ) return;
1856
1857
1858 Handle( SelectMgr_EntityOwner ) owner = new SelectMgr_EntityOwner( this, 7 );
1859 Handle( Select3D_SensitiveSegment ) seg;
1860
1861 gp_Pln aPln;
1862 gp_Cone aCone;
1863 gp_Circ myCircle;
1864 gp_Pnt Apex;
1865 Handle( Geom_Surface ) aSurf; //a surface from the Face
1866 Handle( Geom_OffsetSurface ) aOffsetSurf;
1867 Handle( Geom_ConicalSurface ) aConicalSurf;
1868 Handle( Geom_SurfaceOfRevolution ) aRevSurf;
1869 Handle( Geom_Line ) aLine;
1870 BRepAdaptor_Surface tmpSurf(myCone);
1871 TopoDS_Face aFace;
1872 AIS_KindOfSurface aSurfType;
1873 Standard_Real Offset = 0. ;
1874 Handle( Standard_Type ) aType;
1875
1876 Standard_Real maxV = tmpSurf.FirstVParameter();
1877 Standard_Real minV = tmpSurf.LastVParameter();
1878
1879 AIS::GetPlaneFromFace( myCone, aPln, aSurf, aSurfType, Offset );
1880
1881 if ( aSurfType == AIS_KOS_Revolution ) { //surface of revolution
1882
1883 aRevSurf = Handle( Geom_SurfaceOfRevolution )::DownCast( aSurf );
1884 gp_Lin ln( aRevSurf->Axis() );
1885 Handle( Geom_Curve ) tmpCrv = aRevSurf->BasisCurve();
1886 if ( tmpCrv ->DynamicType() != STANDARD_TYPE(Geom_Line) ) return; //Must be a part of line
1887
1888 Standard_Real par;
1889 gp_Pnt fst = tmpSurf.Value(0., minV);
1890 gp_Pnt lst = tmpSurf.Value(0., maxV);
1891
1892 gp_Vec vec1(fst, lst);
1893
1894 par = ElCLib::Parameter( ln, fst );
1895 gp_Pnt fst2 = ElCLib::Value( par, ln ); //projection fst on ln
1896 par = ElCLib::Parameter( ln, lst );
1897 gp_Pnt lst2 = ElCLib::Value( par, ln ); //projection lst on ln
1898
1899 gp_Vec vec2(fst2, lst2);
1900
1901 // Check if two parts of revolution are parallel ( it's a cylinder ) or normal (it's a circle )
1902 if( vec1.IsParallel( vec2,Precision::Angular() ) || vec1.IsNormal( vec2,Precision::Angular() ) ) return;
1903
1904 gce_MakeCone mkCone(aRevSurf->Axis(), fst, lst);
1905 aCone = mkCone.Value();
1906 Apex = aCone.Apex();
1907 }
1908 else {
1909 aType = aSurf->DynamicType();
1910 if ( aType == STANDARD_TYPE(Geom_OffsetSurface) || Offset > 0.01 ) { //offset surface
1911 aOffsetSurf = new Geom_OffsetSurface (aSurf, Offset);
1912 aSurf = aOffsetSurf->Surface();
1c72dff6 1913 BRepBuilderAPI_MakeFace mkFace(aSurf, Precision::Confusion());
7fd59977 1914 mkFace.Build();
1915 if( !mkFace.IsDone() ) return;
1916 tmpSurf.Initialize( mkFace.Face() );
1917 }
1918
1919 aCone = tmpSurf.Cone();
1920 aConicalSurf = Handle( Geom_ConicalSurface)::DownCast( aSurf );
1921 Apex = aConicalSurf->Apex();
1922 }
1923
1924 Handle(Geom_Curve) aCurve; //A circle where the angle is drawn
1925
1926 if ( myAutomaticPosition ) {
1927 Standard_Real midV = ( minV + maxV ) / 2.5;
1928
1929 aCurve = aSurf->VIso(midV);
1930 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1931
c6541a0c 1932 myPosition = ElCLib::Value(M_PI / 2.0, myCircle);
7fd59977 1933 myAutomaticPosition = Standard_False;
1934 }
1935 else {
1936 Standard_Real U, V;
1937 ElSLib::Parameters(aCone, myPosition, U, V);
1938 aCurve = aSurf->VIso(V);
1939 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1940 }
1941 //__________________________________________________________________
1942 aCurve = aSurf->VIso(maxV);
1943 gp_Circ CircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1944 aCurve = aSurf->VIso(minV);
1945 gp_Circ CircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1946 //__________________________________________________________________
1947
1948 if( CircVmax.Radius() < CircVmin.Radius() ) {
1949 gp_Circ tmpCirc = CircVmax;
1950 CircVmax = CircVmin;
1951 CircVmin = tmpCirc;
1952 }
1953
1954 Standard_Boolean IsArrowOut = Standard_True; //Is arrows inside or outside of the cone
1955 //Standard_Real PntOnMainAxis = 0; //Is projection of aPosition inside of the cone = 0, above = 1, or below = -1
1956 Standard_Boolean IsConeTrimmed = Standard_False;
1957
1958 if( CircVmin.Radius() > 0.01 ) IsConeTrimmed = Standard_True;
1959
1960 gp_Pnt AttachmentPnt;
1961 gp_Pnt OppositePnt;
1962 gp_Pnt aPnt, tmpPnt;
1963 Quantity_Length X,Y,Z;
1964
1965 Standard_Real param = ElCLib::Parameter(myCircle, myPosition);
1966
1967 aPnt = Apex;
1968 gp_Pnt P1 = ElCLib::Value(0., myCircle);
c6541a0c 1969 gp_Pnt P2 = ElCLib::Value(M_PI, myCircle);
7fd59977 1970
1971 gce_MakePln mkPln(P1, P2, aPnt); // create a plane whitch defines plane for projection aPosition on it
1972
1973 aPnt = AIS::ProjectPointOnPlane(myPosition, mkPln.Value());
1974 tmpPnt = aPnt;
1975
1976 if( aPnt.Distance(P1) < aPnt.Distance(P2) ){
1977 AttachmentPnt = P1;
1978 OppositePnt = P2;
1979 }
1980 else {
1981 AttachmentPnt = P2;
1982 OppositePnt = P1;
1983 }
1984
1985 aPnt = AttachmentPnt ; // Creating of circle whitch defines a plane for a dimension arc
1986 gp_Vec Vec(AttachmentPnt, Apex); // Dimension arc is a part of the circle
1987 Vec.Scale(2);
1988 aPnt.Translate(Vec);
1989 GC_MakeCircle mkCirc(AttachmentPnt, OppositePnt, aPnt);
1990 gp_Circ aCircle2 = mkCirc.Value()->Circ();
1991
1992
1993 Standard_Integer i;
1994 Standard_Real AttParam = ElCLib::Parameter(aCircle2, AttachmentPnt);
1995 Standard_Real OppParam = ElCLib::Parameter(aCircle2, OppositePnt);
1996
c6541a0c
D
1997 while ( AttParam >= 2 * M_PI ) AttParam -= 2 * M_PI;
1998 while ( OppParam >= 2 * M_PI ) OppParam -= 2 * M_PI;
7fd59977 1999
2000 if( myPosition.Distance( myCircle.Location() ) <= myCircle.Radius() )
2001 if( 2 * myCircle.Radius() > aCircle2.Radius() * 0.4 ) IsArrowOut = Standard_False; //four times more than an arrow size
2002
2003 Graphic3d_Array1OfVertex V(1, 12);
2004
2005 Standard_Real angle;
2006 param = ElCLib::Parameter(aCircle2, tmpPnt);
2007
2008 if(IsArrowOut) {
c6541a0c
D
2009 angle = OppParam - AttParam + M_PI / 6; //An angle between AttParam and OppParam + 30 degrees
2010 param = AttParam - M_PI / 12; //out parts of dimension line are 15 degrees
7fd59977 2011
c6541a0c 2012 while ( angle > 2 * M_PI ) angle -= 2 * M_PI;
7fd59977 2013 for( i = 0; i <= 11; i++ ) { //calculating of arc
2014 aPnt = ElCLib::Value(param + angle/11 * i, aCircle2);
2015 aPnt.Coord(X, Y, Z);
2016 V(i+1).SetCoord(X, Y, Z);
2017 }
2018
2019 }
2020 else {
2021 angle = OppParam - AttParam;
2022 param = AttParam;
c6541a0c 2023 while ( angle > 2 * M_PI ) angle -= 2 * M_PI;
7fd59977 2024 for( i = 0; i <= 11; i++ ) { //calculating of arc
2025 aPnt = ElCLib::Value(param + angle/11 * i, aCircle2);
2026 aPnt.Coord(X, Y, Z);
2027 V(i+1).SetCoord(X, Y, Z);
2028 }
2029 }
2030
2031 for(i = 1; i<=11; i++) {
2032
2033 V(i).Coord(X, Y, Z);
2034 P1.SetCoord(X, Y, Z);
2035 V(i+1).Coord(X, Y, Z);
2036 P1.SetCoord(X, Y, Z);
2037
2038 seg = new Select3D_SensitiveSegment(owner, P1, P2);
2039 aSelection->Add(seg);
2040 }
2041
2042 tmpPnt = tmpPnt.Translated(gp_Vec(0, 0, -1)*2);
2043
2044 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
2045 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( owner,
2046 tmpPnt.X(),
2047 tmpPnt.Y(),
2048 tmpPnt.Z(),
2049 tmpPnt.X() + size,
2050 tmpPnt.Y() + size,
2051 tmpPnt.Z() + size);
2052 aSelection->Add(box);
2053}
2054
2055
2056