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