Test for 0022778: Bug in BRepMesh
[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>
104#include <Graphic3d_Array1OfVertex.hxx>
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
475//=======================================================================
476//function : Compute
477//purpose : : to avoid warning
478//=======================================================================
479
480void AIS_AngleDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
481 const Handle(Graphic2d_GraphicObject)& aGraphicObject,
482 const Standard_Integer anInteger)
483{
484// Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
485 PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
486}
487
488void AIS_AngleDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
489{
490// Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
491 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
492}
493
494//=======================================================================
495//function : ComputeSelection
496//purpose :
497//=======================================================================
498
499void AIS_AngleDimension::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
500 const Standard_Integer)
501{
502
503 if ( myNbShape == 1 )
504 {
505 // cout << "Computing selection for cone's angle " << endl;
506 ComputeConeAngleSelection(aSelection);
507 return;
508 }
509
510
511 if (myFShape.IsNull()) return;
512
513 if (myFShape.ShapeType() == TopAbs_FACE )
514 Compute3DSelection(aSelection);
515 else
516 Compute2DSelection(aSelection);
517
518 // Text
519 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
520 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
521 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
522 myPosition.X(),
523 myPosition.Y(),
524 myPosition.Z(),
525 myPosition.X() + size,
526 myPosition.Y() + size,
527 myPosition.Z() + size);
528 aSelection->Add(box);
529}
530
531//=======================================================================
532//function : ComputeConeAngle
533//purpose :
534//=======================================================================
535
536void AIS_AngleDimension::ComputeConeAngle(const Handle(Prs3d_Presentation)& aPresentation)
537{
538 if( myCone.IsNull() ) return;
539
540 gp_Pln aPln;
541 gp_Cone aCone;
542 gp_Circ myCircle;
543 gp_Pnt Apex;
544 Handle( Geom_Surface ) aSurf; //a surface from the Face
545 Handle( Geom_OffsetSurface ) aOffsetSurf;
546 Handle( Geom_ConicalSurface ) aConicalSurf;
547 Handle( Geom_SurfaceOfRevolution ) aRevSurf;
548 Handle( Geom_Line ) aLine;
549 BRepAdaptor_Surface tmpSurf(myCone);
550 TopoDS_Face aFace;
551 AIS_KindOfSurface aSurfType;
552 Standard_Real Offset = 0. ;
553 Handle( Standard_Type ) aType;
554
555 Standard_Real maxV = tmpSurf.FirstVParameter();
556 Standard_Real minV = tmpSurf.LastVParameter();
557
558
559 AIS::GetPlaneFromFace( myCone, aPln, aSurf, aSurfType, Offset );
560
561 if ( aSurfType == AIS_KOS_Revolution ) { //surface of revolution
562
563 aRevSurf = Handle( Geom_SurfaceOfRevolution )::DownCast( aSurf );
564 gp_Lin ln( aRevSurf->Axis() );
565 Handle( Geom_Curve ) tmpCrv = aRevSurf->BasisCurve();
566 if ( tmpCrv ->DynamicType() != STANDARD_TYPE(Geom_Line) ) return; //Must be a part of line
567
568 Standard_Real par;
569 gp_Pnt fst = tmpSurf.Value(0., minV);
570 gp_Pnt lst = tmpSurf.Value(0., maxV);
571
572 gp_Vec vec1(fst, lst);
573
574 par = ElCLib::Parameter( ln, fst );
575 gp_Pnt fst2 = ElCLib::Value( par, ln ); //projection fst on ln
576 par = ElCLib::Parameter( ln, lst );
577 gp_Pnt lst2 = ElCLib::Value( par, ln ); //projection lst on ln
578
579 gp_Vec vec2(fst2, lst2);
580
581 // Check if two parts of revolution are parallel ( it's a cylinder ) or normal (it's a circle )
582 if( vec1.IsParallel( vec2,Precision::Angular() ) || vec1.IsNormal( vec2,Precision::Angular() ) ) return;
583
584 gce_MakeCone mkCone(aRevSurf->Axis(), fst, lst);
585 aCone = mkCone.Value();
586 Apex = aCone.Apex();
587 }
588 else {
589 aType = aSurf->DynamicType();
590 if ( aType == STANDARD_TYPE(Geom_OffsetSurface) || Offset > 0.01 ) { //offset surface
591 aOffsetSurf = new Geom_OffsetSurface (aSurf, Offset);
592 aSurf = aOffsetSurf->Surface();
1c72dff6 593 BRepBuilderAPI_MakeFace mkFace(aSurf, Precision::Confusion());
7fd59977 594 mkFace.Build();
595 if( !mkFace.IsDone() ) return;
596 tmpSurf.Initialize( mkFace.Face() );
597 }
598
599 aCone = tmpSurf.Cone();
600 aConicalSurf = Handle( Geom_ConicalSurface)::DownCast( aSurf );
601 Apex = aConicalSurf->Apex();
602 }
603
604 Handle(Geom_Curve) aCurve; //A circle where the angle is drawn
605 if ( myAutomaticPosition ) {
606 Standard_Real midV = ( minV + maxV ) / 2.5;
607
608 aCurve = aSurf->VIso(midV);
609 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
610
c6541a0c 611 myPosition = ElCLib::Value(M_PI / 2.0, myCircle);
7fd59977 612 myAutomaticPosition = Standard_False;
613 }
614 else {
615 Standard_Real U, V;
616 ElSLib::Parameters(aCone, myPosition, U, V);
617 aCurve = aSurf->VIso(V);
618 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
619 }
620
621 //__________________________________________________________________
622 aCurve = aSurf->VIso(maxV);
623 gp_Circ CircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
624 aCurve = aSurf->VIso(minV);
625 gp_Circ CircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
626 //__________________________________________________________________
627
628 if( CircVmax.Radius() < CircVmin.Radius() ) {
629 gp_Circ tmpCirc = CircVmax;
630 CircVmax = CircVmin;
631 CircVmin = tmpCirc;
632 }
633
634 DsgPrs_AnglePresentation::Add(aPresentation, myDrawer, myVal,
635 myText, myCircle, myPosition, Apex, CircVmin, CircVmax, myArrowSize);
636// cout << "ComputeConeAngle is over" << endl;
637}
638
639
640//=======================================================================
641//function : ComputeTwoFacesAngle
642//purpose :
643//=======================================================================
644
645void AIS_AngleDimension::ComputeTwoFacesAngle(const Handle(Prs3d_Presentation)& aPresentation)
646{
647 if (myFirstSurfType == AIS_KOS_Plane)
648 ComputeTwoPlanarFacesAngle( aPresentation );
649 else
650 ComputeTwoCurvilinearFacesAngle( aPresentation );
651}
652
653//=======================================================================
654//function : ComputeTwoCurvilinearFacesAngle
655//purpose :
656//=======================================================================
657
658void AIS_AngleDimension::ComputeTwoCurvilinearFacesAngle(const Handle(Prs3d_Presentation)& aPresentation)
659{
660 AIS::ComputeAngleBetweenCurvilinearFaces( TopoDS::Face( myFShape ),
661 TopoDS::Face( mySShape ),
662 myFirstBasisSurf,
663 mySecondBasisSurf,
664 myFirstSurfType,
665 mySecondSurfType,
666 myAxis,
667 myVal,
668 myAutomaticPosition,
669 myPosition,
670 myCenter,
671 myFAttach,
672 mySAttach,
673 myFDir,
674 mySDir,
675 myPlane );
676 if (myAutomaticPosition && myIsSetBndBox)
677 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCenter, myPosition ) ), myBndBox );
678
679 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
680 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
681#ifdef BUC60915
682 if( !myArrowSizeIsDefined ) {
683#endif
684 Standard_Real arrsize = myCenter.Distance( myPosition );
685
686 if ( (myArrowSize-arrsize) < 0.1 ) arrsize = myArrowSize;
687 if (arrsize == 0.) arrsize = 1.;
688#ifdef BUC60915
689 myArrowSize = arrsize;
690 }
691 arr->SetLength( myArrowSize );
692#else
693 arr->SetLength(arrsize);
694#endif
695
696
c6541a0c 697 if (myVal <= Precision::Angular() || Abs( M_PI-myVal ) <= Precision::Angular())
7fd59977 698 DsgPrs_AnglePresentation::Add(aPresentation,
699 myDrawer,
700 myVal,
701 myText,
702 myCenter,
703 myFAttach,
704 mySAttach,
705 myFDir,
706 mySDir,
707 myPlane->Pln().Axis().Direction(),
708 Standard_False, // not plane
709 myAxis,
710 myPosition,
711 mySymbolPrs);
712 else
713 DsgPrs_AnglePresentation::Add(aPresentation,
714 myDrawer,
715 myVal,
716 myText,
717 myCenter,
718 myFAttach,
719 mySAttach,
720 myFDir,
721 mySDir,
722 myFDir ^ mySDir,
723 Standard_False, // not plane
724 myAxis,
725 myPosition,
726 mySymbolPrs);
727}
728
729//=======================================================================
730//function : ComputeTwoPlanarFacesAngle
731//purpose :
732//=======================================================================
733
734void AIS_AngleDimension::ComputeTwoPlanarFacesAngle( const Handle( Prs3d_Presentation )& aPresentation )
735{
736 AIS::ComputeAngleBetweenPlanarFaces( TopoDS::Face( myFShape ),
737 TopoDS::Face( mySShape ),
738 mySecondBasisSurf,
739 myAxis,
740 myVal,
741 myAutomaticPosition,
742 myPosition,
743 myCenter,
744 myFAttach,
745 mySAttach,
746 myFDir,
747 mySDir );
748 if (myAutomaticPosition && myIsSetBndBox)
749 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCenter, myPosition ) ), myBndBox );
750
751 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
752 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
753#ifdef BUC60915
754 if( !myArrowSizeIsDefined ) {
755#endif
756 Standard_Real arrsize = myCenter.Distance( myPosition );
757
758 if ( (myArrowSize-arrsize) < 0.1 ) arrsize = myArrowSize;
759 if (arrsize == 0.) arrsize = 1.;
760#ifdef BUC60915
761 myArrowSize = arrsize;
762 }
763 arr->SetLength( myArrowSize );
764#else
765 arr->SetLength(arrsize);
766#endif
767
768
769 DsgPrs_AnglePresentation::Add(aPresentation,
770 myDrawer,
771 myVal,
772 myText,
773 myCenter,
774 myFAttach,
775 mySAttach,
776 myFDir,
777 mySDir,
778 myAxis.Direction(),
779 Standard_True,
780 myAxis,
781 myPosition,
782 mySymbolPrs);
783
784}
785
786//=======================================================================
787//function : ComputeTwoEdgesAngle
788//purpose :
789//=======================================================================
790
791void AIS_AngleDimension::ComputeTwoEdgesAngle(const Handle(Prs3d_Presentation)& aPresentation)
792{
793 BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
794 BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
795 if ((cu1.GetType() != GeomAbs_Line) || (cu2.GetType() != GeomAbs_Line)) return;
796
797 // current face
798 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
799 TopoDS_Face face(makeface.Face());
800 BRepAdaptor_Surface adp(makeface.Face());
801
802 // 3d lines
803 Handle(Geom_Line) geom_lin1,geom_lin2;
804 gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
805 Standard_Boolean isInfinite1,isInfinite2;
806 Handle(Geom_Curve) extCurv;
807 Standard_Integer copyOfMyExtShape = myExtShape;
808 if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),
809 TopoDS::Edge(mySShape),
810 myExtShape,
811 geom_lin1,
812 geom_lin2,
813 ptat11,
814 ptat12,
815 ptat21,
816 ptat22,
817 extCurv,
818 isInfinite1,
819 isInfinite2,
820 myPlane)) {
821 return;
822 }
823 // Temporary: computation of myVal
81bba717 824 // myVal = Abs(geom_lin1->Lin().Angle( geom_lin2->Lin())); // Pb with angles JPR
7fd59977 825
826 if (copyOfMyExtShape != 0) myExtShape = copyOfMyExtShape;
827
828 // 2d lines => projection of 3d on current plane
829
830//POP pour NT
831 Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(geom_lin1,myPlane->Pln());
832 Handle(Geom2d_Line) lin1_2d = *((Handle(Geom2d_Line)*)& geoC1);
833 Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(geom_lin2,myPlane->Pln());
834 Handle(Geom2d_Line) lin2_2d = *((Handle(Geom2d_Line)*)& geoC2);
835
836#ifdef BUC60915
837 if( !myArrowSizeIsDefined ) {
838#endif
839 Standard_Real arrSize1(myArrowSize),arrSize2(myArrowSize);
840 if (!isInfinite1) arrSize1 = ptat11.Distance(ptat12)/100.;
841 if (!isInfinite2) arrSize2 = ptat21.Distance(ptat22)/100.;
842#ifdef BUC60655
843 myArrowSize = Min(myArrowSize,Max(arrSize1,arrSize2));
844#else
845 myArrowSize = Min(myArrowSize,Min(arrSize1,arrSize2));
846#endif
847#ifdef BUC60915
848 }
849#endif
850
851
81bba717 852 // Processing in case of 2 parallel straight lines
7fd59977 853 if (lin1_2d->Lin2d().Direction()
854 .IsParallel(lin2_2d->Lin2d().Direction(),Precision::Angular())) {
855 ComputeTwoEdgesNullAngle(aPresentation,
856 geom_lin1,
857 geom_lin2,
858 ptat11,ptat12,
859 ptat21,ptat22,
860 isInfinite1,isInfinite2);
861 }
862
81bba717 863 // Processing in case of 2 non-parallel straight lines
7fd59977 864 else {
865 ComputeTwoEdgesNotNullAngle(aPresentation,
866 geom_lin1,
867 geom_lin2,
868 ptat11,
869 ptat12,
870 ptat21,
871 ptat22,
872 isInfinite1,isInfinite2);
873 }
874 if ( (myExtShape != 0) && !extCurv.IsNull()) {
875 gp_Pnt pf, pl;
876 if ( myExtShape == 1 ) {
877 if (!isInfinite1) {
878 pf = ptat11;
879 pl = ptat12;
880 }
881 aPresentation->SetInfiniteState(isInfinite1);
882 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(myFShape),geom_lin1,pf,pl);
883 }
884 else {
885 if (!isInfinite2) {
886 pf = ptat21;
887 pl = ptat22;
888 }
889 aPresentation->SetInfiniteState(isInfinite2);
890 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(mySShape),geom_lin2,pf,pl);
891 }
892 }
893}
894
895
896//=======================================================================
897//function : ComputeTwoEdgesNotNullAngle
898//purpose :
899//=======================================================================
900
901void AIS_AngleDimension::ComputeTwoEdgesNotNullAngle(const Handle(Prs3d_Presentation)& aPresentation,
902 const Handle(Geom_Line)& l1,
903 const Handle(Geom_Line)& l2,
904 const gp_Pnt& ptat11,
905 const gp_Pnt& ptat12,
906 const gp_Pnt& ptat21,
907 const gp_Pnt& ptat22,
908 const Standard_Boolean isInfinite1,
909 const Standard_Boolean isInfinite2)
910{
911 // current face
912 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
913 TopoDS_Face face(makeface.Face());
914 BRepAdaptor_Surface adp(makeface.Face());
915 // 2d lines => projection of 3d on current plane
916 Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(l1,myPlane->Pln());
917 const Handle(Geom2d_Line)& l1_2d = *((Handle(Geom2d_Line)*)& geoC1);
918 Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(l2,myPlane->Pln());
919 const Handle(Geom2d_Line)& l2_2d = *((Handle(Geom2d_Line)*)& geoC2);
920
921 //----------------------------------------------------------
922 // Computation of myCenter
923 //----------------------------------------------------------
924 IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),l2_2d->Lin2d());
925 if (!inter.IsDone()) return;
926 if (!inter.NbPoints()) return;
927
928 gp_Pnt2d pint(inter.Point(1).Value());
929 myCenter = adp.Value(pint.X(),pint.Y());
930
931 //----------------------------------------------------------
932 // Computation of the 2 directions
933 //----------------------------------------------------------
934 gp_Dir d1,d2;
935 if (!isInfinite1) {
936 if (myCenter.SquareDistance(ptat11) > myCenter.SquareDistance(ptat12)) d1 = gp_Dir(gp_Vec(myCenter,ptat11));
937 else d1 = gp_Dir(gp_Vec(myCenter,ptat12));
938 }
939 else d1 = l1->Lin().Direction();
940
941 if (!isInfinite2) {
942 if (myCenter.SquareDistance(ptat21) > myCenter.SquareDistance(ptat22)) d2 = gp_Dir(gp_Vec(myCenter,ptat21));
943 else d2 = gp_Dir(gp_Vec(myCenter,ptat22));
944 }
945 else d2 = l2->Lin().Direction();
946 if (!isInfinite1) {
947 Standard_Boolean In1(Standard_False);
948 Standard_Boolean In2(Standard_False);
949 if ( !(Abs(d1.Angle(d2) - Abs(myVal)) <= Precision::Confusion())
c6541a0c 950 && (Abs(myVal) < M_PI) ) {
7fd59977 951 Standard_Real parcent1 = ElCLib::Parameter(l1->Lin(), myCenter);
952 Standard_Real par11 = ElCLib::Parameter(l1->Lin(), ptat11);
953 Standard_Real par12 = ElCLib::Parameter(l1->Lin(), ptat12);
954 if ( par11 < par12) {
955 if ( ( parcent1> par11) && (parcent1< par12)) {
956 In1 = Standard_True;
957 d1.Reverse();
958 }
959 }
960 else {
961 if ( ( parcent1> par12) && (parcent1< par11)) {
962 In1 = Standard_True;
963 d1.Reverse();
964 }
965 }
966 if ( !In1) {
967 In2 = Standard_True;
968 d2.Reverse();
969 }
970 }
971 }
972
973 myFDir = d1;
974 mySDir = d2;
975 gp_Lin theaxis;
976 gp_Lin gpl1 = l1->Lin();
977 gp_Lin gpl2 = l2->Lin();
978 theaxis = gp_Lin(myCenter,myFDir^mySDir);
979
c6541a0c 980 if (myVal > M_PI) {
7fd59977 981 theaxis.Reverse();
982 }
983
984 gp_Pnt curpos;
985 TColStd_Array1OfReal tabdist(1,4);
986 if (!isInfinite1) {
987 tabdist(1) = theaxis.Distance(ptat11);
988 tabdist(2) = theaxis.Distance(ptat12);
989 }
990 else {
991 tabdist(1) = tabdist(2) = 0.;
992 }
993
994 if (!isInfinite2) {
995 tabdist(3) = theaxis.Distance(ptat21);
996 tabdist(4) = theaxis.Distance(ptat22);
997 }
998 else {
999 tabdist(3) = tabdist(4) = 0.;
1000 }
1001
1002 if (myAutomaticPosition) {
1003 Standard_Real length_1(RealLast());
1004 if (!isInfinite1) length_1 = .75*Abs(tabdist(2)-tabdist(1))+Min(tabdist(1),tabdist(2));
1005
1006 Standard_Real length_2(RealLast());
1007 if (!isInfinite2) length_2 = .75*Abs(tabdist(4)-tabdist(3))+Min(tabdist(3),tabdist(4));
1008 Standard_Real theLength(Min(length_1,length_2));
1009 if (Precision::IsInfinite(theLength)) theLength = 50.;
1010
1011 myFAttach = myCenter.Translated(gp_Vec(d1)*theLength);
1012 mySAttach = myCenter.Translated(gp_Vec(d2)*theLength);
1013
1014 if (!isInfinite1) {
1015 Standard_Real par_p1_attach(ElCLib::Parameter(gpl1,myFAttach));
1016 Standard_Real par11 = ElCLib::Parameter(gpl1,ptat11);
1017 Standard_Real par12 = ElCLib::Parameter(gpl1,ptat12);
1018 if (par_p1_attach > par11 && par_p1_attach > par12) {
1019 par_p1_attach = Max(par11,par12);
1020 myFAttach = ElCLib::Value(par_p1_attach,gpl1);
1021 }
1022 else if (par_p1_attach < par11 && par_p1_attach < par12) {
1023 par_p1_attach = Min(par11,par12);
1024 myFAttach = ElCLib::Value(par_p1_attach,gpl1);
1025 }
1026 }
1027
1028 if (!isInfinite2) {
1029 Standard_Real par_p2_attach(ElCLib::Parameter(gpl2,mySAttach));
1030 Standard_Real par21 = ElCLib::Parameter(gpl2,ptat21);
1031 Standard_Real par22 = ElCLib::Parameter(gpl2,ptat22);
1032 if (par_p2_attach > par21 && par_p2_attach > par22) {
1033 par_p2_attach = Max(par21,par22);
1034 mySAttach = ElCLib::Value(par_p2_attach,gpl2);
1035 }
1036 else if (par_p2_attach < par21 && par_p2_attach < par22) {
1037 par_p2_attach = Min(par21,par22);
1038 mySAttach = ElCLib::Value(par_p2_attach,gpl2);
1039 }
1040 }
c6541a0c 1041 if ( myVal < M_PI) curpos.SetXYZ(.5*(myFAttach.XYZ()+mySAttach.XYZ()));
7fd59977 1042 else {
1043 curpos.SetXYZ(.5*(myFAttach.XYZ()+mySAttach.XYZ()));
1044 gp_Vec transl(curpos, myCenter);
1045 transl*= 2;
1046 curpos.Translate(transl);
1047 }
1048
1049 gp_Ax2 ax(myCenter,myFDir.Crossed(mySDir),myFDir);
1050 gp_Circ circle(ax,theLength);
1051 Standard_Real par = ElCLib::Parameter(circle,curpos);
1052 curpos = ElCLib::Value(par,circle);
1053
81bba717 1054 // small offset like in LengthDimension
7fd59977 1055 gp_Vec transl(myCenter, curpos);
1056 transl*= 0.3;
1057 curpos.Translate(transl);
1058
1059 if (myIsSetBndBox)
1060 curpos = AIS::TranslatePointToBound( curpos, gp_Dir( gp_Vec( myCenter, curpos ) ), myBndBox );
1061
1062 myPosition = curpos;
1063 myAutomaticPosition = Standard_True;
1064 }
1065
1066 else {
81bba717 1067 // point is projected on the plane
7fd59977 1068 gp_Pnt2d pointOnPln(ProjLib::Project(myPlane->Pln(),myPosition));
1069 myPosition = BRepAdaptor_Surface(BRepBuilderAPI_MakeFace(myPlane->Pln()).Face()).Value(pointOnPln.X(),pointOnPln.Y());
1070 curpos = myPosition;
1071 Standard_Real dist(curpos.Distance(myCenter));
1072 if (dist<=Precision::Confusion()) {
1073 gp_XYZ delta(1.,1.,1.);
1074 curpos.SetXYZ(curpos.XYZ()+delta);
1075 dist = curpos.Distance(myCenter);
1076 }
81bba717 1077 // To learn if it is necessary to take distance -dist or not
1078 // it is necessary to know if we are in the sector opposite to the angle
1079 // if not : we are in the opposite sector if the coordinates
1080 // of curpos in point (d1,d2) are negative
7fd59977 1081 gp_Ax2 ax(myCenter,myFDir.Crossed(mySDir),myFDir);
1082 gp_Circ circle(ax,dist);
1083#ifdef DEB
1084// gp_Pnt p1(myCenter.Translated(gp_Vec(d1)*dist));
1085#endif
1086 gp_Pnt p2(myCenter.Translated(gp_Vec(d2)*dist));
1087 Standard_Real uc1 = 0;
1088 Standard_Real uc2 = ElCLib::Parameter(circle, p2 );
1089 Standard_Real uco = ElCLib::Parameter(circle, curpos );
1090 Standard_Real udeb = uc1;
1091 Standard_Real ufin = uc2;
1092 if (uco > ufin) {
c6541a0c 1093 if (Abs(myVal)<M_PI) {
81bba717 1094 // test if uco is in the opposite sector
c6541a0c 1095 if (uco > udeb+M_PI && uco < ufin+M_PI){
7fd59977 1096 dist = -dist;
1097 }
1098 }
1099 }
1100
1101 gp_Pnt p1_attach(myCenter.Translated(gp_Vec(d1)*dist));
1102 gp_Pnt p2_attach(myCenter.Translated(gp_Vec(d2)*dist));
1103
1104 if (!isInfinite1) {
1105 Standard_Real par_p1_attach(ElCLib::Parameter(gpl1,p1_attach));
1106 Standard_Real par11 = ElCLib::Parameter(gpl1,ptat11);
1107 Standard_Real par12 = ElCLib::Parameter(gpl1,ptat12);
1108 if (par_p1_attach > par11 && par_p1_attach > par12) {
1109 par_p1_attach = Max(par11,par12);
1110 p1_attach = ElCLib::Value(par_p1_attach,gpl1);
1111 }
1112 else if (par_p1_attach < par11 && par_p1_attach < par12) {
1113 par_p1_attach = Min(par11,par12);
1114 p1_attach = ElCLib::Value(par_p1_attach,gpl1);
1115 }
1116 }
1117 myFAttach = p1_attach;
1118
1119 if (!isInfinite2) {
1120 Standard_Real par_p2_attach(ElCLib::Parameter(gpl2,p2_attach));
1121 Standard_Real par21 = ElCLib::Parameter(gpl2,ptat21);
1122 Standard_Real par22 = ElCLib::Parameter(gpl2,ptat22);
1123 if (par_p2_attach > par21 && par_p2_attach > par22) {
1124 par_p2_attach = Max(par21,par22);
1125 p2_attach = ElCLib::Value(par_p2_attach,gpl2);
1126 }
1127 else if (par_p2_attach < par21 && par_p2_attach < par22) {
1128 par_p2_attach = Min(par21,par22);
1129 p2_attach = ElCLib::Value(par_p2_attach,gpl2);
1130 }
1131 }
1132 mySAttach = p2_attach;
1133 }
1134 myAxis = theaxis.Position();
1135
1136 //--------------------------------------------------------
1137 // Computation of the presentation
1138 //--------------------------------------------------------
1139 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
1140 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
1141
1142 arr->SetLength(myArrowSize);
1143
1144 DsgPrs_AnglePresentation::Add(aPresentation,
1145 myDrawer,
1146 myVal,
1147 myText,
1148 myCenter,
1149 myFAttach,
1150 mySAttach,
1151 myFDir,
1152 mySDir,
1153 curpos,
1154 mySymbolPrs);
1155}
1156
1157
1158
1159//=======================================================================
1160//function : ComputeTwoEdgesNullAngle
1161//purpose : compute the presentation of a angle dimension if it's null.
1162// -> the aim of the computation is to have a constant radius
1163// during the dimension moving : the radius is independant
1164// of the cursor position, it's equal to a arbitrary value
1165//=======================================================================
1166
1167void AIS_AngleDimension::ComputeTwoEdgesNullAngle(const Handle(Prs3d_Presentation)& aPresentation,
1168 const Handle(Geom_Line)& l1,
1169 const Handle(Geom_Line)& l2,
1170 const gp_Pnt& ptat11,
1171 const gp_Pnt& ptat12,
1172 const gp_Pnt& ptat21,
1173 const gp_Pnt& ptat22,
1174 const Standard_Boolean isInfinite1,
1175 const Standard_Boolean isInfinite2)
1176{
1177 // current face
1178 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
1179 TopoDS_Face face(makeface.Face());
1180 BRepAdaptor_Surface adp(makeface.Face());
1181 // 2d lines => projection of 3d on current plane
1182 Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(l1,myPlane->Pln());
1183 Handle(Geom2d_Line) l1_2d = *((Handle(Geom2d_Line)*)& geoC1);
1184 Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(l2,myPlane->Pln());
1185 Handle(Geom2d_Line) l2_2d = *((Handle(Geom2d_Line)*)& geoC2);
1186
1187 gp_Lin gpl1 = l1->Lin();
1188 gp_Lin gpl2 = l2->Lin();
1189
1190 //------------------------------------------------------------
81bba717 1191 // Computation of myCenter
1192 // -> Point located on the median of 2 straight lines,
1193 // is calculated as located between 2 closest points
1194 // of each straight line.
7fd59977 1195 //-----------------------------------------------------------
81bba717 1196 // theLength : radius of the future circle
7fd59977 1197 Standard_Real theLength = gpl1.Distance(gpl2.Location());
81bba717 1198 // processing of the particular case when 2 straight lines are coincident
7fd59977 1199 Standard_Boolean SameLines(Standard_False);
1200 if ( theLength <= Precision::Confusion()) {
1201 SameLines = Standard_True;
1202 if (!isInfinite1) {
1203 if (!isInfinite2) theLength = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1204 else theLength = 0.75*ptat11.Distance(ptat12);
1205 }
1206 else {
1207 if (!isInfinite2) theLength = 0.75*ptat21.Distance(ptat22);
1208 else theLength = 50.;
1209 }
1210 }
1211 else theLength = theLength*8/10;
1212
1213 gp_Pnt pmin1 ,pmin2;
1214 if (!isInfinite1 && !isInfinite2) {
1215 pmin1 = ptat11; pmin2 = ptat21;
1216 Standard_Real dis = ptat11.Distance(ptat21);
1217 Standard_Real dis2 = ptat11.Distance(ptat22);
1218 if ( dis2 < dis) {
1219 pmin1 = ptat11;
1220 pmin2 = ptat22;
1221 dis = dis2;
1222 }
1223 dis2 = ptat12.Distance(ptat22);
1224 if ( dis2 < dis) {
1225 pmin1 = ptat12;
1226 pmin2 = ptat22;
1227 dis = dis2;
1228 }
1229 dis2 = ptat12.Distance(ptat21);
1230 if ( dis2 < dis) {
1231 pmin1 = ptat12;
1232 pmin2 = ptat21;
1233 dis = dis2;
1234 }
1235 myCenter.SetXYZ( (pmin1.XYZ() + pmin2.XYZ()) / 2. );
1236 }
1237 else {
1238 gp_Pnt pntOnl1 = gpl1.Location();
1239 gp_Pnt pntOnl2 = ElCLib::Value(ElCLib::Parameter(gpl1,pntOnl1),gpl2);
1240 myCenter.SetXYZ( (pntOnl1.XYZ() + pntOnl2.XYZ()) / 2. );
1241 }
1242
1243
1244 // directions
1245 gp_Dir d1,d2;
1246 if (!isInfinite1) {
1247 if (myCenter.SquareDistance(ptat11) > myCenter.SquareDistance(ptat12)) d1 = gp_Dir(gp_Vec(myCenter,ptat11));
1248 else d1 = gp_Dir(gp_Vec(myCenter,ptat12));
1249 }
1250 else d1 = gpl1.Direction();
1251
1252 if (!isInfinite2) {
1253 if (myCenter.SquareDistance(ptat21) > myCenter.SquareDistance(ptat22)) d2 = gp_Dir(gp_Vec(myCenter,ptat21));
1254 else d2 = gp_Dir(gp_Vec(myCenter,ptat22));
1255 }
1256 else d2 = gpl2.Direction();
1257
1258 gp_Dir theaxis;
1259 if ( SameLines ) theaxis = myPlane->Pln().Axis().Direction();
1260 else {
1261 theaxis = gp_Dir(d1^d2);
1262 gp_Vec V1(d1); gp_Vec V2(d2);
1263 if ( V1.CrossMagnitude(V2) < 0 ) theaxis.Reverse();
1264 }
1265
81bba717 1266 gp_Pnt curpos; // cursor position
7fd59977 1267 TColStd_Array1OfReal tabdist(1,4);
81bba717 1268 gp_Pnt P1, P2; // points at intersection of the circle with 2 straight lines
7fd59977 1269
1270 if (myAutomaticPosition) {
1271 if (!isInfinite1) {
1272 tabdist(1) = myCenter.Distance(ptat11);
1273 tabdist(2) = myCenter.Distance(ptat12);
1274 }
1275 else {
1276 tabdist(1) = tabdist(2) = 0.;
1277 }
1278 if (!isInfinite2) {
1279 tabdist(3) = myCenter.Distance(ptat21);
1280 tabdist(4) = myCenter.Distance(ptat22);
1281 }
1282 else {
1283 tabdist(3) = tabdist(4) = 0.;
1284 }
1285 if ( SameLines ) {
1286 Standard_Real dist1(RealLast());
1287 if (!isInfinite1) dist1 = Max(tabdist(1),tabdist(2));
1288 Standard_Real dist2(RealLast());
1289 if (!isInfinite2) dist2 = Max(tabdist(3),tabdist(4));
1290
1291 myFAttach = myCenter;
1292 mySAttach = myCenter;
1293 P1 = myFAttach;
1294 P2 = mySAttach;
1295
1296 myCenter.Translate(gp_Vec(d1)*theLength);
1297
81bba717 1298 // calculate attachments of the face
1299 // -> they are points of intersection if
1300 // intersection is outside of the edges
7fd59977 1301 Standard_Real pparam = ElCLib::Parameter(gpl1,myFAttach);
1302 Standard_Real pparam1 = ElCLib::Parameter(gpl1,ptat11);
1303 Standard_Real pparam2 = ElCLib::Parameter(gpl1,ptat12);
1304 if (!isInfinite1) {
1305 if ( pparam1 < pparam2 ) {
1306 if ( pparam < pparam1 ) myFAttach = ptat11;
1307 else if ( pparam > pparam2) myFAttach = ptat12;
1308 }
1309 else {
1310 if ( pparam < pparam2) myFAttach = ptat12;
1311 else if ( pparam > pparam1) myFAttach = ptat11;
1312 }
1313 }
1314 if (!isInfinite2) {
1315 pparam = ElCLib::Parameter(gpl2,myFAttach);
1316 pparam1 = ElCLib::Parameter(gpl2,ptat21);
1317 pparam2 = ElCLib::Parameter(gpl2,ptat22);
1318 if ( pparam1 < pparam2 ) {
1319 if ( pparam < pparam1 ) mySAttach = ptat21;
1320 else if ( pparam > pparam2) mySAttach = ptat22;
1321 }
1322 else {
1323 if ( pparam < pparam2) mySAttach = ptat22;
1324 else if ( pparam > pparam1) mySAttach = ptat21;
1325 }
1326 }
1327 }
1328 // Case of disconneted lines
1329 else {
1330 gp_Ax2 AX(myCenter,theaxis,d1);
1331 Handle(Geom_Circle) circle = new Geom_Circle(AX,theLength);
1332 Handle(Geom2d_Curve) geoCurve = GeomAPI::To2d(circle,myPlane->Pln());
1333 Handle(Geom2d_Circle) c2d = *((Handle(Geom2d_Circle)*)& geoCurve);
81bba717 1334 // calculate the intersection of circle with l1
1335 Standard_Real pparam; // parameter of the point of intersection on l1
7fd59977 1336 IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),c2d->Circ2d());
1337 gp_Pnt2d pint1(inter.Point(1).Value());
1338 gp_Pnt2d pint2(inter.Point(2).Value());
1339
1340 gp_Pnt Int1 = adp.Value(pint1.X(),pint1.Y());
1341 gp_Pnt Int2 = adp.Value(pint2.X(),pint2.Y());
1342 gp_Dir I1I2(gp_Vec(Int1,Int2));
1343 if ( d1*I1I2 > 0 ) {
1344 myFAttach = Int2;
1345 pparam = inter.Point(2).ParamOnFirst();
1346 }
1347 else {
1348 myFAttach = Int1;
1349 pparam = inter.Point(1).ParamOnFirst();
1350 }
1351 P1 = myFAttach;
1352
1353 Standard_Real pparam1;
1354 Standard_Real pparam2;
1355 if (!isInfinite1) {
1356 pparam1 = ElCLib::Parameter(gpl1,ptat11);
1357 pparam2 = ElCLib::Parameter(gpl1,ptat12);
1358 if ( pparam1 < pparam2 ) {
1359 if ( pparam < pparam1 ) myFAttach = ptat11;
1360 else if ( pparam > pparam2) myFAttach = ptat12;
1361 }
1362 else {
1363 if ( pparam < pparam2) myFAttach = ptat12;
1364 else if ( pparam > pparam1) myFAttach = ptat11;
1365 }
1366 }
1367 pparam = ElCLib::Parameter(gpl2,P1);
1368 mySAttach = ElCLib::Value(pparam, gpl2);
1369 P2 = mySAttach;
1370
1371 if (!isInfinite2) {
1372 pparam1 = ElCLib::Parameter(gpl2,ptat21);
1373 pparam2 = ElCLib::Parameter(gpl2,ptat22);
1374 if ( pparam1 < pparam2 ) {
1375 if ( pparam < pparam1 ) mySAttach = ptat21;
1376 else if ( pparam > pparam2) mySAttach = ptat22;
1377 }
1378 else {
1379 if ( pparam < pparam2) mySAttach = ptat22;
1380 else if ( pparam > pparam1) mySAttach = ptat21;
1381 }
1382 }
1383 }
1384 curpos.SetXYZ(.5*(P1.XYZ()+P2.XYZ()));
1385
1386 gp_Ax2 ax(myCenter,theaxis,d1);
1387 gp_Circ circle(ax,theLength);
1388 Standard_Real par = ElCLib::Parameter(circle,curpos);
1389 curpos = ElCLib::Value(par,circle);
1390
1391 if (myIsSetBndBox)
1392 curpos = AIS::TranslatePointToBound( curpos, gp_Dir( gp_Vec( myCenter, curpos ) ), myBndBox );
1393 myPosition =curpos;
1394 myAutomaticPosition = Standard_True;
1395 }
1396 else {
1397 curpos = myPosition;
1398 gp_Lin Media(myCenter, gpl1.Direction());
1399 Standard_Real pcurpos = ElCLib::Parameter(Media, curpos);
1400 myCenter = ElCLib::Value(pcurpos, Media);
81bba717 1401 // the centre is translated to avoid a constant radius!
7fd59977 1402 myCenter.Translate(-theLength*gp_Vec(gpl1.Direction()));
1403 gp_Ax2 AX(myCenter,theaxis,gpl1.Direction());
1404 Handle(Geom_Circle) circle = new Geom_Circle(AX,theLength);
1405
81bba717 1406 // re-update curpos
7fd59977 1407 pcurpos = ElCLib::Parameter(circle->Circ(), curpos);
1408 curpos = ElCLib::Value(pcurpos, circle->Circ());
1409
1410 Handle(Geom2d_Curve) geoCurve = GeomAPI::To2d(circle,myPlane->Pln());
1411 Handle(Geom2d_Circle) c2d = *((Handle(Geom2d_Circle)*)& geoCurve);
81bba717 1412 // calculate the point of intersection of circle with l1
7fd59977 1413 IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),c2d->Circ2d());
1414 gp_Pnt2d pint1(inter.Point(1).Value());
1415 gp_Pnt2d pint2(inter.Point(2).Value());
1416 gp_Pnt Int1 = adp.Value(pint1.X(),pint1.Y());
1417 gp_Pnt Int2 = adp.Value(pint2.X(),pint2.Y());
1418 if ( curpos.SquareDistance(Int1) < curpos.SquareDistance(Int2)) myFAttach = Int1;
1419 else myFAttach = Int2;
1420 P1 = myFAttach;
1421
81bba717 1422 // calculate the point of intersection of circle with l2
1423 // -> this is the projection because the centre of circle
1424 // is in the middle of l1 and l2
7fd59977 1425 Standard_Real pparam = ElCLib::Parameter(gpl2,myFAttach);
1426 mySAttach = ElCLib::Value(pparam, gpl2);
1427
1428 P2 = mySAttach;
1429
1430 Standard_Real par_attach(ElCLib::Parameter(gpl1,myFAttach));
1431 Standard_Real par1,par2;
1432 if (!isInfinite1) {
1433 par1 = ElCLib::Parameter(gpl1,ptat11);
1434 par2 = ElCLib::Parameter(gpl1,ptat12);
1435 if (par1 < par2) {
1436 if ( par_attach < par1 ) myFAttach = ptat11;
1437 else if ( par_attach > par2) myFAttach = ptat12;
1438 }
1439 else {
1440 if ( par_attach < par2 ) myFAttach = ptat12;
1441 else if ( par_attach > par1) myFAttach = ptat11;
1442 }
1443 }
1444 par_attach = ElCLib::Parameter(gpl2,mySAttach);
1445 if (!isInfinite2) {
1446 par1 = ElCLib::Parameter(gpl2,ptat21);
1447 par2 = ElCLib::Parameter(gpl2,ptat22);
1448 if (par1 < par2) {
1449 if ( par_attach < par1 ) mySAttach = ptat21;
1450 else if ( par_attach > par2) mySAttach = ptat22;
1451 }
1452 else {
1453 if ( par_attach < par2 ) mySAttach = ptat22;
1454 else if ( par_attach > par1) mySAttach = ptat21;
1455 }
1456 }
1457 }
1458
1459 myFDir = gp_Dir(gp_Vec(myCenter,P1));
1460 mySDir = gp_Dir(gp_Vec(myCenter,P2));
1461
1462 //--------------------------------------------------------
1463 // Computation of the presentation
1464 //--------------------------------------------------------
1465 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
1466 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
1467
1468 arr->SetLength(myArrowSize);
1469
1470 if (SameLines)
1471 DsgPrs_AnglePresentation::Add(aPresentation,
1472 myDrawer,
1473 myVal,
1474 myText,
1475 myCenter,
1476 myFAttach,
1477 mySAttach,
1478 myFDir,
1479 mySDir,
1480 theaxis,
1481 Standard_True,
1482 myAxis,
1483 curpos,
1484 DsgPrs_AS_NONE);
1485 else
1486 DsgPrs_AnglePresentation::Add(aPresentation,
1487 myDrawer,
1488 myVal,
1489 myText,
1490 myCenter,
1491 myFAttach,
1492 mySAttach,
1493 myFDir,
1494 mySDir,
1495 curpos,
1496 mySymbolPrs);
1497}
1498
1499
1500//=======================================================================
1501//function : Compute3DSelection
1502// purpose : compute the zones of selection for an angle dimension
1503// between 2 faces
1504//=======================================================================
1505
1506void AIS_AngleDimension::Compute3DSelection( const Handle( SelectMgr_Selection )& aSelection )
1507{
1508 gp_Circ AngleCirc, AttachCirc;
1509 Standard_Real FirstParAngleCirc, LastParAngleCirc, FirstParAttachCirc, LastParAttachCirc;
1510 gp_Pnt EndOfArrow1, EndOfArrow2, ProjAttachPoint2;
1511 gp_Dir DirOfArrow1, DirOfArrow2;
c6541a0c 1512 gp_Dir axisdir = (myVal <= Precision::Angular() || Abs( M_PI-myVal ) <= Precision::Angular())?
7fd59977 1513 myPlane->Pln().Axis().Direction() : (myFDir ^ mySDir);
1514 Standard_Boolean isPlane = (myFirstSurfType == AIS_KOS_Plane)? Standard_True : Standard_False;
1515
1516 Standard_Real ArrowLength = myDrawer->AngleAspect()->ArrowAspect()->Length();
1517 DsgPrs::ComputeFacesAnglePresentation( ArrowLength,
1518 myVal,
1519 myCenter,
1520 myFAttach,
1521 mySAttach,
1522 myFDir,
1523 mySDir,
1524 axisdir,
1525 isPlane,
1526 myAxis,
1527 myPosition,
1528 AngleCirc,
1529 FirstParAngleCirc,
1530 LastParAngleCirc,
1531 EndOfArrow1,
1532 EndOfArrow2,
1533 DirOfArrow1,
1534 DirOfArrow2,
1535 ProjAttachPoint2,
1536 AttachCirc,
1537 FirstParAttachCirc,
1538 LastParAttachCirc );
1539
1540 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
1541 Handle( Select3D_SensitiveSegment ) seg;
1542 Handle( Geom_TrimmedCurve ) curve;
1543 Handle( Select3D_SensitiveCurve ) SensCurve;
1544
1545 // Angle's arc or line
c6541a0c 1546 if (myVal > Precision::Angular() && Abs( M_PI-myVal ) > Precision::Angular())
7fd59977 1547 {
1548 curve = new Geom_TrimmedCurve( new Geom_Circle( AngleCirc ), FirstParAngleCirc, LastParAngleCirc );
1549 SensCurve = new Select3D_SensitiveCurve( own, curve );
1550 aSelection->Add( SensCurve );
1551 }
1552 else // angle's line
1553 {
1554 gp_Vec ArrowVec( DirOfArrow1 );
1555 ArrowVec *= ArrowLength;
1556 gp_Pnt FirstPoint, LastPoint;
1557
1558 if (myPosition.Distance( EndOfArrow1 ) > ArrowLength)
1559 {
1560 FirstPoint = myPosition;
1561 LastPoint = EndOfArrow1.Translated( ArrowVec );
1562 if (myPosition.SquareDistance( LastPoint ) < myPosition.SquareDistance( EndOfArrow1 ))
1563 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1564 }
1565 else
1566 {
1567 FirstPoint = EndOfArrow1.Translated( ArrowVec );
1568 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1569 }
1570 seg = new Select3D_SensitiveSegment( own, FirstPoint, LastPoint );
1571 aSelection->Add( seg );
1572 }
1573
1574 if (! myFAttach.IsEqual( EndOfArrow1, Precision::Confusion() ))
1575 {
1576 seg = new Select3D_SensitiveSegment( own, myFAttach, EndOfArrow1 );
1577 aSelection->Add( seg );
1578 }
1579 if (! ProjAttachPoint2.IsEqual( EndOfArrow2, Precision::Confusion() ))
1580 {
1581 seg = new Select3D_SensitiveSegment( own, ProjAttachPoint2, EndOfArrow2 );
1582 aSelection->Add( seg );
1583 }
1584
1585 // Line or arc from mySAttach to its "projection"
1586 if (! mySAttach.IsEqual( ProjAttachPoint2, Precision::Confusion() ))
1587 {
1588 if (isPlane)
1589 {
1590 seg = new Select3D_SensitiveSegment( own, mySAttach, ProjAttachPoint2 );
1591 aSelection->Add( seg );
1592 }
1593 else
1594 {
1595 curve = new Geom_TrimmedCurve( new Geom_Circle( AttachCirc ),
1596 FirstParAttachCirc,
1597 LastParAttachCirc );
1598 SensCurve = new Select3D_SensitiveCurve( own, curve );
1599 aSelection->Add( SensCurve );
1600 }
1601 }
1602
1603 // Text
1604 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
1605 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
1606 myPosition.X(),
1607 myPosition.Y(),
1608 myPosition.Z(),
1609 myPosition.X() + size,
1610 myPosition.Y() + size,
1611 myPosition.Z() + size);
1612 aSelection->Add(box);
1613}
1614
1615//=======================================================================
1616//function : Compute2DSelection
81bba717 1617//purpose : compute zones of selection on a side of angle between 2 edges
1618// Special processing of zero angles!
7fd59977 1619//=======================================================================
1620
1621void AIS_AngleDimension::Compute2DSelection(const Handle(SelectMgr_Selection)& aSelection)
1622{
1623 BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
1624 BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
1625
1626 gp_Lin l1(cu1.Line());
1627 gp_Lin l2(cu2.Line());
1628
1629 // it is patch!
c6541a0c 1630 if (Abs( myVal ) <= Precision::Angular() || Abs( M_PI - myVal ) <= Precision::Angular())
7fd59977 1631/*
1632 //---------------------------------------------------------
c6541a0c 1633 // Cas de droites paralleles ( <=> angle nul a M_PI pres)
7fd59977 1634 if ((Abs(l1.Angle(l2)) < Precision::Angular()) ||
c6541a0c 1635 (Abs((l1.Angle(l2) - M_PI)) < Precision::Angular()) )
7fd59977 1636*/
1637 {
1638
1639 Standard_Real distLL= l1.Distance(l2);
1640 if ( Abs(distLL) <= Precision::Confusion() ) {
1641 gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
1642 gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
1643 gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
1644 gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
1645 distLL = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1646 ComputeNull2DSelection(aSelection, distLL);
1647 }
1648 else {
1649 ComputeNull2DSelection(aSelection, distLL*8/10);
1650 }
1651 }
1652
1653 //----------------------------------------------------------
81bba717 1654 // Classic case ( angle != 0 )
7fd59977 1655 else {
1656
1657 if (myFDir.IsParallel(mySDir,Precision::Angular())) {
1658 Standard_Real distLL= l1.Distance(l2);
1659 if ( Abs(distLL) <= Precision::Confusion() ) {
1660 gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
1661 gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
1662 gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
1663 gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
1664 distLL = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1665 ComputeNull2DSelection(aSelection, distLL*8/10);
1666 }
1667 }
1668 else {
1669 gp_Dir Norm = myFDir.Crossed(mySDir);
1670
1671 gp_Ax2 ax(myCenter,Norm,myFDir);
1672 gp_Circ cer(ax,myCenter.Distance(myPosition));
1673 gp_Vec vec1(myFDir);
1674
1675 Standard_Boolean nullrad(Standard_False);
1676 if (cer.Radius() == 0.) {
1677 cer.SetRadius(1.);
1678 nullrad = Standard_True;
1679 }
1680 vec1 *= cer.Radius();
1681 gp_Pnt p1 = myCenter.Translated(vec1);
1682 gp_Vec vec2(mySDir);
1683 vec2 *= cer.Radius();
1684 gp_Pnt p2 = myCenter.Translated(vec2);
1685
1686 Standard_Real uc1 = 0.;
1687 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
1688 Standard_Real uco;
1689 if (nullrad) uco = ElCLib::Parameter(cer,p1);
1690 else uco = ElCLib::Parameter(cer,myPosition);
1691
1692 Standard_Real udeb = uc1;
1693 Standard_Real ufin = uc2;
1694
1695 if (uco > ufin) {
c6541a0c 1696 if (Abs(myVal)<M_PI) {
81bba717 1697 // test if uco is in the opposing sector
c6541a0c
D
1698 if (uco > udeb+M_PI && uco < ufin+M_PI){
1699 udeb = udeb + M_PI;
1700 ufin = ufin + M_PI;
7fd59977 1701 uc1 = udeb;
1702 uc2 = ufin;
1703 }
1704 }
1705 }
1706 if (uco > ufin) {
c6541a0c
D
1707 if ((uco-uc2) < (uc1-uco+(2*M_PI))) ufin = uco;
1708 else udeb = uco - 2*M_PI;
7fd59977 1709 }
1710 p1 = ElCLib::Value(udeb,cer);
1711 p2 = ElCLib::Value(ufin,cer);
1712
81bba717 1713 //Create 2 owners for each part of the arrow
7fd59977 1714 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1715 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1716 if (myExtShape != 0) {
1717 if (myExtShape == 1) {
1718 own1->SetShape(mySShape);
1719 own2->SetShape(mySShape);
1720 }
1721 else {
1722 own1->SetShape(myFShape);
1723 own2->SetShape(myFShape);
1724 }
1725 }
1726 else {
1727 own1->SetShape(myFShape);
1728 own2->SetShape(mySShape);
1729 }
1730
1731 Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
1732
1733 Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
1734 Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
1735
1736 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
1737 aSelection->Add(scurv);
1738 scurv = new Select3D_SensitiveCurve(own2,thecu2);
1739 aSelection->Add(scurv);
1740
1741 Handle(Select3D_SensitiveSegment) seg;
1742 if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
1743 seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
1744 aSelection->Add(seg);
1745 }
1746 if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
1747 seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
1748 aSelection->Add(seg);
1749 }
1750 }
1751 }
1752
1753}
1754//=======================================================================
1755//function : Compute2DNullSelection
1756//purpose : for dimension of null angle
1757//=======================================================================
1758
1759void AIS_AngleDimension::ComputeNull2DSelection(
1760 const Handle(SelectMgr_Selection)& aSelection,
1761 const Standard_Real distLL)
1762{
1763 gp_Dir Norm;
1764 if ( myFDir.IsParallel(mySDir, Precision::Angular()) ) {
1765 Norm = myPlane->Pln().Axis().Direction();
1766 }
1767 else
1768 Norm = myFDir.Crossed(mySDir);
1769
1770 gp_Ax2 ax(myCenter,Norm,myFDir);
1771 gp_Circ cer(ax,distLL);
1772
1773 gp_Vec vec1(myFDir);
1774 vec1 *= cer.Radius();
1775 gp_Pnt p1 = myCenter.Translated(vec1);
1776 gp_Vec vec2(mySDir);
1777 vec2 *= cer.Radius();
1778 gp_Pnt p2 = myCenter.Translated(vec2);
1779
1780 // calcul de parametres de debut et de fin des extremites de l'arc
1781 Standard_Real uc1 = 0.;
1782 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
1783 Standard_Real uco = ElCLib::Parameter(cer,myPosition);
1784
1785 Standard_Real udeb = uc1;
1786 Standard_Real ufin = uc2;
1787
1788 if (uco > ufin) {
c6541a0c 1789 if (Abs(myVal)<M_PI) {
81bba717 1790 // test if uco is in the opposing sector
c6541a0c
D
1791 if (uco > udeb+M_PI && uco < ufin+M_PI){
1792 udeb = udeb + M_PI;
1793 ufin = ufin + M_PI;
7fd59977 1794 uc1 = udeb;
1795 uc2 = ufin;
1796 }
1797 }
1798 }
1799
1800 if (uco > ufin) {
c6541a0c 1801 if ((uco-uc2) < (uc1-uco+(2*M_PI))) {
7fd59977 1802 ufin = uco;
1803 }
1804 else {
c6541a0c 1805 udeb = uco - 2*M_PI;
7fd59977 1806 }
1807 }
1808
81bba717 1809 //Create 2 owners for each part of the arrow
7fd59977 1810 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1811 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1812 if (myExtShape != 0) {
1813 if (myExtShape == 1) {
1814 own1->SetShape(mySShape);
1815 own2->SetShape(mySShape);
1816 }
1817 else {
1818 own1->SetShape(myFShape);
1819 own2->SetShape(myFShape);
1820 }
1821 }
1822 else {
1823 own1->SetShape(myFShape);
1824 own2->SetShape(mySShape);
1825 }
1826
1827 Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
1828
1829 if ( udeb != ufin ) {
1830 Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
1831 Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
1832
1833 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
1834 aSelection->Add(scurv);
1835 scurv = new Select3D_SensitiveCurve(own2,thecu2);
1836 aSelection->Add(scurv);
1837 }
1838 else {
81bba717 1839 // find end of segment to allow selection
7fd59977 1840 gp_Vec VTrans(myFDir.Crossed(Norm));
1841 Handle(Select3D_SensitiveSegment) seg1;
1842 seg1 = new Select3D_SensitiveSegment(own1,
1843 p1,
1844 p1.Translated( VTrans*distLL/10 ) );
1845 aSelection->Add(seg1);
1846 seg1 = new Select3D_SensitiveSegment(own2,
1847 p2,
1848 p2.Translated(-VTrans*distLL/10 ) );
1849 aSelection->Add(seg1);
1850 }
1851
1852 Handle(Select3D_SensitiveSegment) seg;
1853 if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
1854 seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
1855 aSelection->Add(seg);
1856 }
1857
1858 if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
1859 seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
1860 aSelection->Add(seg);
1861 }
1862}
1863
1864
1865//=======================================================================
1866//function : ComputeConeAngleSelection
1867//purpose : for cone angle
1868//=======================================================================
1869void AIS_AngleDimension::ComputeConeAngleSelection(const Handle(SelectMgr_Selection)& aSelection)
1870{
1871 if( myCone.IsNull() ) return;
1872
1873
1874 Handle( SelectMgr_EntityOwner ) owner = new SelectMgr_EntityOwner( this, 7 );
1875 Handle( Select3D_SensitiveSegment ) seg;
1876
1877 gp_Pln aPln;
1878 gp_Cone aCone;
1879 gp_Circ myCircle;
1880 gp_Pnt Apex;
1881 Handle( Geom_Surface ) aSurf; //a surface from the Face
1882 Handle( Geom_OffsetSurface ) aOffsetSurf;
1883 Handle( Geom_ConicalSurface ) aConicalSurf;
1884 Handle( Geom_SurfaceOfRevolution ) aRevSurf;
1885 Handle( Geom_Line ) aLine;
1886 BRepAdaptor_Surface tmpSurf(myCone);
1887 TopoDS_Face aFace;
1888 AIS_KindOfSurface aSurfType;
1889 Standard_Real Offset = 0. ;
1890 Handle( Standard_Type ) aType;
1891
1892 Standard_Real maxV = tmpSurf.FirstVParameter();
1893 Standard_Real minV = tmpSurf.LastVParameter();
1894
1895 AIS::GetPlaneFromFace( myCone, aPln, aSurf, aSurfType, Offset );
1896
1897 if ( aSurfType == AIS_KOS_Revolution ) { //surface of revolution
1898
1899 aRevSurf = Handle( Geom_SurfaceOfRevolution )::DownCast( aSurf );
1900 gp_Lin ln( aRevSurf->Axis() );
1901 Handle( Geom_Curve ) tmpCrv = aRevSurf->BasisCurve();
1902 if ( tmpCrv ->DynamicType() != STANDARD_TYPE(Geom_Line) ) return; //Must be a part of line
1903
1904 Standard_Real par;
1905 gp_Pnt fst = tmpSurf.Value(0., minV);
1906 gp_Pnt lst = tmpSurf.Value(0., maxV);
1907
1908 gp_Vec vec1(fst, lst);
1909
1910 par = ElCLib::Parameter( ln, fst );
1911 gp_Pnt fst2 = ElCLib::Value( par, ln ); //projection fst on ln
1912 par = ElCLib::Parameter( ln, lst );
1913 gp_Pnt lst2 = ElCLib::Value( par, ln ); //projection lst on ln
1914
1915 gp_Vec vec2(fst2, lst2);
1916
1917 // Check if two parts of revolution are parallel ( it's a cylinder ) or normal (it's a circle )
1918 if( vec1.IsParallel( vec2,Precision::Angular() ) || vec1.IsNormal( vec2,Precision::Angular() ) ) return;
1919
1920 gce_MakeCone mkCone(aRevSurf->Axis(), fst, lst);
1921 aCone = mkCone.Value();
1922 Apex = aCone.Apex();
1923 }
1924 else {
1925 aType = aSurf->DynamicType();
1926 if ( aType == STANDARD_TYPE(Geom_OffsetSurface) || Offset > 0.01 ) { //offset surface
1927 aOffsetSurf = new Geom_OffsetSurface (aSurf, Offset);
1928 aSurf = aOffsetSurf->Surface();
1c72dff6 1929 BRepBuilderAPI_MakeFace mkFace(aSurf, Precision::Confusion());
7fd59977 1930 mkFace.Build();
1931 if( !mkFace.IsDone() ) return;
1932 tmpSurf.Initialize( mkFace.Face() );
1933 }
1934
1935 aCone = tmpSurf.Cone();
1936 aConicalSurf = Handle( Geom_ConicalSurface)::DownCast( aSurf );
1937 Apex = aConicalSurf->Apex();
1938 }
1939
1940 Handle(Geom_Curve) aCurve; //A circle where the angle is drawn
1941
1942 if ( myAutomaticPosition ) {
1943 Standard_Real midV = ( minV + maxV ) / 2.5;
1944
1945 aCurve = aSurf->VIso(midV);
1946 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1947
c6541a0c 1948 myPosition = ElCLib::Value(M_PI / 2.0, myCircle);
7fd59977 1949 myAutomaticPosition = Standard_False;
1950 }
1951 else {
1952 Standard_Real U, V;
1953 ElSLib::Parameters(aCone, myPosition, U, V);
1954 aCurve = aSurf->VIso(V);
1955 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1956 }
1957 //__________________________________________________________________
1958 aCurve = aSurf->VIso(maxV);
1959 gp_Circ CircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1960 aCurve = aSurf->VIso(minV);
1961 gp_Circ CircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1962 //__________________________________________________________________
1963
1964 if( CircVmax.Radius() < CircVmin.Radius() ) {
1965 gp_Circ tmpCirc = CircVmax;
1966 CircVmax = CircVmin;
1967 CircVmin = tmpCirc;
1968 }
1969
1970 Standard_Boolean IsArrowOut = Standard_True; //Is arrows inside or outside of the cone
1971 //Standard_Real PntOnMainAxis = 0; //Is projection of aPosition inside of the cone = 0, above = 1, or below = -1
1972 Standard_Boolean IsConeTrimmed = Standard_False;
1973
1974 if( CircVmin.Radius() > 0.01 ) IsConeTrimmed = Standard_True;
1975
1976 gp_Pnt AttachmentPnt;
1977 gp_Pnt OppositePnt;
1978 gp_Pnt aPnt, tmpPnt;
1979 Quantity_Length X,Y,Z;
1980
1981 Standard_Real param = ElCLib::Parameter(myCircle, myPosition);
1982
1983 aPnt = Apex;
1984 gp_Pnt P1 = ElCLib::Value(0., myCircle);
c6541a0c 1985 gp_Pnt P2 = ElCLib::Value(M_PI, myCircle);
7fd59977 1986
1987 gce_MakePln mkPln(P1, P2, aPnt); // create a plane whitch defines plane for projection aPosition on it
1988
1989 aPnt = AIS::ProjectPointOnPlane(myPosition, mkPln.Value());
1990 tmpPnt = aPnt;
1991
1992 if( aPnt.Distance(P1) < aPnt.Distance(P2) ){
1993 AttachmentPnt = P1;
1994 OppositePnt = P2;
1995 }
1996 else {
1997 AttachmentPnt = P2;
1998 OppositePnt = P1;
1999 }
2000
2001 aPnt = AttachmentPnt ; // Creating of circle whitch defines a plane for a dimension arc
2002 gp_Vec Vec(AttachmentPnt, Apex); // Dimension arc is a part of the circle
2003 Vec.Scale(2);
2004 aPnt.Translate(Vec);
2005 GC_MakeCircle mkCirc(AttachmentPnt, OppositePnt, aPnt);
2006 gp_Circ aCircle2 = mkCirc.Value()->Circ();
2007
2008
2009 Standard_Integer i;
2010 Standard_Real AttParam = ElCLib::Parameter(aCircle2, AttachmentPnt);
2011 Standard_Real OppParam = ElCLib::Parameter(aCircle2, OppositePnt);
2012
c6541a0c
D
2013 while ( AttParam >= 2 * M_PI ) AttParam -= 2 * M_PI;
2014 while ( OppParam >= 2 * M_PI ) OppParam -= 2 * M_PI;
7fd59977 2015
2016 if( myPosition.Distance( myCircle.Location() ) <= myCircle.Radius() )
2017 if( 2 * myCircle.Radius() > aCircle2.Radius() * 0.4 ) IsArrowOut = Standard_False; //four times more than an arrow size
2018
2019 Graphic3d_Array1OfVertex V(1, 12);
2020
2021 Standard_Real angle;
2022 param = ElCLib::Parameter(aCircle2, tmpPnt);
2023
2024 if(IsArrowOut) {
c6541a0c
D
2025 angle = OppParam - AttParam + M_PI / 6; //An angle between AttParam and OppParam + 30 degrees
2026 param = AttParam - M_PI / 12; //out parts of dimension line are 15 degrees
7fd59977 2027
c6541a0c 2028 while ( angle > 2 * M_PI ) angle -= 2 * M_PI;
7fd59977 2029 for( i = 0; i <= 11; i++ ) { //calculating of arc
2030 aPnt = ElCLib::Value(param + angle/11 * i, aCircle2);
2031 aPnt.Coord(X, Y, Z);
2032 V(i+1).SetCoord(X, Y, Z);
2033 }
2034
2035 }
2036 else {
2037 angle = OppParam - AttParam;
2038 param = AttParam;
c6541a0c 2039 while ( angle > 2 * M_PI ) angle -= 2 * M_PI;
7fd59977 2040 for( i = 0; i <= 11; i++ ) { //calculating of arc
2041 aPnt = ElCLib::Value(param + angle/11 * i, aCircle2);
2042 aPnt.Coord(X, Y, Z);
2043 V(i+1).SetCoord(X, Y, Z);
2044 }
2045 }
2046
2047 for(i = 1; i<=11; i++) {
2048
2049 V(i).Coord(X, Y, Z);
2050 P1.SetCoord(X, Y, Z);
2051 V(i+1).Coord(X, Y, Z);
2052 P1.SetCoord(X, Y, Z);
2053
2054 seg = new Select3D_SensitiveSegment(owner, P1, P2);
2055 aSelection->Add(seg);
2056 }
2057
2058 tmpPnt = tmpPnt.Translated(gp_Vec(0, 0, -1)*2);
2059
2060 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
2061 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( owner,
2062 tmpPnt.X(),
2063 tmpPnt.Y(),
2064 tmpPnt.Z(),
2065 tmpPnt.X() + size,
2066 tmpPnt.Y() + size,
2067 tmpPnt.Z() + size);
2068 aSelection->Add(box);
2069}
2070
2071
2072