1 // File: AIS_DiameterDimension.cdl
2 // Created: Tue Dec 5 15:09:04 1996
3 // Modified Mon 12-january-98
4 // Author: Jacques MINOT/Odile Olivier/Sergey ZARITCHNY
8 #define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
9 // if any in all dimensions.
11 #include <Standard_NotImplemented.hxx>
13 #include <AIS_DiameterDimension.ixx>
14 #include <AIS_DimensionOwner.hxx>
15 #include <DsgPrs_DiameterPresentation.hxx>
16 #include <DsgPrs_RadiusPresentation.hxx>
18 #include <TCollection_ExtendedString.hxx>
20 #include <Prs3d_LengthAspect.hxx>
21 #include <Prs3d_ArrowAspect.hxx>
22 #include <Prs3d_Drawer.hxx>
23 #include <Prs3d_TextAspect.hxx>
24 #include <Prs3d_Text.hxx>
26 #include <Select3D_SensitiveSegment.hxx>
27 #include <Select3D_SensitiveBox.hxx>
28 #include <SelectMgr_EntityOwner.hxx>
35 #include <BRepAdaptor_Surface.hxx>
36 #include <BRepAdaptor_Curve.hxx>
37 #include <Adaptor3d_HCurve.hxx>
39 #include <Geom_Circle.hxx>
40 #include <Geom_TrimmedCurve.hxx>
41 #include <Geom_Plane.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_CylindricalSurface.hxx>
44 #include <Geom_SurfaceOfRevolution.hxx>
45 #include <Geom_CylindricalSurface.hxx>
46 #include <Geom_SurfaceOfLinearExtrusion.hxx>
56 #include <AIS_Drawer.hxx>
58 #include <GC_MakeCircle.hxx>
60 #include <Precision.hxx>
62 #include <TopExp_Explorer.hxx>
64 //=======================================================================
65 //function : Constructor
67 //=======================================================================
69 AIS_DiameterDimension::AIS_DiameterDimension(const TopoDS_Shape& aShape,
70 const Standard_Real aVal,
71 const TCollection_ExtendedString& aText)
73 myDiamSymbol(Standard_True)
75 myPosition = gp_Pnt(0.,0.,0.);
79 mySymbolPrs = DsgPrs_AS_LASTAR;
80 myAutomaticPosition = Standard_True;
81 myArrowSize = myVal / 100.;
84 //=======================================================================
85 //function : Constructor
87 //=======================================================================
89 AIS_DiameterDimension::AIS_DiameterDimension(const TopoDS_Shape& aShape,
90 const Standard_Real aVal,
91 const TCollection_ExtendedString& aText,
92 const gp_Pnt& aPosition,
93 const DsgPrs_ArrowSide aSymbolPrs,
94 const Standard_Boolean aDiamSymbol,
95 const Standard_Real anArrowSize)
97 myDiamSymbol(aDiamSymbol)
102 mySymbolPrs = aSymbolPrs;
103 myPosition = aPosition;
104 myAutomaticPosition = Standard_False;
106 SetArrowSize( anArrowSize );
108 myArrowSize = anArrowSize;
112 //=======================================================================
115 //=======================================================================
117 void AIS_DiameterDimension::Compute(
118 const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
119 const Handle(Prs3d_Presentation)& aPresentation,
120 const Standard_Integer /*aMode*/)
122 aPresentation->Clear();
124 switch (myFShape.ShapeType()) {
127 // compute one face case
128 ComputeOneFaceDiameter (aPresentation);
133 ComputeOneEdgeDiameter (aPresentation);
142 //=======================================================================
144 //purpose : to avoid warning
145 //=======================================================================
147 void AIS_DiameterDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
148 const Handle(Prs3d_Presentation)& aPresentation)
150 // Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)");
151 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
154 //=======================================================================
156 //purpose : to avoid warning
157 //=======================================================================
159 void AIS_DiameterDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager,
160 const Handle(Graphic2d_GraphicObject)& aPresentation,
161 const Standard_Integer aMode)
163 // Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager, const Handle(Graphic2d_GraphicObject)& aPresentation, const Standard_Integer aMode)");
164 PrsMgr_PresentableObject::Compute( aPresentationManager ,aPresentation,aMode) ;
167 void AIS_DiameterDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
169 // Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
170 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
173 //=======================================================================
174 //function : ComputeSelection
176 //=======================================================================
178 void AIS_DiameterDimension::ComputeSelection(
179 const Handle(SelectMgr_Selection)& aSelection,
180 const Standard_Integer /*aMode*/)
182 Handle(AIS_DimensionOwner) own = new AIS_DimensionOwner(this,7);
183 own->SetShape(myFShape);
186 gp_Pnt AttachmentPoint = myPosition;
187 Standard_Real parat = ElCLib::Parameter(myCircle,AttachmentPoint);
188 gp_Pnt ptoncirc = ElCLib::Value (parat,myCircle);
192 gp_Pnt center = myCircle.Location();
193 gp_Vec vecrap (ptoncirc,center);
195 Standard_Real dist = center.Distance(AttachmentPoint);
196 Standard_Real aRadius = myCircle.Radius();
197 Standard_Real inside = Standard_False;
199 gp_Pnt pt1 = AttachmentPoint;
200 if (dist < aRadius) {
203 inside = Standard_True;
206 vecrap *= (dist+aRadius);
207 gp_Pnt OppositePoint = pt1.Translated(vecrap);
209 if ( pt1.Distance(OppositePoint)>=Precision::Confusion()) {
210 Handle(Select3D_SensitiveSegment)
211 seg = new Select3D_SensitiveSegment(own,pt1 ,OppositePoint);
212 aSelection->Add(seg);
216 ComputeArcSelection(aSelection);
219 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
220 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
224 myPosition.X() + size,
225 myPosition.Y() + size,
226 myPosition.Z() + size);
227 aSelection->Add(box);
229 //==========================================================================
230 // function : ComputeArcSelection
233 //==========================================================================
235 void AIS_DiameterDimension::ComputeArcSelection(const Handle(SelectMgr_Selection)& aSelection)
243 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
244 gp_Pnt theCenter = myCircle.Location();
245 while (lpara > 2*M_PI) {
249 Standard_Real parat = ElCLib::Parameter(myCircle,myPosition);
250 Standard_Boolean otherside(Standard_False);
251 gp_Pnt attpoint = myPosition;
253 if (!AIS::InDomain(fpara,lpara,parat)) {
254 Standard_Real otherpar = parat + M_PI;
255 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
256 if (AIS::InDomain(fpara,lpara,otherpar)) {
258 otherside = Standard_True;
261 Standard_Real ecartpar = Min(Abs(fpara-parat),
263 Standard_Real ecartoth = Min(Abs(fpara-otherpar),
264 Abs(lpara-otherpar));
265 if (ecartpar <= ecartoth) {
266 if (parat < fpara) parat = fpara;
270 otherside = Standard_True;
271 if (otherpar < fpara) parat = fpara;
274 gp_Pnt ptdir = ElCLib::Value(parat,myCircle);
275 gp_Lin lsup(theCenter,
276 gp_Dir(ptdir.XYZ()-theCenter.XYZ()));
277 Standard_Real parpos = ElCLib::Parameter(lsup,myPosition);
278 attpoint = ElCLib::Value(parpos,lsup);
281 gp_Pnt ptoncirc = ElCLib::Value(parat,myCircle);
282 gp_Lin L (theCenter,gp_Dir(attpoint.XYZ()-theCenter.XYZ()));
283 gp_Pnt firstpoint = attpoint;
284 gp_Pnt drawtopoint = ptoncirc;
287 Standard_Real uatt = ElCLib::Parameter(L,attpoint);
288 Standard_Real uptc = ElCLib::Parameter(L,ptoncirc);
289 if (Abs(uatt) > Abs(uptc)) {
290 drawtopoint = theCenter;
293 firstpoint = theCenter;
297 Handle(Select3D_SensitiveSegment) seg = new Select3D_SensitiveSegment(own,firstpoint,drawtopoint);
298 aSelection->Add(seg);
301 //=======================================================================
302 //function : ComputeOneFaceDiameter
304 //=======================================================================
306 void AIS_DiameterDimension::ComputeOneFaceDiameter(
307 const Handle(Prs3d_Presentation)& aPresentation)
309 //cout<<"AIS_DiameterDimension::ComputeOneFaceDiameter"<<endl;
312 Handle( Geom_Surface ) aBasisSurf;
313 AIS_KindOfSurface aSurfType;
314 Standard_Real Offset;
315 if( myAutomaticPosition )
316 AIS::GetPlaneFromFace( TopoDS::Face( myFShape),
322 if ( aSurfType == AIS_KOS_Plane )
323 ComputeOnePlanarFaceDiameter( aPresentation );
325 ComputeOneCylFaceDiameter( aPresentation, aSurfType, aBasisSurf );
330 //=======================================================================
331 //function : ComputeOneCylFaceDiameter
333 //=======================================================================
335 void AIS_DiameterDimension::ComputeOneCylFaceDiameter
336 (const Handle(Prs3d_Presentation)& aPresentation,
337 const AIS_KindOfSurface aSurfType,
338 const Handle( Geom_Surface )& aBasisSurf )
341 if( myAutomaticPosition )
343 BRepAdaptor_Surface surf1(TopoDS::Face(myFShape));
344 Standard_Real uFirst, uLast, vFirst, vLast;
345 uFirst = surf1.FirstUParameter();
346 uLast = surf1.LastUParameter();
347 vFirst = surf1.FirstVParameter();
348 vLast = surf1.LastVParameter();
349 Standard_Real uMid = (uFirst + uLast)*0.5;
350 Standard_Real vMid = (vFirst + vLast)*0.5;
351 surf1.D0(uMid, vMid, curPos);
352 Handle( Adaptor3d_HCurve ) BasisCurve;
353 //Standard_Real Param;
354 Standard_Boolean ExpectedType = Standard_False;
355 if (aSurfType == AIS_KOS_Cylinder)
357 ExpectedType = Standard_True;
360 if (aSurfType == AIS_KOS_Revolution)
362 BasisCurve = surf1.BasisCurve();
363 if (BasisCurve->GetType() == GeomAbs_Line)
364 ExpectedType = Standard_True;
366 else if (aSurfType == AIS_KOS_Extrusion)
368 BasisCurve = surf1.BasisCurve();
369 if ( BasisCurve->GetType() == GeomAbs_Circle )
370 ExpectedType = Standard_True;
373 Standard_ConstructionError::Raise("AIS:: Not expected type of surface") ;
377 Handle(Geom_Curve) aCurve;
378 aCurve = aBasisSurf->VIso(vMid);
379 if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
381 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ
383 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
384 Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
385 aCurve = tCurve->BasisCurve();
386 uFirst = tCurve->FirstParameter();
387 uLast = tCurve->LastParameter();
388 if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
389 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ
392 // compute a circle from 3 points on "aCurve"
394 surf1.D0(uFirst, vMid, P1);
395 surf1.D0(uLast, vMid, P2);
396 GC_MakeCircle mkCirc(P1, curPos, P2);
397 myCircle = mkCirc.Value()->Circ();
399 myCircle.SetRadius(myVal/2.);
400 myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
401 gp_Vec v1(myCircle.Location(), curPos);
404 myPosition = myCircle.Location().Translated(v1);
407 p1 = ElCLib::Value (uFirst, myCircle);
408 p2 = ElCLib::Value (uLast, myCircle);
409 if ( p1.IsEqual(p2, Precision::Confusion()) )
410 myIsAnArc = Standard_False;
411 else myIsAnArc = Standard_True;
414 // myPosition = curPos;
415 myAutomaticPosition = Standard_True;
417 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
418 myPosition ) ), myBndBox );
420 else { // !AutomaticPosition
422 curPos = AIS::ProjectPointOnPlane( curPos, myPlane->Pln() );
426 Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
427 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
431 if( !myArrowSizeIsDefined ) {
432 myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
434 arr->SetLength(myArrowSize);
436 if (myCircle.Radius()/5. > myArrowSize) {
437 arr->SetLength(myArrowSize);
440 arr->SetLength(myCircle.Radius()/5.);
444 //cout<<"AIS_DiameterDimension:: add Prs"<<endl;
446 DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
447 myCircle, myFirstPar, myLastPar, mySymbolPrs, myDiamSymbol);
449 DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
450 myCircle, DsgPrs_AS_BOTHAR, myDiamSymbol);
456 //=======================================================================
457 //function : ComputeCircleDiameter
459 //=======================================================================
461 void AIS_DiameterDimension::ComputeCircleDiameter(const Handle(Prs3d_Presentation)& aPresentation)
463 gp_Pnt center = myCircle.Location();
464 Standard_Real rad = myCircle.Radius();
467 if (myAutomaticPosition) {
468 // we compute 1 point on the circle
469 myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
470 gp_Dir xdir = myCircle.XAxis().Direction();
471 Standard_Real deport = rad *1.2;
472 curpos = center.Translated( gp_Vec(xdir)*deport );
473 SetPosition (curpos);// myPosition = curpos
474 myAutomaticPosition = Standard_True;
476 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
477 myPosition ) ), myBndBox );
481 // VRO (2007-05-17) inserted this IF.
482 if (myPlane.IsNull())
483 myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));
484 myPosition = AIS::ProjectPointOnPlane( curpos, myPlane->Pln() );
488 Handle(Prs3d_LengthAspect) LA = myDrawer->LengthAspect();
489 Handle(Prs3d_ArrowAspect) arr = LA->Arrow1Aspect();
492 if( !myArrowSizeIsDefined ) {
493 myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
495 arr->SetLength(myArrowSize);
497 if (myCircle.Radius()/5. > myArrowSize) {
498 arr->SetLength(myArrowSize);
501 arr->SetLength(myCircle.Radius()/5.);
505 DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition, myCircle,
506 DsgPrs_AS_BOTHAR, myDiamSymbol );
510 //==========================================================================
511 // function : ComputeArcDiameter
514 //==========================================================================
516 void AIS_DiameterDimension::ComputeArcDiameter(
517 const Handle(Prs3d_Presentation)& aPresentation,
518 const gp_Pnt& pfirst,
522 gp_Pnt center = myCircle.Location();
523 Standard_Real rad = myCircle.Radius();
526 Standard_Real parfirst, parend;
528 parfirst = ElCLib::Parameter(myCircle, pfirst);
529 parend = ElCLib::Parameter(myCircle, pend);
530 myFirstPar = parfirst;
532 if ( parfirst > parend) {
535 if (myAutomaticPosition) {
536 Standard_Real pcurpos = (parfirst + parend)/2.;
537 curpos = ElCLib::Value(pcurpos, myCircle);
538 myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
539 gp_Dir vdir(gp_Vec(myCircle.Location(),curpos));
540 Standard_Real deport = rad * 1.2;
541 curpos = center.Translated( gp_Vec(vdir)*deport );
543 SetPosition (curpos);
544 myAutomaticPosition = Standard_True;
547 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
548 myPosition ) ), myBndBox );
553 myPosition = AIS::ProjectPointOnPlane( curpos, myPlane->Pln() );
558 Handle(Prs3d_LengthAspect) LA = myDrawer->LengthAspect();
559 Handle(Prs3d_ArrowAspect) arr = LA->Arrow1Aspect();
562 if( !myArrowSizeIsDefined ) {
563 myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
565 arr->SetLength(myArrowSize);
567 if (myCircle.Radius()/5. > myArrowSize) {
568 arr->SetLength(myArrowSize);
571 arr->SetLength(myCircle.Radius()/5.);
576 DsgPrs_DiameterPresentation::Add (aPresentation, myDrawer, myText, myPosition, myCircle,
577 parfirst, parend, mySymbolPrs, myDiamSymbol);
582 //==========================================================================
583 // function : ComputeOneEdgeDiameter
586 //==========================================================================
588 void AIS_DiameterDimension::ComputeOneEdgeDiameter(const Handle(Prs3d_Presentation)& aPresentation)
590 gp_Pnt ptfirst,ptend;
591 Handle(Geom_Curve) curv;
592 if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),curv,ptfirst,ptend)) return;
594 Handle(Geom_Circle) circ = Handle(Geom_Circle)::DownCast(curv);
595 if ( circ.IsNull()) return;
597 myCircle = circ->Circ();
598 myCircle.SetRadius(myVal/2.);
599 if ( ptfirst.IsEqual(ptend, Precision::Confusion()) ) {
600 myIsAnArc = Standard_False;
601 ComputeCircleDiameter(aPresentation);
604 myIsAnArc = Standard_True;
605 ComputeArcDiameter(aPresentation,ptfirst,ptend );
609 //===================================================================
610 //function : CircleFromPlanarFace
611 //purpose : if possible computes circle from planar face
612 //=======================================================================
613 static Standard_Boolean CircleFromPlanarFace(const TopoDS_Face& aFace,
614 Handle(Geom_Curve)& aCurve,
615 gp_Pnt & ptfirst, gp_Pnt & ptend)
617 TopExp_Explorer ExploEd( aFace, TopAbs_EDGE );
618 for ( ; ExploEd.More(); ExploEd.Next())
620 TopoDS_Edge curedge = TopoDS::Edge( ExploEd.Current() );
621 if (AIS::ComputeGeometry(curedge, aCurve, ptfirst, ptend))
622 if(aCurve->IsInstance(STANDARD_TYPE(Geom_Circle)) &&
623 !Handle(Geom_Circle)::DownCast(aCurve).IsNull())
624 return Standard_True;
626 return Standard_False;
629 //=======================================================================
630 //function : ComputeOnePlanarFaceDiameter
632 //=======================================================================
634 void AIS_DiameterDimension::ComputeOnePlanarFaceDiameter(const Handle(Prs3d_Presentation)& aPresentation)
638 Standard_Real parfirst =0., parend =0.;
640 Standard_Real parfirst, parend;
642 if (myAutomaticPosition) {
643 Handle(Geom_Curve) curv;
644 gp_Pnt ptfirst,ptend;
646 if( !CircleFromPlanarFace( TopoDS::Face( myFShape ), curv, ptfirst, ptend) ) {
647 Standard_ConstructionError::Raise("AIS:: Curve is not a circle or is Null") ;
651 myCircle = Handle(Geom_Circle)::DownCast(curv)->Circ();
652 if ( ptfirst.IsEqual(ptend, Precision::Confusion()) )
653 myIsAnArc = Standard_False;
655 myIsAnArc = Standard_True;
656 myCircle.SetRadius(myVal/2.);//
657 BRepAdaptor_Surface surfAlgo (TopoDS::Face(myFShape));
658 myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
659 gp_Pnt center = myCircle.Location();
660 Standard_Real rad = myCircle.Radius();
661 Standard_Real deport = rad * 1.2;
662 if(! myIsAnArc ) { // Circle
663 gp_Dir xdir = myCircle.XAxis().Direction();
664 curPos = center.Translated( gp_Vec(xdir)*deport );
667 parfirst = ElCLib::Parameter(myCircle, ptfirst);
668 parend = ElCLib::Parameter(myCircle, ptend);
669 if ( parfirst > parend) {
672 Standard_Real parcurPos = (parfirst + parend) * 0.5;
673 curPos = ElCLib::Value(parcurPos, myCircle);
674 gp_Vec v1( center, curPos );
676 curPos = center.Translated( v1 * deport );
678 myFirstPar = parfirst;
681 myAutomaticPosition = Standard_True;
683 myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
684 myPosition ) ), myBndBox );
687 // !myAutomaticPosition
688 // Project point on the plane of face
690 curPos = AIS::ProjectPointOnPlane( curPos, myPlane->Pln() );
695 Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
696 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
700 if( !myArrowSizeIsDefined ) {
701 myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
703 arr->SetLength(myArrowSize);
705 if (myCircle.Radius()/5. > myArrowSize) {
706 arr->SetLength(myArrowSize);
709 arr->SetLength(myCircle.Radius()/5.);
714 DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
715 myCircle, DsgPrs_AS_BOTHAR, myDiamSymbol);
717 DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
718 myCircle, myFirstPar, myLastPar, mySymbolPrs, myDiamSymbol );