Integration of OCCT 6.5.0 from SVN
[occt.git] / src / AIS / AIS_RadiusDimension.cxx
CommitLineData
7fd59977 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.
6
7#define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
8// if any in all dimensions.
9
10#include <Standard_NotImplemented.hxx>
11
12#include <AIS_RadiusDimension.ixx>
13
14#include <AIS_DimensionOwner.hxx>
15#include <DsgPrs_RadiusPresentation.hxx>
16#include <DsgPrs.hxx>
17
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>
26
27#include <gp_Circ.hxx>
28#include <gp_Pnt.hxx>
29#include <gp_Trsf.hxx>
30#include <ElCLib.hxx>
31#include <GC_MakeCircle.hxx>
32#include <gce_MakeLin.hxx>
33#include <gce_MakeCirc.hxx>
34
35#include <SelectMgr_EntityOwner.hxx>
36#include <Select3D_SensitiveSegment.hxx>
37
38#include <Precision.hxx>
39
40#include <TopExp_Explorer.hxx>
41#include <TopAbs_ShapeEnum.hxx>
42#include <TopoDS.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>
51
52#include <Prs3d_AngleAspect.hxx>
53#include <Prs3d_ArrowAspect.hxx>
54#include <Prs3d_LengthAspect.hxx>
55#include <Prs3d_Drawer.hxx>
56
57#include <TCollection_AsciiString.hxx>
58#include <TCollection_ExtendedString.hxx>
59
60
61#include <AIS.hxx>
62#include <AIS_Drawer.hxx>
63#include <gce_MakeDir.hxx>
64#include <Select3D_SensitiveBox.hxx>
65
66
67
68//======================================================================
69//function : CircleFromPlanarFace
70//purpose : if possible gets circle from planar face
71//=======================================================================
72static Standard_Boolean CircleFromPlanarFace (const TopoDS_Shape& aFace,
73 Handle(Geom_Curve)& aCurve,
74 gp_Pnt & ptfirst,
75 gp_Pnt & ptend)
76{
77 TopExp_Explorer ExploEd (aFace, TopAbs_EDGE);
78 for ( ; ExploEd.More(); ExploEd.Next())
79 {
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())
84 return Standard_True;
85 }
86 return Standard_False;
87}
88
89
90//=======================================================================
91//function : Constructor
92//purpose :
93//=======================================================================
94AIS_RadiusDimension::AIS_RadiusDimension(const TopoDS_Shape& aShape,
95 const Standard_Real aVal,
96 const TCollection_ExtendedString& aText)
97:mydrawFromCenter(Standard_True)
98{
99 myFShape = aShape;
100 myVal = aVal;
101 myText = aText;
102 mySymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
103 myAutomaticPosition = Standard_True;
104
105 myArrowSize = myVal / 100.;
106 InitFirstShape();
107}
108
109//=======================================================================
110//function : Constructor
111//purpose :(avec position et texte)
112//=======================================================================
113AIS_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)
120{
121 myFShape = aShape;
122 myVal = aVal;
123 myText = aText;
124 myPosition = aPosition;
125 mySymbolPrs = aSymbolPrs;
126#ifdef BUC60915
127 SetArrowSize( anArrowSize );
128#else
129 myArrowSize = anArrowSize;
130#endif
131 myAutomaticPosition = Standard_False;
132 InitFirstShape();
133}
134
135//=======================================================================
136//function : InitFirstShape
137//purpose :
138//=======================================================================
139void AIS_RadiusDimension::InitFirstShape()
140{
141 if (myFShape.ShapeType() == TopAbs_FACE)
142 {
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;
154
155 if (surf->DynamicType() == STANDARD_TYPE(Geom_ToroidalSurface))
156 {
157 aCurve = surf->UIso( uMoy );
158 uFirst = vFirst;
159 uLast = vLast;
160 }
161 else if (surf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))
162 {
163 Handle( Adaptor3d_HCurve ) BasisCurve = surfAlgo.BasisCurve();
164 if ( BasisCurve->GetType() == GeomAbs_Circle )
165 aCurve = surf->VIso( vMoy );
166 else return;
167 }
168 else if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane))
169 {
170 gp_Pnt FirstPnt, LastPnt;
171 if (CircleFromPlanarFace (TopoDS::Face(myFShape), aCurve, FirstPnt, LastPnt))
172// if (CircleFromPlanarFace (myFShape, aCurve, FirstPnt, LastPnt))
173 {
174 uFirst = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), FirstPnt);
175 uLast = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), LastPnt);
176 }
177 else return;
178 }
179 else
180 aCurve = surf->VIso( vMoy );
181
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
191 else return;
192 }
193 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve)) {
194 gp_Pnt P1,P2,P3;
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);
202 }
203
204 myFirstPar = uFirst;
205 myLastPar = uLast;
206 } // TopAbs_FACE
207
208 else // it is edge or a wire
209 {
210 TopoDS_Edge anEdge;
211 if (myFShape.ShapeType() == TopAbs_WIRE) {
212 TopExp_Explorer exp (myFShape,TopAbs_EDGE);
213 if (exp.More()) anEdge = TopoDS::Edge (exp.Current());
214 }
215 else {
216 if ( myFShape.ShapeType() == TopAbs_EDGE) {
217 anEdge = TopoDS::Edge (myFShape);
218 BRepAdaptor_Curve AdaptedCurve (anEdge);
219 if (!AdaptedCurve.GetType() == GeomAbs_Circle) return;
220
221 myCircle = AdaptedCurve.Circle();
222 myFirstPar = AdaptedCurve.FirstParameter();
223 myLastPar = AdaptedCurve.LastParameter();
224 }
225#ifdef DEB
226 else {
227 cout << "AIS_RadiusDimension::InitFirstShape ==> myFShape.ShapeType() == " << myFShape.ShapeType() << endl;
228 }
229#endif
230 }
231 }
232
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 ) );
242}
243
244//=======================================================================
245//function : SetFirstShape
246//purpose :
247//=======================================================================
248void AIS_RadiusDimension::SetFirstShape( const TopoDS_Shape& aFShape )
249{
250 myFShape = aFShape;
251 InitFirstShape();
252}
253
254//=======================================================================
255//function : Compute
256//purpose :
257//=======================================================================
258void AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
259 const Handle(Prs3d_Presentation)& aPresentation,
260 const Standard_Integer /*aMode*/)
261{
262 aPresentation->Clear();
263
264 ComputeRadius( aPresentation );
265}
266
267//=======================================================================
268//function : Compute
269//purpose : to avoid warning
270//=======================================================================
271void AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
272 const Handle(Prs3d_Presentation)& aPresentation)
273{
274// Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector,const Handle(Prs3d_Presentation)& aPresentation)");
275 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
276}
277
278//=======================================================================
279//function : Compute
280//purpose : to avoid warning
281//=======================================================================
282void AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager,
283 const Handle(Graphic2d_GraphicObject)& aPresentation,
284 const Standard_Integer aMode)
285{
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) ;
288}
289
290//=======================================================================
291//function : Compute
292//purpose :
293//=======================================================================
294
295void AIS_RadiusDimension::Compute(const Handle_Prs3d_Projector& aProjector,
296 const Handle_Geom_Transformation& aTransformation,
297 const Handle_Prs3d_Presentation& aPresentation)
298{
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 ) ;
301}
302
303//=======================================================================
304//function : ComputeSelection
305//purpose :
306//=======================================================================
307void AIS_RadiusDimension::ComputeSelection( const Handle(SelectMgr_Selection)& aSelection,
308 const Standard_Integer )
309{
310 gp_Pnt LineOrigin, LineEnd;
311 DsgPrs::ComputeRadiusLine( myCenter, myEndOfArrow, myPosition, mydrawFromCenter,
312 LineOrigin,LineEnd);
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 );
317
318 // Text
319 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
320 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
321 myPosition.X(),
322 myPosition.Y(),
323 myPosition.Z(),
324 myPosition.X() + size,
325 myPosition.Y() + size,
326 myPosition.Z() + size );
327 aSelection->Add(box);
328}
329
330//=======================================================================
331//function : ComputeRadius
332//purpose :
333//=======================================================================
334
335void AIS_RadiusDimension::ComputeRadius( const Handle( Prs3d_Presentation )& aPresentation )
336{
337 if (myAutomaticPosition)
338 {
339 InitFirstShape();
340 myEndOfArrow = ElCLib::Value( (myFirstPar + myLastPar)/2, myCircle );
341 if(mydrawFromCenter) {
342 myPosition = myCenter;
343 }
344 else
345 {
346 gp_Vec v1(myCenter, myEndOfArrow);
347 myPosition = myCenter.Translated(v1 * 1.2);
348 }
349 myAutomaticPosition = Standard_True;
350
351 if (myIsSetBndBox)
352 myPosition = AIS::TranslatePointToBound(myPosition, gce_MakeDir( myCenter, myEndOfArrow ),
353 myBndBox );
354 }
355 else
356 {
357 //!Automaticposition
358 myPosition = AIS::ProjectPointOnPlane( myPosition, myPlane->Pln() );
359 Standard_Real PosPar = ElCLib::Parameter( myCircle, myPosition );
360 if (!AIS::InDomain(myFirstPar, myLastPar, PosPar))
361 { // not in domain
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 );
367 }
368 else {
369 Standard_Real Teta1 = Abs( PosPar - myFirstPar ), Teta2 = Abs( PosPar - myLastPar );
370 if (Teta1 > PI)
371 Teta1 = 2.0*PI - Teta1;
372 if (Teta2 > PI)
373 Teta2 = 2.0*PI - Teta2;
374 if (Teta1 < Teta2)
375 {
376 if(myFirstLine.Contains(myPosition,Precision::Confusion()))
377 PosPar = myFirstPar;
378 else
379 PosPar = myLastPar;
380 }
381 else
382 {
383 if(myLastLine.Contains(myPosition,Precision::Confusion()))
384 PosPar = myLastPar;
385 else
386 PosPar = myFirstPar;
387 }
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 );
392 }
393 }
394 else
395 myEndOfArrow = ElCLib::Value( PosPar, myCircle );
396 }
397
398 Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
399 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
400 // size
401#ifdef BUC60915
402 if( !myArrowSizeIsDefined ) {
403 myArrowSize = Min(myArrowSize,myVal/5.);
404 }
405 arr->SetLength(myArrowSize);
406#else
407 if (myVal/5. > myArrowSize)
408 arr->SetLength(myArrowSize);
409 else
410 arr->SetLength(myVal/5.);
411#endif
412
413 DsgPrs_RadiusPresentation::Add( aPresentation, myDrawer, myText, myPosition,
414 myCenter, myEndOfArrow, mySymbolPrs, mydrawFromCenter );
415 }