1 // File: AIS_AngleDimension.cdl
2 // Created: Tue Dec 5 15:09:04 1996
3 // Author: Arnaud BOUZY/Odile Olivier
6 #define BUC60655 //GG 22/03/00 Enable to compute correctly
7 // the arrow size at object creation time.
9 #define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
10 // if any in all dimensions.
12 #include <Standard_NotImplemented.hxx>
14 #include <AIS_AngleDimension.ixx>
17 #include <AIS_DimensionOwner.hxx>
18 #include <AIS_Drawer.hxx>
20 #include <BRepBuilderAPI_MakeFace.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <BRep_Tool.hxx>
26 #include <DsgPrs_AnglePresentation.hxx>
31 #include <Geom2d_Circle.hxx>
32 #include <Geom2d_Curve.hxx>
33 #include <Geom2d_Line.hxx>
34 #include <GeomAPI.hxx>
35 #include <Geom_Circle.hxx>
36 #include <Geom_Line.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Geom_TrimmedCurve.hxx>
39 #include <Geom_Surface.hxx>
40 #include <Geom_CylindricalSurface.hxx>
41 #include <Geom_ConicalSurface.hxx>
42 #include <Geom_SurfaceOfRevolution.hxx>
43 #include <Geom_SurfaceOfLinearExtrusion.hxx>
44 #include <Geom_OffsetSurface.hxx>
46 #include <IntAna2d_AnaIntersection.hxx>
47 #include <IntAna2d_IntPoint.hxx>
48 #include <IntAna_QuadQuadGeo.hxx>
49 #include <IntAna_ResultType.hxx>
51 #include <Precision.hxx>
53 #include <ProjLib.hxx>
55 #include <Prs3d_AngleAspect.hxx>
56 #include <Prs3d_ArrowAspect.hxx>
57 #include <Prs3d_Drawer.hxx>
59 #include <Select3D_SensitiveCurve.hxx>
60 #include <Select3D_SensitiveSegment.hxx>
61 #include <Select3D_SensitiveBox.hxx>
62 #include <SelectMgr_EntityOwner.hxx>
64 #include <TColStd_Array1OfReal.hxx>
67 #include <TopExp_Explorer.hxx>
69 #include <TopoDS_Shape.hxx>
70 #include <TopoDS_Vertex.hxx>
72 #include <UnitsAPI.hxx>
77 #include <gp_Cone.hxx>
80 #include <gp_Pnt2d.hxx>
84 #include <GC_MakeCircle.hxx>
85 #include <GC_MakeConicalSurface.hxx>
86 #include <gce_MakePln.hxx>
87 #include <gce_MakeCone.hxx>
88 #include <Graphic3d_Array1OfVertex.hxx>
90 //=======================================================================
91 //function : Constructor
92 //purpose : ConeAngle dimension
93 //=======================================================================
95 AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aCone,
96 const Standard_Real aVal,
97 const TCollection_ExtendedString& aText,
98 const gp_Pnt& aPosition,
99 const DsgPrs_ArrowSide /*aSymbolPrs*/,
100 const Standard_Real anArrowSize):
106 myPosition = aPosition;
107 mySymbolPrs = DsgPrs_AS_BOTHAR;
108 myAutomaticPosition = Standard_True;
110 SetArrowSize( anArrowSize );
112 myArrowSize = anArrowSize;
116 //=======================================================================
117 //function : Constructor
118 //purpose : ConeAngle dimension
119 //=======================================================================
121 AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aCone,
122 const Standard_Real aVal,
123 const TCollection_ExtendedString& aText):
127 cout << "Call new AngleDimension for cone's angle" << endl;
130 gp_Pnt tmpPnt(0., 0., 0.);
136 mySymbolPrs = DsgPrs_AS_BOTHAR;
137 myAutomaticPosition = Standard_True;
144 //=======================================================================
145 //function : Constructor
146 //purpose : TwoEdgesAngle dimension
147 //=======================================================================
150 AIS_AngleDimension::AIS_AngleDimension(const TopoDS_Edge& aFirstEdge,
151 const TopoDS_Edge& aSecondEdge,
152 const Handle (Geom_Plane)& aPlane,
153 const Standard_Real aVal,
154 const TCollection_ExtendedString& aText)
159 cout << endl << "Call new AngleDimension for edges, default" << endl;
162 myFShape = aFirstEdge;
163 mySShape = aSecondEdge;
167 mySymbolPrs = DsgPrs_AS_BOTHAR;
168 myAutomaticPosition = Standard_True;
170 myArrowSize = myVal / 100.;
173 //=======================================================================
174 //function : Constructor
175 //purpose : TwoEdgesAngle dimension (avec position et texte)
176 //=======================================================================
178 AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Edge& aFirstEdge,
179 const TopoDS_Edge& aSecondEdge,
180 const Handle (Geom_Plane)& aPlane,
181 const Standard_Real aVal,
182 const TCollection_ExtendedString& aText,
183 const gp_Pnt& aPosition,
184 const DsgPrs_ArrowSide aSymbolPrs,
185 const Standard_Real anArrowSize):
189 cout << endl << "Call new AngleDimension for edges" << endl;
192 myFShape = aFirstEdge;
193 mySShape = aSecondEdge;
197 mySymbolPrs = aSymbolPrs;
198 myAutomaticPosition = Standard_False;
200 SetArrowSize( anArrowSize );
202 myArrowSize = anArrowSize;
204 myPosition = aPosition;
208 //=======================================================================
209 //function : Constructor
210 //purpose : TwoPlanarFacesAngle dimension
211 //=======================================================================
213 AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFirstFace,
214 const TopoDS_Face& aSecondFace,
215 const gp_Ax1& anAxis,
216 const Standard_Real aVal,
217 const TCollection_ExtendedString& aText):
222 cout << endl << "Call new AngleDimension for planar faces, default" << endl;
225 myFShape = aFirstFace;
226 mySShape = aSecondFace;
228 AIS::GetPlaneFromFace( aFirstFace, myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
229 AIS::GetPlaneFromFace( aSecondFace, mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );
231 //POP init champ myPlane
232 myPlane = new Geom_Plane(myFirstPlane);
236 mySymbolPrs = DsgPrs_AS_BOTHAR;
237 myAutomaticPosition = Standard_True;
239 myArrowSize = myVal / 100.;
242 //=======================================================================
243 //function : Constructor
244 //purpose : TwoPlanarFacesAngle dimension (avec position et texte)
245 //=======================================================================
247 AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFirstFace,
248 const TopoDS_Face& aSecondFace,
249 const gp_Ax1& anAxis,
250 const Standard_Real aVal,
251 const TCollection_ExtendedString& aText,
252 const gp_Pnt& aPosition,
253 const DsgPrs_ArrowSide aSymbolPrs,
254 const Standard_Real anArrowSize):
259 cout << endl << "Call new AngleDimension for planar faces" << endl;
262 myFShape = aFirstFace;
263 mySShape = aSecondFace;
265 AIS::GetPlaneFromFace( aFirstFace, myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
266 AIS::GetPlaneFromFace( aSecondFace, mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );
268 //POP init champ myPlane
269 myPlane = new Geom_Plane(myFirstPlane);
273 mySymbolPrs = aSymbolPrs;
274 myAutomaticPosition = Standard_False;
276 SetArrowSize( anArrowSize );
278 myArrowSize = anArrowSize;
280 myPosition = aPosition;
284 //=======================================================================
285 //function : AIS_AngleDimension
286 //purpose : Two curvilinear faces dimension
287 //=======================================================================
289 AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFFace,
290 const TopoDS_Face& aSFace,
291 const Standard_Real aVal,
292 const TCollection_ExtendedString& aText ):
296 cout << endl << "Call new AngleDimension for curvilinear faces, default" << endl;
299 SetFirstShape( aFFace );
300 SetSecondShape( aSFace );
304 mySymbolPrs = DsgPrs_AS_BOTHAR;
305 myAutomaticPosition = Standard_True;
307 myArrowSize = myVal / 100.;
310 //=======================================================================
311 //function : AIS_AngleDimension
313 //=======================================================================
315 AIS_AngleDimension::AIS_AngleDimension( const TopoDS_Face& aFFace,
316 const TopoDS_Face& aSFace,
317 const Standard_Real aVal,
318 const TCollection_ExtendedString& aText,
319 const gp_Pnt& aPosition,
320 const DsgPrs_ArrowSide aSymbolPrs,
321 const Standard_Real anArrowSize):
325 cout << endl << "Call new AngleDimension for curvilinear faces" << endl;
328 SetFirstShape( aFFace );
329 SetSecondShape( aSFace );
333 mySymbolPrs = DsgPrs_AS_BOTHAR;
334 myAutomaticPosition = Standard_True;
336 mySymbolPrs = aSymbolPrs;
337 myAutomaticPosition = Standard_False;
339 SetArrowSize( anArrowSize );
341 myArrowSize = anArrowSize;
343 myPosition = aPosition;
347 //=======================================================================
348 //function : SetConeFace
350 //=======================================================================
352 void AIS_AngleDimension::SetConeFace( const TopoDS_Face& aConeFace )
355 myAutomaticPosition = Standard_True;
359 //=======================================================================
360 //function : SetFirstShape
362 //=======================================================================
364 void AIS_AngleDimension::SetFirstShape( const TopoDS_Shape& aFShape )
368 if (myFShape.ShapeType() == TopAbs_FACE)
370 AIS::GetPlaneFromFace( TopoDS::Face( myFShape ),
376 if (myFirstSurfType == AIS_KOS_Cylinder)
377 myAxis = (Handle( Geom_CylindricalSurface )::DownCast( myFirstBasisSurf ))->Cylinder().Axis();
378 else if (myFirstSurfType == AIS_KOS_Cone)
379 myAxis = (Handle( Geom_ConicalSurface )::DownCast( myFirstBasisSurf ))->Cone().Axis();
380 else if (myFirstSurfType == AIS_KOS_Revolution)
381 myAxis = (Handle( Geom_SurfaceOfRevolution )::DownCast( myFirstBasisSurf ))->Axis();
382 else if (myFirstSurfType == AIS_KOS_Extrusion)
384 myAxis.SetDirection((Handle( Geom_SurfaceOfLinearExtrusion )::DownCast( myFirstBasisSurf ))
386 //myAxis.SetLocation( ??? );
391 //=======================================================================
392 //function : SetSecondShape
394 //=======================================================================
396 void AIS_AngleDimension::SetSecondShape( const TopoDS_Shape& aSShape )
400 if (myFShape.ShapeType() == TopAbs_FACE)
401 AIS::GetPlaneFromFace( TopoDS::Face( mySShape ),
411 ///=======================================================================
414 //=======================================================================
416 void AIS_AngleDimension::Compute(const Handle(PrsMgr_PresentationManager3d)&,
417 const Handle(Prs3d_Presentation)& aPresentation,
418 const Standard_Integer)
420 aPresentation->Clear();
424 // cout << "Computing for cone' angle " << endl;
425 ComputeConeAngle(aPresentation);
428 switch (myFShape.ShapeType()) {
431 // cas angle entre deux faces
432 ComputeTwoFacesAngle(aPresentation);
437 // cas angle entre deux edges
438 ComputeTwoEdgesAngle(aPresentation);
447 //=======================================================================
449 //purpose : : to avoid warning
450 //=======================================================================
452 void AIS_AngleDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
453 const Handle(Prs3d_Presentation)& aPresentation)
455 // Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
456 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
459 //=======================================================================
461 //purpose : : to avoid warning
462 //=======================================================================
464 void AIS_AngleDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
465 const Handle(Graphic2d_GraphicObject)& aGraphicObject,
466 const Standard_Integer anInteger)
468 // Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
469 PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
472 void AIS_AngleDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
474 // Standard_NotImplemented::Raise("AIS_AngleDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
475 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
478 //=======================================================================
479 //function : ComputeSelection
481 //=======================================================================
483 void AIS_AngleDimension::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
484 const Standard_Integer)
487 if ( myNbShape == 1 )
489 // cout << "Computing selection for cone's angle " << endl;
490 ComputeConeAngleSelection(aSelection);
495 if (myFShape.IsNull()) return;
497 if (myFShape.ShapeType() == TopAbs_FACE )
498 Compute3DSelection(aSelection);
500 Compute2DSelection(aSelection);
503 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
504 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
505 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
509 myPosition.X() + size,
510 myPosition.Y() + size,
511 myPosition.Z() + size);
512 aSelection->Add(box);
515 //=======================================================================
516 //function : ComputeConeAngle
518 //=======================================================================
520 void AIS_AngleDimension::ComputeConeAngle(const Handle(Prs3d_Presentation)& aPresentation)
522 if( myCone.IsNull() ) return;
528 Handle( Geom_Surface ) aSurf; //a surface from the Face
529 Handle( Geom_OffsetSurface ) aOffsetSurf;
530 Handle( Geom_ConicalSurface ) aConicalSurf;
531 Handle( Geom_SurfaceOfRevolution ) aRevSurf;
532 Handle( Geom_Line ) aLine;
533 BRepAdaptor_Surface tmpSurf(myCone);
535 AIS_KindOfSurface aSurfType;
536 Standard_Real Offset = 0. ;
537 Handle( Standard_Type ) aType;
539 Standard_Real maxV = tmpSurf.FirstVParameter();
540 Standard_Real minV = tmpSurf.LastVParameter();
543 AIS::GetPlaneFromFace( myCone, aPln, aSurf, aSurfType, Offset );
545 if ( aSurfType == AIS_KOS_Revolution ) { //surface of revolution
547 aRevSurf = Handle( Geom_SurfaceOfRevolution )::DownCast( aSurf );
548 gp_Lin ln( aRevSurf->Axis() );
549 Handle( Geom_Curve ) tmpCrv = aRevSurf->BasisCurve();
550 if ( tmpCrv ->DynamicType() != STANDARD_TYPE(Geom_Line) ) return; //Must be a part of line
553 gp_Pnt fst = tmpSurf.Value(0., minV);
554 gp_Pnt lst = tmpSurf.Value(0., maxV);
556 gp_Vec vec1(fst, lst);
558 par = ElCLib::Parameter( ln, fst );
559 gp_Pnt fst2 = ElCLib::Value( par, ln ); //projection fst on ln
560 par = ElCLib::Parameter( ln, lst );
561 gp_Pnt lst2 = ElCLib::Value( par, ln ); //projection lst on ln
563 gp_Vec vec2(fst2, lst2);
565 // Check if two parts of revolution are parallel ( it's a cylinder ) or normal (it's a circle )
566 if( vec1.IsParallel( vec2,Precision::Angular() ) || vec1.IsNormal( vec2,Precision::Angular() ) ) return;
568 gce_MakeCone mkCone(aRevSurf->Axis(), fst, lst);
569 aCone = mkCone.Value();
573 aType = aSurf->DynamicType();
574 if ( aType == STANDARD_TYPE(Geom_OffsetSurface) || Offset > 0.01 ) { //offset surface
575 aOffsetSurf = new Geom_OffsetSurface (aSurf, Offset);
576 aSurf = aOffsetSurf->Surface();
577 BRepBuilderAPI_MakeFace mkFace(aSurf);
579 if( !mkFace.IsDone() ) return;
580 tmpSurf.Initialize( mkFace.Face() );
583 aCone = tmpSurf.Cone();
584 aConicalSurf = Handle( Geom_ConicalSurface)::DownCast( aSurf );
585 Apex = aConicalSurf->Apex();
588 Handle(Geom_Curve) aCurve; //A circle where the angle is drawn
589 if ( myAutomaticPosition ) {
590 Standard_Real midV = ( minV + maxV ) / 2.5;
592 aCurve = aSurf->VIso(midV);
593 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
595 myPosition = ElCLib::Value(Standard_PI/2.0, myCircle);
596 myAutomaticPosition = Standard_False;
600 ElSLib::Parameters(aCone, myPosition, U, V);
601 aCurve = aSurf->VIso(V);
602 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
605 //__________________________________________________________________
606 aCurve = aSurf->VIso(maxV);
607 gp_Circ CircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
608 aCurve = aSurf->VIso(minV);
609 gp_Circ CircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
610 //__________________________________________________________________
612 if( CircVmax.Radius() < CircVmin.Radius() ) {
613 gp_Circ tmpCirc = CircVmax;
618 DsgPrs_AnglePresentation::Add(aPresentation, myDrawer, myVal,
619 myText, myCircle, myPosition, Apex, CircVmin, CircVmax, myArrowSize);
620 // cout << "ComputeConeAngle is over" << endl;
624 //=======================================================================
625 //function : ComputeTwoFacesAngle
627 //=======================================================================
629 void AIS_AngleDimension::ComputeTwoFacesAngle(const Handle(Prs3d_Presentation)& aPresentation)
631 if (myFirstSurfType == AIS_KOS_Plane)
632 ComputeTwoPlanarFacesAngle( aPresentation );
634 ComputeTwoCurvilinearFacesAngle( aPresentation );
637 //=======================================================================
638 //function : ComputeTwoCurvilinearFacesAngle
640 //=======================================================================
642 void AIS_AngleDimension::ComputeTwoCurvilinearFacesAngle(const Handle(Prs3d_Presentation)& aPresentation)
644 AIS::ComputeAngleBetweenCurvilinearFaces( TopoDS::Face( myFShape ),
645 TopoDS::Face( mySShape ),
660 if (myAutomaticPosition && myIsSetBndBox)
661 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCenter, myPosition ) ), myBndBox );
663 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
664 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
666 if( !myArrowSizeIsDefined ) {
668 Standard_Real arrsize = myCenter.Distance( myPosition );
670 if ( (myArrowSize-arrsize) < 0.1 ) arrsize = myArrowSize;
671 if (arrsize == 0.) arrsize = 1.;
673 myArrowSize = arrsize;
675 arr->SetLength( myArrowSize );
677 arr->SetLength(arrsize);
681 if (myVal <= Precision::Angular() || Abs( PI-myVal ) <= Precision::Angular())
682 DsgPrs_AnglePresentation::Add(aPresentation,
691 myPlane->Pln().Axis().Direction(),
692 Standard_False, // not plane
697 DsgPrs_AnglePresentation::Add(aPresentation,
707 Standard_False, // not plane
713 //=======================================================================
714 //function : ComputeTwoPlanarFacesAngle
716 //=======================================================================
718 void AIS_AngleDimension::ComputeTwoPlanarFacesAngle( const Handle( Prs3d_Presentation )& aPresentation )
720 AIS::ComputeAngleBetweenPlanarFaces( TopoDS::Face( myFShape ),
721 TopoDS::Face( mySShape ),
732 if (myAutomaticPosition && myIsSetBndBox)
733 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCenter, myPosition ) ), myBndBox );
735 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
736 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
738 if( !myArrowSizeIsDefined ) {
740 Standard_Real arrsize = myCenter.Distance( myPosition );
742 if ( (myArrowSize-arrsize) < 0.1 ) arrsize = myArrowSize;
743 if (arrsize == 0.) arrsize = 1.;
745 myArrowSize = arrsize;
747 arr->SetLength( myArrowSize );
749 arr->SetLength(arrsize);
753 DsgPrs_AnglePresentation::Add(aPresentation,
770 //=======================================================================
771 //function : ComputeTwoEdgesAngle
773 //=======================================================================
775 void AIS_AngleDimension::ComputeTwoEdgesAngle(const Handle(Prs3d_Presentation)& aPresentation)
777 BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
778 BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
779 if ((cu1.GetType() != GeomAbs_Line) || (cu2.GetType() != GeomAbs_Line)) return;
782 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
783 TopoDS_Face face(makeface.Face());
784 BRepAdaptor_Surface adp(makeface.Face());
787 Handle(Geom_Line) geom_lin1,geom_lin2;
788 gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
789 Standard_Boolean isInfinite1,isInfinite2;
790 Handle(Geom_Curve) extCurv;
791 Standard_Integer copyOfMyExtShape = myExtShape;
792 if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),
793 TopoDS::Edge(mySShape),
807 // Temporary: computation of myVal
808 // myVal = Abs(geom_lin1->Lin().Angle( geom_lin2->Lin())); // Pb with angles JPR
810 if (copyOfMyExtShape != 0) myExtShape = copyOfMyExtShape;
812 // 2d lines => projection of 3d on current plane
815 Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(geom_lin1,myPlane->Pln());
816 Handle(Geom2d_Line) lin1_2d = *((Handle(Geom2d_Line)*)& geoC1);
817 Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(geom_lin2,myPlane->Pln());
818 Handle(Geom2d_Line) lin2_2d = *((Handle(Geom2d_Line)*)& geoC2);
821 if( !myArrowSizeIsDefined ) {
823 Standard_Real arrSize1(myArrowSize),arrSize2(myArrowSize);
824 if (!isInfinite1) arrSize1 = ptat11.Distance(ptat12)/100.;
825 if (!isInfinite2) arrSize2 = ptat21.Distance(ptat22)/100.;
827 myArrowSize = Min(myArrowSize,Max(arrSize1,arrSize2));
829 myArrowSize = Min(myArrowSize,Min(arrSize1,arrSize2));
836 // Processing in case of 2 parallel straight lines
837 if (lin1_2d->Lin2d().Direction()
838 .IsParallel(lin2_2d->Lin2d().Direction(),Precision::Angular())) {
839 ComputeTwoEdgesNullAngle(aPresentation,
844 isInfinite1,isInfinite2);
847 // Processing in case of 2 non-parallel straight lines
849 ComputeTwoEdgesNotNullAngle(aPresentation,
856 isInfinite1,isInfinite2);
858 if ( (myExtShape != 0) && !extCurv.IsNull()) {
860 if ( myExtShape == 1 ) {
865 aPresentation->SetInfiniteState(isInfinite1);
866 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(myFShape),geom_lin1,pf,pl);
873 aPresentation->SetInfiniteState(isInfinite2);
874 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(mySShape),geom_lin2,pf,pl);
880 //=======================================================================
881 //function : ComputeTwoEdgesNotNullAngle
883 //=======================================================================
885 void AIS_AngleDimension::ComputeTwoEdgesNotNullAngle(const Handle(Prs3d_Presentation)& aPresentation,
886 const Handle(Geom_Line)& l1,
887 const Handle(Geom_Line)& l2,
888 const gp_Pnt& ptat11,
889 const gp_Pnt& ptat12,
890 const gp_Pnt& ptat21,
891 const gp_Pnt& ptat22,
892 const Standard_Boolean isInfinite1,
893 const Standard_Boolean isInfinite2)
896 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
897 TopoDS_Face face(makeface.Face());
898 BRepAdaptor_Surface adp(makeface.Face());
899 // 2d lines => projection of 3d on current plane
900 Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(l1,myPlane->Pln());
901 const Handle(Geom2d_Line)& l1_2d = *((Handle(Geom2d_Line)*)& geoC1);
902 Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(l2,myPlane->Pln());
903 const Handle(Geom2d_Line)& l2_2d = *((Handle(Geom2d_Line)*)& geoC2);
905 //----------------------------------------------------------
906 // Computation of myCenter
907 //----------------------------------------------------------
908 IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),l2_2d->Lin2d());
909 if (!inter.IsDone()) return;
910 if (!inter.NbPoints()) return;
912 gp_Pnt2d pint(inter.Point(1).Value());
913 myCenter = adp.Value(pint.X(),pint.Y());
915 //----------------------------------------------------------
916 // Computation of the 2 directions
917 //----------------------------------------------------------
920 if (myCenter.SquareDistance(ptat11) > myCenter.SquareDistance(ptat12)) d1 = gp_Dir(gp_Vec(myCenter,ptat11));
921 else d1 = gp_Dir(gp_Vec(myCenter,ptat12));
923 else d1 = l1->Lin().Direction();
926 if (myCenter.SquareDistance(ptat21) > myCenter.SquareDistance(ptat22)) d2 = gp_Dir(gp_Vec(myCenter,ptat21));
927 else d2 = gp_Dir(gp_Vec(myCenter,ptat22));
929 else d2 = l2->Lin().Direction();
931 Standard_Boolean In1(Standard_False);
932 Standard_Boolean In2(Standard_False);
933 if ( !(Abs(d1.Angle(d2) - Abs(myVal)) <= Precision::Confusion())
934 && (Abs(myVal) < PI) ) {
935 Standard_Real parcent1 = ElCLib::Parameter(l1->Lin(), myCenter);
936 Standard_Real par11 = ElCLib::Parameter(l1->Lin(), ptat11);
937 Standard_Real par12 = ElCLib::Parameter(l1->Lin(), ptat12);
938 if ( par11 < par12) {
939 if ( ( parcent1> par11) && (parcent1< par12)) {
945 if ( ( parcent1> par12) && (parcent1< par11)) {
960 gp_Lin gpl1 = l1->Lin();
961 gp_Lin gpl2 = l2->Lin();
962 theaxis = gp_Lin(myCenter,myFDir^mySDir);
969 TColStd_Array1OfReal tabdist(1,4);
971 tabdist(1) = theaxis.Distance(ptat11);
972 tabdist(2) = theaxis.Distance(ptat12);
975 tabdist(1) = tabdist(2) = 0.;
979 tabdist(3) = theaxis.Distance(ptat21);
980 tabdist(4) = theaxis.Distance(ptat22);
983 tabdist(3) = tabdist(4) = 0.;
986 if (myAutomaticPosition) {
987 Standard_Real length_1(RealLast());
988 if (!isInfinite1) length_1 = .75*Abs(tabdist(2)-tabdist(1))+Min(tabdist(1),tabdist(2));
990 Standard_Real length_2(RealLast());
991 if (!isInfinite2) length_2 = .75*Abs(tabdist(4)-tabdist(3))+Min(tabdist(3),tabdist(4));
992 Standard_Real theLength(Min(length_1,length_2));
993 if (Precision::IsInfinite(theLength)) theLength = 50.;
995 myFAttach = myCenter.Translated(gp_Vec(d1)*theLength);
996 mySAttach = myCenter.Translated(gp_Vec(d2)*theLength);
999 Standard_Real par_p1_attach(ElCLib::Parameter(gpl1,myFAttach));
1000 Standard_Real par11 = ElCLib::Parameter(gpl1,ptat11);
1001 Standard_Real par12 = ElCLib::Parameter(gpl1,ptat12);
1002 if (par_p1_attach > par11 && par_p1_attach > par12) {
1003 par_p1_attach = Max(par11,par12);
1004 myFAttach = ElCLib::Value(par_p1_attach,gpl1);
1006 else if (par_p1_attach < par11 && par_p1_attach < par12) {
1007 par_p1_attach = Min(par11,par12);
1008 myFAttach = ElCLib::Value(par_p1_attach,gpl1);
1013 Standard_Real par_p2_attach(ElCLib::Parameter(gpl2,mySAttach));
1014 Standard_Real par21 = ElCLib::Parameter(gpl2,ptat21);
1015 Standard_Real par22 = ElCLib::Parameter(gpl2,ptat22);
1016 if (par_p2_attach > par21 && par_p2_attach > par22) {
1017 par_p2_attach = Max(par21,par22);
1018 mySAttach = ElCLib::Value(par_p2_attach,gpl2);
1020 else if (par_p2_attach < par21 && par_p2_attach < par22) {
1021 par_p2_attach = Min(par21,par22);
1022 mySAttach = ElCLib::Value(par_p2_attach,gpl2);
1025 if ( myVal < PI) curpos.SetXYZ(.5*(myFAttach.XYZ()+mySAttach.XYZ()));
1027 curpos.SetXYZ(.5*(myFAttach.XYZ()+mySAttach.XYZ()));
1028 gp_Vec transl(curpos, myCenter);
1030 curpos.Translate(transl);
1033 gp_Ax2 ax(myCenter,myFDir.Crossed(mySDir),myFDir);
1034 gp_Circ circle(ax,theLength);
1035 Standard_Real par = ElCLib::Parameter(circle,curpos);
1036 curpos = ElCLib::Value(par,circle);
1038 // small offset like in LengthDimension
1039 gp_Vec transl(myCenter, curpos);
1041 curpos.Translate(transl);
1044 curpos = AIS::TranslatePointToBound( curpos, gp_Dir( gp_Vec( myCenter, curpos ) ), myBndBox );
1046 myPosition = curpos;
1047 myAutomaticPosition = Standard_True;
1051 // point is projected on the plane
1052 gp_Pnt2d pointOnPln(ProjLib::Project(myPlane->Pln(),myPosition));
1053 myPosition = BRepAdaptor_Surface(BRepBuilderAPI_MakeFace(myPlane->Pln()).Face()).Value(pointOnPln.X(),pointOnPln.Y());
1054 curpos = myPosition;
1055 Standard_Real dist(curpos.Distance(myCenter));
1056 if (dist<=Precision::Confusion()) {
1057 gp_XYZ delta(1.,1.,1.);
1058 curpos.SetXYZ(curpos.XYZ()+delta);
1059 dist = curpos.Distance(myCenter);
1061 // To learn if it is necessary to take distance -dist or not
1062 // it is necessary to know if we are in the sector opposite to the angle
1063 // if not : we are in the opposite sector if the coordinates
1064 // of curpos in point (d1,d2) are negative
1065 gp_Ax2 ax(myCenter,myFDir.Crossed(mySDir),myFDir);
1066 gp_Circ circle(ax,dist);
1068 // gp_Pnt p1(myCenter.Translated(gp_Vec(d1)*dist));
1070 gp_Pnt p2(myCenter.Translated(gp_Vec(d2)*dist));
1071 Standard_Real uc1 = 0;
1072 Standard_Real uc2 = ElCLib::Parameter(circle, p2 );
1073 Standard_Real uco = ElCLib::Parameter(circle, curpos );
1074 Standard_Real udeb = uc1;
1075 Standard_Real ufin = uc2;
1077 if (Abs(myVal)<PI) {
1078 // test if uco is in the opposite sector
1079 if (uco > udeb+PI && uco < ufin+PI){
1085 gp_Pnt p1_attach(myCenter.Translated(gp_Vec(d1)*dist));
1086 gp_Pnt p2_attach(myCenter.Translated(gp_Vec(d2)*dist));
1089 Standard_Real par_p1_attach(ElCLib::Parameter(gpl1,p1_attach));
1090 Standard_Real par11 = ElCLib::Parameter(gpl1,ptat11);
1091 Standard_Real par12 = ElCLib::Parameter(gpl1,ptat12);
1092 if (par_p1_attach > par11 && par_p1_attach > par12) {
1093 par_p1_attach = Max(par11,par12);
1094 p1_attach = ElCLib::Value(par_p1_attach,gpl1);
1096 else if (par_p1_attach < par11 && par_p1_attach < par12) {
1097 par_p1_attach = Min(par11,par12);
1098 p1_attach = ElCLib::Value(par_p1_attach,gpl1);
1101 myFAttach = p1_attach;
1104 Standard_Real par_p2_attach(ElCLib::Parameter(gpl2,p2_attach));
1105 Standard_Real par21 = ElCLib::Parameter(gpl2,ptat21);
1106 Standard_Real par22 = ElCLib::Parameter(gpl2,ptat22);
1107 if (par_p2_attach > par21 && par_p2_attach > par22) {
1108 par_p2_attach = Max(par21,par22);
1109 p2_attach = ElCLib::Value(par_p2_attach,gpl2);
1111 else if (par_p2_attach < par21 && par_p2_attach < par22) {
1112 par_p2_attach = Min(par21,par22);
1113 p2_attach = ElCLib::Value(par_p2_attach,gpl2);
1116 mySAttach = p2_attach;
1118 myAxis = theaxis.Position();
1120 //--------------------------------------------------------
1121 // Computation of the presentation
1122 //--------------------------------------------------------
1123 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
1124 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
1126 arr->SetLength(myArrowSize);
1128 DsgPrs_AnglePresentation::Add(aPresentation,
1143 //=======================================================================
1144 //function : ComputeTwoEdgesNullAngle
1145 //purpose : compute the presentation of a angle dimension if it's null.
1146 // -> the aim of the computation is to have a constant radius
1147 // during the dimension moving : the radius is independant
1148 // of the cursor position, it's equal to a arbitrary value
1149 //=======================================================================
1151 void AIS_AngleDimension::ComputeTwoEdgesNullAngle(const Handle(Prs3d_Presentation)& aPresentation,
1152 const Handle(Geom_Line)& l1,
1153 const Handle(Geom_Line)& l2,
1154 const gp_Pnt& ptat11,
1155 const gp_Pnt& ptat12,
1156 const gp_Pnt& ptat21,
1157 const gp_Pnt& ptat22,
1158 const Standard_Boolean isInfinite1,
1159 const Standard_Boolean isInfinite2)
1162 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
1163 TopoDS_Face face(makeface.Face());
1164 BRepAdaptor_Surface adp(makeface.Face());
1165 // 2d lines => projection of 3d on current plane
1166 Handle(Geom2d_Curve) geoC1 = GeomAPI::To2d(l1,myPlane->Pln());
1167 Handle(Geom2d_Line) l1_2d = *((Handle(Geom2d_Line)*)& geoC1);
1168 Handle(Geom2d_Curve) geoC2 = GeomAPI::To2d(l2,myPlane->Pln());
1169 Handle(Geom2d_Line) l2_2d = *((Handle(Geom2d_Line)*)& geoC2);
1171 gp_Lin gpl1 = l1->Lin();
1172 gp_Lin gpl2 = l2->Lin();
1174 //------------------------------------------------------------
1175 // Computation of myCenter
1176 // -> Point located on the median of 2 straight lines,
1177 // is calculated as located between 2 closest points
1178 // of each straight line.
1179 //-----------------------------------------------------------
1180 // theLength : radius of the future circle
1181 Standard_Real theLength = gpl1.Distance(gpl2.Location());
1182 // processing of the particular case when 2 straight lines are coincident
1183 Standard_Boolean SameLines(Standard_False);
1184 if ( theLength <= Precision::Confusion()) {
1185 SameLines = Standard_True;
1187 if (!isInfinite2) theLength = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1188 else theLength = 0.75*ptat11.Distance(ptat12);
1191 if (!isInfinite2) theLength = 0.75*ptat21.Distance(ptat22);
1192 else theLength = 50.;
1195 else theLength = theLength*8/10;
1197 gp_Pnt pmin1 ,pmin2;
1198 if (!isInfinite1 && !isInfinite2) {
1199 pmin1 = ptat11; pmin2 = ptat21;
1200 Standard_Real dis = ptat11.Distance(ptat21);
1201 Standard_Real dis2 = ptat11.Distance(ptat22);
1207 dis2 = ptat12.Distance(ptat22);
1213 dis2 = ptat12.Distance(ptat21);
1219 myCenter.SetXYZ( (pmin1.XYZ() + pmin2.XYZ()) / 2. );
1222 gp_Pnt pntOnl1 = gpl1.Location();
1223 gp_Pnt pntOnl2 = ElCLib::Value(ElCLib::Parameter(gpl1,pntOnl1),gpl2);
1224 myCenter.SetXYZ( (pntOnl1.XYZ() + pntOnl2.XYZ()) / 2. );
1231 if (myCenter.SquareDistance(ptat11) > myCenter.SquareDistance(ptat12)) d1 = gp_Dir(gp_Vec(myCenter,ptat11));
1232 else d1 = gp_Dir(gp_Vec(myCenter,ptat12));
1234 else d1 = gpl1.Direction();
1237 if (myCenter.SquareDistance(ptat21) > myCenter.SquareDistance(ptat22)) d2 = gp_Dir(gp_Vec(myCenter,ptat21));
1238 else d2 = gp_Dir(gp_Vec(myCenter,ptat22));
1240 else d2 = gpl2.Direction();
1243 if ( SameLines ) theaxis = myPlane->Pln().Axis().Direction();
1245 theaxis = gp_Dir(d1^d2);
1246 gp_Vec V1(d1); gp_Vec V2(d2);
1247 if ( V1.CrossMagnitude(V2) < 0 ) theaxis.Reverse();
1250 gp_Pnt curpos; // cursor position
1251 TColStd_Array1OfReal tabdist(1,4);
1252 gp_Pnt P1, P2; // points at intersection of the circle with 2 straight lines
1254 if (myAutomaticPosition) {
1256 tabdist(1) = myCenter.Distance(ptat11);
1257 tabdist(2) = myCenter.Distance(ptat12);
1260 tabdist(1) = tabdist(2) = 0.;
1263 tabdist(3) = myCenter.Distance(ptat21);
1264 tabdist(4) = myCenter.Distance(ptat22);
1267 tabdist(3) = tabdist(4) = 0.;
1270 Standard_Real dist1(RealLast());
1271 if (!isInfinite1) dist1 = Max(tabdist(1),tabdist(2));
1272 Standard_Real dist2(RealLast());
1273 if (!isInfinite2) dist2 = Max(tabdist(3),tabdist(4));
1275 myFAttach = myCenter;
1276 mySAttach = myCenter;
1280 myCenter.Translate(gp_Vec(d1)*theLength);
1282 // calculate attachments of the face
1283 // -> they are points of intersection if
1284 // intersection is outside of the edges
1285 Standard_Real pparam = ElCLib::Parameter(gpl1,myFAttach);
1286 Standard_Real pparam1 = ElCLib::Parameter(gpl1,ptat11);
1287 Standard_Real pparam2 = ElCLib::Parameter(gpl1,ptat12);
1289 if ( pparam1 < pparam2 ) {
1290 if ( pparam < pparam1 ) myFAttach = ptat11;
1291 else if ( pparam > pparam2) myFAttach = ptat12;
1294 if ( pparam < pparam2) myFAttach = ptat12;
1295 else if ( pparam > pparam1) myFAttach = ptat11;
1299 pparam = ElCLib::Parameter(gpl2,myFAttach);
1300 pparam1 = ElCLib::Parameter(gpl2,ptat21);
1301 pparam2 = ElCLib::Parameter(gpl2,ptat22);
1302 if ( pparam1 < pparam2 ) {
1303 if ( pparam < pparam1 ) mySAttach = ptat21;
1304 else if ( pparam > pparam2) mySAttach = ptat22;
1307 if ( pparam < pparam2) mySAttach = ptat22;
1308 else if ( pparam > pparam1) mySAttach = ptat21;
1312 // Case of disconneted lines
1314 gp_Ax2 AX(myCenter,theaxis,d1);
1315 Handle(Geom_Circle) circle = new Geom_Circle(AX,theLength);
1316 Handle(Geom2d_Curve) geoCurve = GeomAPI::To2d(circle,myPlane->Pln());
1317 Handle(Geom2d_Circle) c2d = *((Handle(Geom2d_Circle)*)& geoCurve);
1318 // calculate the intersection of circle with l1
1319 Standard_Real pparam; // parameter of the point of intersection on l1
1320 IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),c2d->Circ2d());
1321 gp_Pnt2d pint1(inter.Point(1).Value());
1322 gp_Pnt2d pint2(inter.Point(2).Value());
1324 gp_Pnt Int1 = adp.Value(pint1.X(),pint1.Y());
1325 gp_Pnt Int2 = adp.Value(pint2.X(),pint2.Y());
1326 gp_Dir I1I2(gp_Vec(Int1,Int2));
1327 if ( d1*I1I2 > 0 ) {
1329 pparam = inter.Point(2).ParamOnFirst();
1333 pparam = inter.Point(1).ParamOnFirst();
1337 Standard_Real pparam1;
1338 Standard_Real pparam2;
1340 pparam1 = ElCLib::Parameter(gpl1,ptat11);
1341 pparam2 = ElCLib::Parameter(gpl1,ptat12);
1342 if ( pparam1 < pparam2 ) {
1343 if ( pparam < pparam1 ) myFAttach = ptat11;
1344 else if ( pparam > pparam2) myFAttach = ptat12;
1347 if ( pparam < pparam2) myFAttach = ptat12;
1348 else if ( pparam > pparam1) myFAttach = ptat11;
1351 pparam = ElCLib::Parameter(gpl2,P1);
1352 mySAttach = ElCLib::Value(pparam, gpl2);
1356 pparam1 = ElCLib::Parameter(gpl2,ptat21);
1357 pparam2 = ElCLib::Parameter(gpl2,ptat22);
1358 if ( pparam1 < pparam2 ) {
1359 if ( pparam < pparam1 ) mySAttach = ptat21;
1360 else if ( pparam > pparam2) mySAttach = ptat22;
1363 if ( pparam < pparam2) mySAttach = ptat22;
1364 else if ( pparam > pparam1) mySAttach = ptat21;
1368 curpos.SetXYZ(.5*(P1.XYZ()+P2.XYZ()));
1370 gp_Ax2 ax(myCenter,theaxis,d1);
1371 gp_Circ circle(ax,theLength);
1372 Standard_Real par = ElCLib::Parameter(circle,curpos);
1373 curpos = ElCLib::Value(par,circle);
1376 curpos = AIS::TranslatePointToBound( curpos, gp_Dir( gp_Vec( myCenter, curpos ) ), myBndBox );
1378 myAutomaticPosition = Standard_True;
1381 curpos = myPosition;
1382 gp_Lin Media(myCenter, gpl1.Direction());
1383 Standard_Real pcurpos = ElCLib::Parameter(Media, curpos);
1384 myCenter = ElCLib::Value(pcurpos, Media);
1385 // the centre is translated to avoid a constant radius!
1386 myCenter.Translate(-theLength*gp_Vec(gpl1.Direction()));
1387 gp_Ax2 AX(myCenter,theaxis,gpl1.Direction());
1388 Handle(Geom_Circle) circle = new Geom_Circle(AX,theLength);
1391 pcurpos = ElCLib::Parameter(circle->Circ(), curpos);
1392 curpos = ElCLib::Value(pcurpos, circle->Circ());
1394 Handle(Geom2d_Curve) geoCurve = GeomAPI::To2d(circle,myPlane->Pln());
1395 Handle(Geom2d_Circle) c2d = *((Handle(Geom2d_Circle)*)& geoCurve);
1396 // calculate the point of intersection of circle with l1
1397 IntAna2d_AnaIntersection inter(l1_2d->Lin2d(),c2d->Circ2d());
1398 gp_Pnt2d pint1(inter.Point(1).Value());
1399 gp_Pnt2d pint2(inter.Point(2).Value());
1400 gp_Pnt Int1 = adp.Value(pint1.X(),pint1.Y());
1401 gp_Pnt Int2 = adp.Value(pint2.X(),pint2.Y());
1402 if ( curpos.SquareDistance(Int1) < curpos.SquareDistance(Int2)) myFAttach = Int1;
1403 else myFAttach = Int2;
1406 // calculate the point of intersection of circle with l2
1407 // -> this is the projection because the centre of circle
1408 // is in the middle of l1 and l2
1409 Standard_Real pparam = ElCLib::Parameter(gpl2,myFAttach);
1410 mySAttach = ElCLib::Value(pparam, gpl2);
1414 Standard_Real par_attach(ElCLib::Parameter(gpl1,myFAttach));
1415 Standard_Real par1,par2;
1417 par1 = ElCLib::Parameter(gpl1,ptat11);
1418 par2 = ElCLib::Parameter(gpl1,ptat12);
1420 if ( par_attach < par1 ) myFAttach = ptat11;
1421 else if ( par_attach > par2) myFAttach = ptat12;
1424 if ( par_attach < par2 ) myFAttach = ptat12;
1425 else if ( par_attach > par1) myFAttach = ptat11;
1428 par_attach = ElCLib::Parameter(gpl2,mySAttach);
1430 par1 = ElCLib::Parameter(gpl2,ptat21);
1431 par2 = ElCLib::Parameter(gpl2,ptat22);
1433 if ( par_attach < par1 ) mySAttach = ptat21;
1434 else if ( par_attach > par2) mySAttach = ptat22;
1437 if ( par_attach < par2 ) mySAttach = ptat22;
1438 else if ( par_attach > par1) mySAttach = ptat21;
1443 myFDir = gp_Dir(gp_Vec(myCenter,P1));
1444 mySDir = gp_Dir(gp_Vec(myCenter,P2));
1446 //--------------------------------------------------------
1447 // Computation of the presentation
1448 //--------------------------------------------------------
1449 Handle(Prs3d_AngleAspect) la = myDrawer->AngleAspect();
1450 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
1452 arr->SetLength(myArrowSize);
1455 DsgPrs_AnglePresentation::Add(aPresentation,
1470 DsgPrs_AnglePresentation::Add(aPresentation,
1484 //=======================================================================
1485 //function : Compute3DSelection
1486 // purpose : compute the zones of selection for an angle dimension
1488 //=======================================================================
1490 void AIS_AngleDimension::Compute3DSelection( const Handle( SelectMgr_Selection )& aSelection )
1492 gp_Circ AngleCirc, AttachCirc;
1493 Standard_Real FirstParAngleCirc, LastParAngleCirc, FirstParAttachCirc, LastParAttachCirc;
1494 gp_Pnt EndOfArrow1, EndOfArrow2, ProjAttachPoint2;
1495 gp_Dir DirOfArrow1, DirOfArrow2;
1496 gp_Dir axisdir = (myVal <= Precision::Angular() || Abs( PI-myVal ) <= Precision::Angular())?
1497 myPlane->Pln().Axis().Direction() : (myFDir ^ mySDir);
1498 Standard_Boolean isPlane = (myFirstSurfType == AIS_KOS_Plane)? Standard_True : Standard_False;
1500 Standard_Real ArrowLength = myDrawer->AngleAspect()->ArrowAspect()->Length();
1501 DsgPrs::ComputeFacesAnglePresentation( ArrowLength,
1522 LastParAttachCirc );
1524 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
1525 Handle( Select3D_SensitiveSegment ) seg;
1526 Handle( Geom_TrimmedCurve ) curve;
1527 Handle( Select3D_SensitiveCurve ) SensCurve;
1529 // Angle's arc or line
1530 if (myVal > Precision::Angular() && Abs( PI-myVal ) > Precision::Angular())
1532 curve = new Geom_TrimmedCurve( new Geom_Circle( AngleCirc ), FirstParAngleCirc, LastParAngleCirc );
1533 SensCurve = new Select3D_SensitiveCurve( own, curve );
1534 aSelection->Add( SensCurve );
1536 else // angle's line
1538 gp_Vec ArrowVec( DirOfArrow1 );
1539 ArrowVec *= ArrowLength;
1540 gp_Pnt FirstPoint, LastPoint;
1542 if (myPosition.Distance( EndOfArrow1 ) > ArrowLength)
1544 FirstPoint = myPosition;
1545 LastPoint = EndOfArrow1.Translated( ArrowVec );
1546 if (myPosition.SquareDistance( LastPoint ) < myPosition.SquareDistance( EndOfArrow1 ))
1547 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1551 FirstPoint = EndOfArrow1.Translated( ArrowVec );
1552 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1554 seg = new Select3D_SensitiveSegment( own, FirstPoint, LastPoint );
1555 aSelection->Add( seg );
1558 if (! myFAttach.IsEqual( EndOfArrow1, Precision::Confusion() ))
1560 seg = new Select3D_SensitiveSegment( own, myFAttach, EndOfArrow1 );
1561 aSelection->Add( seg );
1563 if (! ProjAttachPoint2.IsEqual( EndOfArrow2, Precision::Confusion() ))
1565 seg = new Select3D_SensitiveSegment( own, ProjAttachPoint2, EndOfArrow2 );
1566 aSelection->Add( seg );
1569 // Line or arc from mySAttach to its "projection"
1570 if (! mySAttach.IsEqual( ProjAttachPoint2, Precision::Confusion() ))
1574 seg = new Select3D_SensitiveSegment( own, mySAttach, ProjAttachPoint2 );
1575 aSelection->Add( seg );
1579 curve = new Geom_TrimmedCurve( new Geom_Circle( AttachCirc ),
1581 LastParAttachCirc );
1582 SensCurve = new Select3D_SensitiveCurve( own, curve );
1583 aSelection->Add( SensCurve );
1588 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
1589 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
1593 myPosition.X() + size,
1594 myPosition.Y() + size,
1595 myPosition.Z() + size);
1596 aSelection->Add(box);
1599 //=======================================================================
1600 //function : Compute2DSelection
1601 //purpose : compute zones of selection on a side of angle between 2 edges
1602 // Special processing of zero angles!
1603 //=======================================================================
1605 void AIS_AngleDimension::Compute2DSelection(const Handle(SelectMgr_Selection)& aSelection)
1607 BRepAdaptor_Curve cu1(TopoDS::Edge(myFShape));
1608 BRepAdaptor_Curve cu2(TopoDS::Edge(mySShape));
1610 gp_Lin l1(cu1.Line());
1611 gp_Lin l2(cu2.Line());
1614 if (Abs( myVal ) <= Precision::Angular() || Abs( PI - myVal ) <= Precision::Angular())
1616 //---------------------------------------------------------
1617 // Cas de droites paralleles ( <=> angle nul a PI pres)
1618 if ((Abs(l1.Angle(l2)) < Precision::Angular()) ||
1619 (Abs((l1.Angle(l2) - PI)) < Precision::Angular()) )
1623 Standard_Real distLL= l1.Distance(l2);
1624 if ( Abs(distLL) <= Precision::Confusion() ) {
1625 gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
1626 gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
1627 gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
1628 gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
1629 distLL = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1630 ComputeNull2DSelection(aSelection, distLL);
1633 ComputeNull2DSelection(aSelection, distLL*8/10);
1637 //----------------------------------------------------------
1638 // Classic case ( angle != 0 )
1641 if (myFDir.IsParallel(mySDir,Precision::Angular())) {
1642 Standard_Real distLL= l1.Distance(l2);
1643 if ( Abs(distLL) <= Precision::Confusion() ) {
1644 gp_Pnt ptat11 = cu1.Value(cu1.FirstParameter());
1645 gp_Pnt ptat12 = cu1.Value(cu1.LastParameter());
1646 gp_Pnt ptat21 = cu2.Value(cu2.FirstParameter());
1647 gp_Pnt ptat22 = cu2.Value(cu2.LastParameter());
1648 distLL = 0.75 * Max( ptat11.Distance(ptat12), ptat21.Distance(ptat22));
1649 ComputeNull2DSelection(aSelection, distLL*8/10);
1653 gp_Dir Norm = myFDir.Crossed(mySDir);
1655 gp_Ax2 ax(myCenter,Norm,myFDir);
1656 gp_Circ cer(ax,myCenter.Distance(myPosition));
1657 gp_Vec vec1(myFDir);
1659 Standard_Boolean nullrad(Standard_False);
1660 if (cer.Radius() == 0.) {
1662 nullrad = Standard_True;
1664 vec1 *= cer.Radius();
1665 gp_Pnt p1 = myCenter.Translated(vec1);
1666 gp_Vec vec2(mySDir);
1667 vec2 *= cer.Radius();
1668 gp_Pnt p2 = myCenter.Translated(vec2);
1670 Standard_Real uc1 = 0.;
1671 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
1673 if (nullrad) uco = ElCLib::Parameter(cer,p1);
1674 else uco = ElCLib::Parameter(cer,myPosition);
1676 Standard_Real udeb = uc1;
1677 Standard_Real ufin = uc2;
1680 if (Abs(myVal)<PI) {
1681 // test if uco is in the opposing sector
1682 if (uco > udeb+PI && uco < ufin+PI){
1691 if ((uco-uc2) < (uc1-uco+(2*PI))) ufin = uco;
1692 else udeb = uco - 2*PI;
1694 p1 = ElCLib::Value(udeb,cer);
1695 p2 = ElCLib::Value(ufin,cer);
1697 //Create 2 owners for each part of the arrow
1698 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1699 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1700 if (myExtShape != 0) {
1701 if (myExtShape == 1) {
1702 own1->SetShape(mySShape);
1703 own2->SetShape(mySShape);
1706 own1->SetShape(myFShape);
1707 own2->SetShape(myFShape);
1711 own1->SetShape(myFShape);
1712 own2->SetShape(mySShape);
1715 Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
1717 Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
1718 Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
1720 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
1721 aSelection->Add(scurv);
1722 scurv = new Select3D_SensitiveCurve(own2,thecu2);
1723 aSelection->Add(scurv);
1725 Handle(Select3D_SensitiveSegment) seg;
1726 if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
1727 seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
1728 aSelection->Add(seg);
1730 if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
1731 seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
1732 aSelection->Add(seg);
1738 //=======================================================================
1739 //function : Compute2DNullSelection
1740 //purpose : for dimension of null angle
1741 //=======================================================================
1743 void AIS_AngleDimension::ComputeNull2DSelection(
1744 const Handle(SelectMgr_Selection)& aSelection,
1745 const Standard_Real distLL)
1748 if ( myFDir.IsParallel(mySDir, Precision::Angular()) ) {
1749 Norm = myPlane->Pln().Axis().Direction();
1752 Norm = myFDir.Crossed(mySDir);
1754 gp_Ax2 ax(myCenter,Norm,myFDir);
1755 gp_Circ cer(ax,distLL);
1757 gp_Vec vec1(myFDir);
1758 vec1 *= cer.Radius();
1759 gp_Pnt p1 = myCenter.Translated(vec1);
1760 gp_Vec vec2(mySDir);
1761 vec2 *= cer.Radius();
1762 gp_Pnt p2 = myCenter.Translated(vec2);
1764 // calcul de parametres de debut et de fin des extremites de l'arc
1765 Standard_Real uc1 = 0.;
1766 Standard_Real uc2 = ElCLib::Parameter(cer,p2);
1767 Standard_Real uco = ElCLib::Parameter(cer,myPosition);
1769 Standard_Real udeb = uc1;
1770 Standard_Real ufin = uc2;
1773 if (Abs(myVal)<PI) {
1774 // test if uco is in the opposing sector
1775 if (uco > udeb+PI && uco < ufin+PI){
1785 if ((uco-uc2) < (uc1-uco+(2*PI))) {
1793 //Create 2 owners for each part of the arrow
1794 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1795 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1796 if (myExtShape != 0) {
1797 if (myExtShape == 1) {
1798 own1->SetShape(mySShape);
1799 own2->SetShape(mySShape);
1802 own1->SetShape(myFShape);
1803 own2->SetShape(myFShape);
1807 own1->SetShape(myFShape);
1808 own2->SetShape(mySShape);
1811 Handle(Geom_Circle) thecirc = new Geom_Circle(cer);
1813 if ( udeb != ufin ) {
1814 Handle(Geom_TrimmedCurve) thecu1 = new Geom_TrimmedCurve(thecirc,udeb,(udeb+ufin)/2);
1815 Handle(Geom_TrimmedCurve) thecu2 = new Geom_TrimmedCurve(thecirc,(udeb+ufin)/2,ufin);
1817 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own1,thecu1);
1818 aSelection->Add(scurv);
1819 scurv = new Select3D_SensitiveCurve(own2,thecu2);
1820 aSelection->Add(scurv);
1823 // find end of segment to allow selection
1824 gp_Vec VTrans(myFDir.Crossed(Norm));
1825 Handle(Select3D_SensitiveSegment) seg1;
1826 seg1 = new Select3D_SensitiveSegment(own1,
1828 p1.Translated( VTrans*distLL/10 ) );
1829 aSelection->Add(seg1);
1830 seg1 = new Select3D_SensitiveSegment(own2,
1832 p2.Translated(-VTrans*distLL/10 ) );
1833 aSelection->Add(seg1);
1836 Handle(Select3D_SensitiveSegment) seg;
1837 if (!myFAttach.IsEqual(p1,Precision::Confusion())) {
1838 seg = new Select3D_SensitiveSegment(own1,myFAttach,p1);
1839 aSelection->Add(seg);
1842 if (!mySAttach.IsEqual(p2,Precision::Confusion())) {
1843 seg = new Select3D_SensitiveSegment(own2,mySAttach,p2);
1844 aSelection->Add(seg);
1849 //=======================================================================
1850 //function : ComputeConeAngleSelection
1851 //purpose : for cone angle
1852 //=======================================================================
1853 void AIS_AngleDimension::ComputeConeAngleSelection(const Handle(SelectMgr_Selection)& aSelection)
1855 if( myCone.IsNull() ) return;
1858 Handle( SelectMgr_EntityOwner ) owner = new SelectMgr_EntityOwner( this, 7 );
1859 Handle( Select3D_SensitiveSegment ) seg;
1865 Handle( Geom_Surface ) aSurf; //a surface from the Face
1866 Handle( Geom_OffsetSurface ) aOffsetSurf;
1867 Handle( Geom_ConicalSurface ) aConicalSurf;
1868 Handle( Geom_SurfaceOfRevolution ) aRevSurf;
1869 Handle( Geom_Line ) aLine;
1870 BRepAdaptor_Surface tmpSurf(myCone);
1872 AIS_KindOfSurface aSurfType;
1873 Standard_Real Offset = 0. ;
1874 Handle( Standard_Type ) aType;
1876 Standard_Real maxV = tmpSurf.FirstVParameter();
1877 Standard_Real minV = tmpSurf.LastVParameter();
1879 AIS::GetPlaneFromFace( myCone, aPln, aSurf, aSurfType, Offset );
1881 if ( aSurfType == AIS_KOS_Revolution ) { //surface of revolution
1883 aRevSurf = Handle( Geom_SurfaceOfRevolution )::DownCast( aSurf );
1884 gp_Lin ln( aRevSurf->Axis() );
1885 Handle( Geom_Curve ) tmpCrv = aRevSurf->BasisCurve();
1886 if ( tmpCrv ->DynamicType() != STANDARD_TYPE(Geom_Line) ) return; //Must be a part of line
1889 gp_Pnt fst = tmpSurf.Value(0., minV);
1890 gp_Pnt lst = tmpSurf.Value(0., maxV);
1892 gp_Vec vec1(fst, lst);
1894 par = ElCLib::Parameter( ln, fst );
1895 gp_Pnt fst2 = ElCLib::Value( par, ln ); //projection fst on ln
1896 par = ElCLib::Parameter( ln, lst );
1897 gp_Pnt lst2 = ElCLib::Value( par, ln ); //projection lst on ln
1899 gp_Vec vec2(fst2, lst2);
1901 // Check if two parts of revolution are parallel ( it's a cylinder ) or normal (it's a circle )
1902 if( vec1.IsParallel( vec2,Precision::Angular() ) || vec1.IsNormal( vec2,Precision::Angular() ) ) return;
1904 gce_MakeCone mkCone(aRevSurf->Axis(), fst, lst);
1905 aCone = mkCone.Value();
1906 Apex = aCone.Apex();
1909 aType = aSurf->DynamicType();
1910 if ( aType == STANDARD_TYPE(Geom_OffsetSurface) || Offset > 0.01 ) { //offset surface
1911 aOffsetSurf = new Geom_OffsetSurface (aSurf, Offset);
1912 aSurf = aOffsetSurf->Surface();
1913 BRepBuilderAPI_MakeFace mkFace(aSurf);
1915 if( !mkFace.IsDone() ) return;
1916 tmpSurf.Initialize( mkFace.Face() );
1919 aCone = tmpSurf.Cone();
1920 aConicalSurf = Handle( Geom_ConicalSurface)::DownCast( aSurf );
1921 Apex = aConicalSurf->Apex();
1924 Handle(Geom_Curve) aCurve; //A circle where the angle is drawn
1926 if ( myAutomaticPosition ) {
1927 Standard_Real midV = ( minV + maxV ) / 2.5;
1929 aCurve = aSurf->VIso(midV);
1930 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1932 myPosition = ElCLib::Value(Standard_PI / 2.0, myCircle);
1933 myAutomaticPosition = Standard_False;
1937 ElSLib::Parameters(aCone, myPosition, U, V);
1938 aCurve = aSurf->VIso(V);
1939 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1941 //__________________________________________________________________
1942 aCurve = aSurf->VIso(maxV);
1943 gp_Circ CircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1944 aCurve = aSurf->VIso(minV);
1945 gp_Circ CircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ();
1946 //__________________________________________________________________
1948 if( CircVmax.Radius() < CircVmin.Radius() ) {
1949 gp_Circ tmpCirc = CircVmax;
1950 CircVmax = CircVmin;
1954 Standard_Boolean IsArrowOut = Standard_True; //Is arrows inside or outside of the cone
1955 //Standard_Real PntOnMainAxis = 0; //Is projection of aPosition inside of the cone = 0, above = 1, or below = -1
1956 Standard_Boolean IsConeTrimmed = Standard_False;
1958 if( CircVmin.Radius() > 0.01 ) IsConeTrimmed = Standard_True;
1960 gp_Pnt AttachmentPnt;
1962 gp_Pnt aPnt, tmpPnt;
1963 Quantity_Length X,Y,Z;
1965 Standard_Real param = ElCLib::Parameter(myCircle, myPosition);
1968 gp_Pnt P1 = ElCLib::Value(0., myCircle);
1969 gp_Pnt P2 = ElCLib::Value(Standard_PI, myCircle);
1971 gce_MakePln mkPln(P1, P2, aPnt); // create a plane whitch defines plane for projection aPosition on it
1973 aPnt = AIS::ProjectPointOnPlane(myPosition, mkPln.Value());
1976 if( aPnt.Distance(P1) < aPnt.Distance(P2) ){
1985 aPnt = AttachmentPnt ; // Creating of circle whitch defines a plane for a dimension arc
1986 gp_Vec Vec(AttachmentPnt, Apex); // Dimension arc is a part of the circle
1988 aPnt.Translate(Vec);
1989 GC_MakeCircle mkCirc(AttachmentPnt, OppositePnt, aPnt);
1990 gp_Circ aCircle2 = mkCirc.Value()->Circ();
1994 Standard_Real AttParam = ElCLib::Parameter(aCircle2, AttachmentPnt);
1995 Standard_Real OppParam = ElCLib::Parameter(aCircle2, OppositePnt);
1997 while ( AttParam >= 2*Standard_PI ) AttParam -= 2*Standard_PI;
1998 while ( OppParam >= 2*Standard_PI ) OppParam -= 2*Standard_PI;
2000 if( myPosition.Distance( myCircle.Location() ) <= myCircle.Radius() )
2001 if( 2 * myCircle.Radius() > aCircle2.Radius() * 0.4 ) IsArrowOut = Standard_False; //four times more than an arrow size
2003 Graphic3d_Array1OfVertex V(1, 12);
2005 Standard_Real angle;
2006 param = ElCLib::Parameter(aCircle2, tmpPnt);
2009 angle = OppParam - AttParam + Standard_PI/6; //An angle between AttParam and OppParam + 30 degrees
2010 param = AttParam - Standard_PI/12; //out parts of dimension line are 15 degrees
2012 while ( angle > 2*Standard_PI ) angle -= 2*Standard_PI;
2013 for( i = 0; i <= 11; i++ ) { //calculating of arc
2014 aPnt = ElCLib::Value(param + angle/11 * i, aCircle2);
2015 aPnt.Coord(X, Y, Z);
2016 V(i+1).SetCoord(X, Y, Z);
2021 angle = OppParam - AttParam;
2023 while ( angle > 2*Standard_PI ) angle -= 2*Standard_PI;
2024 for( i = 0; i <= 11; i++ ) { //calculating of arc
2025 aPnt = ElCLib::Value(param + angle/11 * i, aCircle2);
2026 aPnt.Coord(X, Y, Z);
2027 V(i+1).SetCoord(X, Y, Z);
2031 for(i = 1; i<=11; i++) {
2033 V(i).Coord(X, Y, Z);
2034 P1.SetCoord(X, Y, Z);
2035 V(i+1).Coord(X, Y, Z);
2036 P1.SetCoord(X, Y, Z);
2038 seg = new Select3D_SensitiveSegment(owner, P1, P2);
2039 aSelection->Add(seg);
2042 tmpPnt = tmpPnt.Translated(gp_Vec(0, 0, -1)*2);
2044 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
2045 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( owner,
2052 aSelection->Add(box);