1 // File: AIS_RadiusDimension.cxx
2 // Created: Tue Dec 5 15:09:04 1996
3 // Author: Jean-Pierre COMBE/Odile Olivier/Serguei Zaritchny
4 // modified <SZY> 20-feb-98
5 // <VBU> myFShape could be a wire.
7 #define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
8 // if any in all dimensions.
10 #include <Standard_NotImplemented.hxx>
12 #include <AIS_RadiusDimension.ixx>
14 #include <AIS_DimensionOwner.hxx>
15 #include <DsgPrs_RadiusPresentation.hxx>
18 #include <Geom_Surface.hxx>
19 #include <Geom_Plane.hxx>
20 #include <Geom_Circle.hxx>
21 #include <Geom_Curve.hxx>
22 #include <Geom_TrimmedCurve.hxx>
23 #include <Geom_ToroidalSurface.hxx>
24 #include <Geom_CylindricalSurface.hxx>
25 #include <Geom_SurfaceOfLinearExtrusion.hxx>
27 #include <gp_Circ.hxx>
29 #include <gp_Trsf.hxx>
31 #include <GC_MakeCircle.hxx>
32 #include <gce_MakeLin.hxx>
33 #include <gce_MakeCirc.hxx>
35 #include <SelectMgr_EntityOwner.hxx>
36 #include <Select3D_SensitiveSegment.hxx>
38 #include <Precision.hxx>
40 #include <TopExp_Explorer.hxx>
41 #include <TopAbs_ShapeEnum.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Wire.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopLoc_Location.hxx>
47 #include <BRep_Tool.hxx>
48 #include <BRepAdaptor_Surface.hxx>
49 #include <BRepAdaptor_Curve.hxx>
50 #include <Adaptor3d_HCurve.hxx>
52 #include <Prs3d_AngleAspect.hxx>
53 #include <Prs3d_ArrowAspect.hxx>
54 #include <Prs3d_LengthAspect.hxx>
55 #include <Prs3d_Drawer.hxx>
57 #include <TCollection_AsciiString.hxx>
58 #include <TCollection_ExtendedString.hxx>
62 #include <AIS_Drawer.hxx>
63 #include <gce_MakeDir.hxx>
64 #include <Select3D_SensitiveBox.hxx>
68 //======================================================================
69 //function : CircleFromPlanarFace
70 //purpose : if possible gets circle from planar face
71 //=======================================================================
72 static Standard_Boolean CircleFromPlanarFace (const TopoDS_Shape& aFace,
73 Handle(Geom_Curve)& aCurve,
77 TopExp_Explorer ExploEd (aFace, TopAbs_EDGE);
78 for ( ; ExploEd.More(); ExploEd.Next())
80 TopoDS_Edge curedge = TopoDS::Edge (ExploEd.Current());
81 if (AIS::ComputeGeometry (curedge, aCurve, ptfirst, ptend))
82 if (aCurve->IsInstance (STANDARD_TYPE(Geom_Circle)) &&
83 !Handle(Geom_Circle)::DownCast(aCurve).IsNull())
86 return Standard_False;
90 //=======================================================================
91 //function : Constructor
93 //=======================================================================
94 AIS_RadiusDimension::AIS_RadiusDimension(const TopoDS_Shape& aShape,
95 const Standard_Real aVal,
96 const TCollection_ExtendedString& aText)
97 :mydrawFromCenter(Standard_True)
102 mySymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
103 myAutomaticPosition = Standard_True;
105 myArrowSize = myVal / 100.;
109 //=======================================================================
110 //function : Constructor
111 //purpose :(avec position et texte)
112 //=======================================================================
113 AIS_RadiusDimension::AIS_RadiusDimension( const TopoDS_Shape& aShape,
114 const Standard_Real aVal,
115 const TCollection_ExtendedString& aText,
116 const gp_Pnt& aPosition,
117 const DsgPrs_ArrowSide aSymbolPrs,
118 const Standard_Real anArrowSize )
119 :mydrawFromCenter(Standard_True)
124 myPosition = aPosition;
125 mySymbolPrs = aSymbolPrs;
127 SetArrowSize( anArrowSize );
129 myArrowSize = anArrowSize;
131 myAutomaticPosition = Standard_False;
135 //=======================================================================
136 //function : InitFirstShape
138 //=======================================================================
139 void AIS_RadiusDimension::InitFirstShape()
141 if (myFShape.ShapeType() == TopAbs_FACE)
143 BRepAdaptor_Surface surfAlgo( TopoDS::Face( myFShape ) );
144 Standard_Real uFirst, uLast, vFirst, vLast;
145 uFirst = surfAlgo.FirstUParameter();
146 uLast = surfAlgo.LastUParameter();
147 vFirst = surfAlgo.FirstVParameter();
148 vLast = surfAlgo.LastVParameter();
149 Standard_Real uMoy = (uFirst + uLast)/2;
150 Standard_Real vMoy = (vFirst + vLast)/2;
151 Handle( Geom_Surface ) surf = surfAlgo.Surface().Surface();
152 surf = Handle( Geom_Surface )::DownCast( surf->Transformed( surfAlgo.Trsf() ) );
153 Handle( Geom_Curve ) aCurve;
155 if (surf->DynamicType() == STANDARD_TYPE(Geom_ToroidalSurface))
157 aCurve = surf->UIso( uMoy );
161 else if (surf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
163 Handle( Adaptor3d_HCurve ) BasisCurve = surfAlgo.BasisCurve();
164 if ( BasisCurve->GetType() == GeomAbs_Circle )
165 aCurve = surf->VIso( vMoy );
168 else if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane))
170 gp_Pnt FirstPnt, LastPnt;
171 if (CircleFromPlanarFace (TopoDS::Face(myFShape), aCurve, FirstPnt, LastPnt))
172 // if (CircleFromPlanarFace (myFShape, aCurve, FirstPnt, LastPnt))
174 uFirst = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), FirstPnt);
175 uLast = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), LastPnt);
180 aCurve = surf->VIso( vMoy );
182 if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
183 myCircle = (Handle( Geom_Circle )::DownCast( aCurve ))->Circ();
184 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
185 Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
186 aCurve = tCurve->BasisCurve();
187 uFirst = tCurve->FirstParameter();
188 uLast = tCurve->LastParameter();
189 if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
190 myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ
193 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve)) {
195 aCurve->D0(uFirst,P1);
196 aCurve->D0((uFirst+uLast)/2,P2);
197 aCurve->D0(uLast,P3);
198 gce_MakeCirc MakeCirc = gce_MakeCirc(P1,P2,P3);
199 myCircle = MakeCirc.Value();
200 uFirst = ElCLib::Parameter(myCircle,P1);
201 uLast = ElCLib::Parameter(myCircle,P2);
208 else // it is edge or a wire
211 if (myFShape.ShapeType() == TopAbs_WIRE) {
212 TopExp_Explorer exp (myFShape,TopAbs_EDGE);
213 if (exp.More()) anEdge = TopoDS::Edge (exp.Current());
216 if ( myFShape.ShapeType() == TopAbs_EDGE) {
217 anEdge = TopoDS::Edge (myFShape);
218 BRepAdaptor_Curve AdaptedCurve (anEdge);
219 if (!AdaptedCurve.GetType() == GeomAbs_Circle) return;
221 myCircle = AdaptedCurve.Circle();
222 myFirstPar = AdaptedCurve.FirstParameter();
223 myLastPar = AdaptedCurve.LastParameter();
227 cout << "AIS_RadiusDimension::InitFirstShape ==> myFShape.ShapeType() == " << myFShape.ShapeType() << endl;
233 myCenter = myCircle.Location();
234 myCircle.SetRadius(myVal);
235 while (myFirstPar > 2*PI) myFirstPar -= 2*PI;
236 while (myFirstPar < 0.0 ) myFirstPar += 2*PI;
237 while (myLastPar > 2*PI) myLastPar -= 2*PI;
238 while (myLastPar < 0.0 ) myLastPar += 2*PI;
239 myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));
240 myFirstLine = gce_MakeLin( myCenter, ElCLib::Value( myFirstPar, myCircle ) );
241 myLastLine = gce_MakeLin( myCenter, ElCLib::Value( myLastPar, myCircle ) );
244 //=======================================================================
245 //function : SetFirstShape
247 //=======================================================================
248 void AIS_RadiusDimension::SetFirstShape( const TopoDS_Shape& aFShape )
254 //=======================================================================
257 //=======================================================================
258 void AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
259 const Handle(Prs3d_Presentation)& aPresentation,
260 const Standard_Integer /*aMode*/)
262 aPresentation->Clear();
264 ComputeRadius( aPresentation );
267 //=======================================================================
269 //purpose : to avoid warning
270 //=======================================================================
271 void AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
272 const Handle(Prs3d_Presentation)& aPresentation)
274 // Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector,const Handle(Prs3d_Presentation)& aPresentation)");
275 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
278 //=======================================================================
280 //purpose : to avoid warning
281 //=======================================================================
282 void AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager,
283 const Handle(Graphic2d_GraphicObject)& aPresentation,
284 const Standard_Integer aMode)
286 // Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager,const Handle(Graphic2d_GraphicObject)& aPresentation,const Standard_Integer aMode)");
287 PrsMgr_PresentableObject::Compute( aPresentationManager ,aPresentation,aMode) ;
290 //=======================================================================
293 //=======================================================================
295 void AIS_RadiusDimension::Compute(const Handle_Prs3d_Projector& aProjector,
296 const Handle_Geom_Transformation& aTransformation,
297 const Handle_Prs3d_Presentation& aPresentation)
299 // Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
300 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
303 //=======================================================================
304 //function : ComputeSelection
306 //=======================================================================
307 void AIS_RadiusDimension::ComputeSelection( const Handle(SelectMgr_Selection)& aSelection,
308 const Standard_Integer )
310 gp_Pnt LineOrigin, LineEnd;
311 DsgPrs::ComputeRadiusLine( myCenter, myEndOfArrow, myPosition, mydrawFromCenter,
313 Handle(AIS_DimensionOwner) own = new AIS_DimensionOwner(this,7);
314 own->SetShape(myFShape);
315 Handle( Select3D_SensitiveSegment ) seg = new Select3D_SensitiveSegment( own, LineOrigin, LineEnd );
316 aSelection->Add( seg );
319 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
320 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
324 myPosition.X() + size,
325 myPosition.Y() + size,
326 myPosition.Z() + size );
327 aSelection->Add(box);
330 //=======================================================================
331 //function : ComputeRadius
333 //=======================================================================
335 void AIS_RadiusDimension::ComputeRadius( const Handle( Prs3d_Presentation )& aPresentation )
337 if (myAutomaticPosition)
340 myEndOfArrow = ElCLib::Value( (myFirstPar + myLastPar)/2, myCircle );
341 if(mydrawFromCenter) {
342 myPosition = myCenter;
346 gp_Vec v1(myCenter, myEndOfArrow);
347 myPosition = myCenter.Translated(v1 * 1.2);
349 myAutomaticPosition = Standard_True;
352 myPosition = AIS::TranslatePointToBound(myPosition, gce_MakeDir( myCenter, myEndOfArrow ),
358 myPosition = AIS::ProjectPointOnPlane( myPosition, myPlane->Pln() );
359 Standard_Real PosPar = ElCLib::Parameter( myCircle, myPosition );
360 if (!AIS::InDomain(myFirstPar, myLastPar, PosPar))
362 Standard_Real otherpar = PosPar + PI;
363 if (otherpar > 2*PI) otherpar -= 2*PI;
364 if (AIS::InDomain(myFirstPar, myLastPar, otherpar)){
365 PosPar = otherpar;// parameter on circle
366 myEndOfArrow = ElCLib::Value( PosPar, myCircle );
369 Standard_Real Teta1 = Abs( PosPar - myFirstPar ), Teta2 = Abs( PosPar - myLastPar );
371 Teta1 = 2.0*PI - Teta1;
373 Teta2 = 2.0*PI - Teta2;
376 if(myFirstLine.Contains(myPosition,Precision::Confusion()))
383 if(myLastLine.Contains(myPosition,Precision::Confusion()))
388 myEndOfArrow = ElCLib::Value( PosPar, myCircle );
389 gp_Lin RadiusLine = gce_MakeLin( myCenter, myEndOfArrow );
390 // project on radius line
391 myPosition = ElCLib::Value( ElCLib::Parameter( RadiusLine, myPosition ), RadiusLine );
395 myEndOfArrow = ElCLib::Value( PosPar, myCircle );
398 Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
399 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
402 if( !myArrowSizeIsDefined ) {
403 myArrowSize = Min(myArrowSize,myVal/5.);
405 arr->SetLength(myArrowSize);
407 if (myVal/5. > myArrowSize)
408 arr->SetLength(myArrowSize);
410 arr->SetLength(myVal/5.);
413 DsgPrs_RadiusPresentation::Add( aPresentation, myDrawer, myText, myPosition,
414 myCenter, myEndOfArrow, mySymbolPrs, mydrawFromCenter );