0023024: Update headers of OCCT files
[occt.git] / src / AIS / AIS_RadiusDimension.cxx
1 // Created on: 1996-12-05
2 // Created by: Jean-Pierre COMBE/Odile Olivier/Serguei Zaritchny
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 // modified     <SZY> 20-feb-98
22 //              <VBU> myFShape could be a wire.
23
24 #define BUC60915        //GG 05/06/01 Enable to compute the requested arrow size
25 //                      if any in all dimensions.
26
27 #include <Standard_NotImplemented.hxx>
28
29 #include <AIS_RadiusDimension.ixx>
30
31 #include <AIS_DimensionOwner.hxx>
32 #include <DsgPrs_RadiusPresentation.hxx>
33 #include <DsgPrs.hxx>
34
35 #include <Geom_Surface.hxx>
36 #include <Geom_Plane.hxx>
37 #include <Geom_Circle.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom_TrimmedCurve.hxx>
40 #include <Geom_ToroidalSurface.hxx>
41 #include <Geom_CylindricalSurface.hxx>
42 #include <Geom_SurfaceOfLinearExtrusion.hxx>
43
44 #include <gp_Circ.hxx>
45 #include <gp_Pnt.hxx>
46 #include <gp_Trsf.hxx>
47 #include <ElCLib.hxx>
48 #include <GC_MakeCircle.hxx>
49 #include <gce_MakeLin.hxx>
50 #include <gce_MakeCirc.hxx>
51
52 #include <SelectMgr_EntityOwner.hxx>
53 #include <Select3D_SensitiveSegment.hxx>
54
55 #include <Precision.hxx>
56
57 #include <TopExp_Explorer.hxx>
58 #include <TopAbs_ShapeEnum.hxx>
59 #include <TopoDS.hxx>
60 #include <TopoDS_Face.hxx>
61 #include <TopoDS_Wire.hxx>
62 #include <TopoDS_Edge.hxx>
63 #include <TopLoc_Location.hxx>
64 #include <BRep_Tool.hxx>
65 #include <BRepAdaptor_Surface.hxx>
66 #include <BRepAdaptor_Curve.hxx>
67 #include <Adaptor3d_HCurve.hxx>
68
69 #include <Prs3d_AngleAspect.hxx>
70 #include <Prs3d_ArrowAspect.hxx>
71 #include <Prs3d_LengthAspect.hxx>
72 #include <Prs3d_Drawer.hxx>
73
74 #include <TCollection_AsciiString.hxx>
75 #include <TCollection_ExtendedString.hxx>
76
77
78 #include <AIS.hxx>
79 #include <AIS_Drawer.hxx>
80 #include <gce_MakeDir.hxx>
81 #include <Select3D_SensitiveBox.hxx>
82
83
84
85 //======================================================================
86 //function : CircleFromPlanarFace
87 //purpose  : if possible gets circle from planar face
88 //=======================================================================
89 static Standard_Boolean CircleFromPlanarFace (const TopoDS_Shape& aFace,
90                                               Handle(Geom_Curve)& aCurve, 
91                                               gp_Pnt & ptfirst,
92                                               gp_Pnt & ptend)
93 {
94   TopExp_Explorer ExploEd (aFace, TopAbs_EDGE);
95   for ( ; ExploEd.More(); ExploEd.Next())
96     {
97       TopoDS_Edge curedge =  TopoDS::Edge (ExploEd.Current());
98       if (AIS::ComputeGeometry (curedge, aCurve, ptfirst, ptend))
99         if (aCurve->IsInstance (STANDARD_TYPE(Geom_Circle)) && 
100             !Handle(Geom_Circle)::DownCast(aCurve).IsNull())
101           return Standard_True;
102     }
103   return Standard_False;
104 }
105
106
107 //=======================================================================
108 //function : Constructor
109 //purpose  : 
110 //=======================================================================
111 AIS_RadiusDimension::AIS_RadiusDimension(const TopoDS_Shape& aShape, 
112                                          const Standard_Real aVal, 
113                                          const TCollection_ExtendedString& aText)
114 :mydrawFromCenter(Standard_True)
115 {
116   myFShape = aShape;
117   myVal = aVal;
118   myText = aText;
119   mySymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
120   myAutomaticPosition = Standard_True;
121
122   myArrowSize = myVal / 100.;
123   InitFirstShape();
124 }
125
126 //=======================================================================
127 //function : Constructor
128 //purpose  :(avec position et texte)
129 //=======================================================================
130 AIS_RadiusDimension::AIS_RadiusDimension( const TopoDS_Shape& aShape, 
131                                           const Standard_Real aVal, 
132                                           const TCollection_ExtendedString& aText, 
133                                           const gp_Pnt& aPosition,
134                                           const DsgPrs_ArrowSide aSymbolPrs, 
135                                           const Standard_Real anArrowSize )
136 :mydrawFromCenter(Standard_True)
137 {
138   myFShape = aShape;
139   myVal = aVal;
140   myText = aText;
141   myPosition = aPosition;
142   mySymbolPrs = aSymbolPrs;
143 #ifdef BUC60915
144   SetArrowSize( anArrowSize );
145 #else
146   myArrowSize = anArrowSize;
147 #endif
148   myAutomaticPosition = Standard_False;
149   InitFirstShape();
150 }
151
152 //=======================================================================
153 //function : InitFirstShape
154 //purpose  : 
155 //=======================================================================
156 void AIS_RadiusDimension::InitFirstShape()
157 {
158   if (myFShape.ShapeType() == TopAbs_FACE)
159     {
160       BRepAdaptor_Surface surfAlgo( TopoDS::Face( myFShape ) );
161       Standard_Real uFirst, uLast, vFirst, vLast;
162       uFirst = surfAlgo.FirstUParameter();
163       uLast = surfAlgo.LastUParameter();
164       vFirst = surfAlgo.FirstVParameter();
165       vLast = surfAlgo.LastVParameter();
166       Standard_Real uMoy = (uFirst + uLast)/2;
167       Standard_Real vMoy = (vFirst + vLast)/2;
168       Handle( Geom_Surface ) surf = surfAlgo.Surface().Surface();
169       surf = Handle( Geom_Surface )::DownCast( surf->Transformed( surfAlgo.Trsf() ) );
170       Handle( Geom_Curve ) aCurve;
171
172       if (surf->DynamicType() == STANDARD_TYPE(Geom_ToroidalSurface))
173         {
174           aCurve = surf->UIso( uMoy );
175           uFirst = vFirst;
176           uLast = vLast;
177         }
178       else if (surf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) 
179         {
180           Handle( Adaptor3d_HCurve ) BasisCurve = surfAlgo.BasisCurve();
181           if ( BasisCurve->GetType() == GeomAbs_Circle )
182             aCurve = surf->VIso( vMoy );
183           else return;
184         }
185       else if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane)) 
186         {
187           gp_Pnt FirstPnt, LastPnt;
188           if (CircleFromPlanarFace (TopoDS::Face(myFShape), aCurve, FirstPnt, LastPnt))
189 //        if (CircleFromPlanarFace (myFShape, aCurve, FirstPnt, LastPnt))
190             {
191               uFirst = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), FirstPnt);
192               uLast  = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), LastPnt);
193             }
194           else return;
195         }
196       else
197         aCurve = surf->VIso( vMoy );
198       
199       if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
200         myCircle = (Handle( Geom_Circle )::DownCast( aCurve ))->Circ();
201       else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
202         Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve); 
203         aCurve = tCurve->BasisCurve();
204         uFirst = tCurve->FirstParameter();
205         uLast  = tCurve->LastParameter();
206         if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
207           myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ
208         else return;
209       }
210       else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve)) {
211         gp_Pnt P1,P2,P3;
212         aCurve->D0(uFirst,P1);
213         aCurve->D0((uFirst+uLast)/2,P2);
214         aCurve->D0(uLast,P3);
215         gce_MakeCirc MakeCirc = gce_MakeCirc(P1,P2,P3);
216         myCircle = MakeCirc.Value();
217         uFirst = ElCLib::Parameter(myCircle,P1);
218         uLast = ElCLib::Parameter(myCircle,P2);
219       }
220
221       myFirstPar = uFirst;
222       myLastPar  = uLast;
223     } // TopAbs_FACE
224
225   else // it is edge or a wire
226     {
227       TopoDS_Edge anEdge;
228       if (myFShape.ShapeType() == TopAbs_WIRE)  {
229         TopExp_Explorer exp (myFShape,TopAbs_EDGE);
230         if (exp.More())  anEdge = TopoDS::Edge (exp.Current());
231       }
232       else {
233         if ( myFShape.ShapeType() == TopAbs_EDGE) { 
234           anEdge = TopoDS::Edge (myFShape);
235           BRepAdaptor_Curve AdaptedCurve (anEdge);
236           if (!AdaptedCurve.GetType() == GeomAbs_Circle) return;
237           
238           myCircle = AdaptedCurve.Circle();
239           myFirstPar = AdaptedCurve.FirstParameter();
240           myLastPar = AdaptedCurve.LastParameter();
241         }
242 #ifdef DEB
243         else {
244           cout << "AIS_RadiusDimension::InitFirstShape ==> myFShape.ShapeType() == " << myFShape.ShapeType()  << endl;
245         }
246 #endif
247       }
248     } 
249
250   myCenter = myCircle.Location();
251   myCircle.SetRadius(myVal);
252   while (myFirstPar > 2*M_PI) myFirstPar -= 2*M_PI;
253   while (myFirstPar < 0.0 ) myFirstPar += 2*M_PI;
254   while (myLastPar  > 2*M_PI) myLastPar  -= 2*M_PI;
255   while (myLastPar  < 0.0 ) myLastPar  += 2*M_PI;
256   myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));
257   myFirstLine = gce_MakeLin( myCenter, ElCLib::Value( myFirstPar, myCircle ) );
258   myLastLine  = gce_MakeLin( myCenter, ElCLib::Value( myLastPar, myCircle ) );
259 }
260
261 //=======================================================================
262 //function : SetFirstShape
263 //purpose  : 
264 //=======================================================================
265 void AIS_RadiusDimension::SetFirstShape( const TopoDS_Shape& aFShape )
266 {
267   myFShape = aFShape;
268   InitFirstShape();
269 }
270
271 //=======================================================================
272 //function : Compute
273 //purpose  : 
274 //=======================================================================
275 void AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
276                                   const Handle(Prs3d_Presentation)& aPresentation, 
277                                   const Standard_Integer /*aMode*/)
278 {
279   aPresentation->Clear();
280
281   ComputeRadius( aPresentation );
282 }
283
284 //=======================================================================
285 //function : Compute
286 //purpose  :  to avoid warning
287 //=======================================================================
288 void AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector, 
289                                   const Handle(Prs3d_Presentation)& aPresentation)
290 {
291 // Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector,const Handle(Prs3d_Presentation)& aPresentation)");
292  PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
293 }
294
295 //=======================================================================
296 //function : Compute
297 //purpose  :  to avoid warning
298 //=======================================================================
299 void AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager, 
300                                   const Handle(Graphic2d_GraphicObject)& aPresentation, 
301                                   const Standard_Integer aMode)
302 {
303 // Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager,const Handle(Graphic2d_GraphicObject)& aPresentation,const Standard_Integer aMode)");
304  PrsMgr_PresentableObject::Compute( aPresentationManager ,aPresentation,aMode) ;
305 }
306
307 //=======================================================================
308 //function : Compute
309 //purpose  : 
310 //=======================================================================
311
312 void AIS_RadiusDimension::Compute(const Handle_Prs3d_Projector& aProjector,
313                                   const Handle_Geom_Transformation& aTransformation,
314                                   const Handle_Prs3d_Presentation& aPresentation)
315 {
316 // Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
317  PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
318 }
319
320 //=======================================================================
321 //function : ComputeSelection
322 //purpose  : 
323 //=======================================================================
324 void AIS_RadiusDimension::ComputeSelection( const Handle(SelectMgr_Selection)& aSelection, 
325                                             const Standard_Integer )
326 {
327   gp_Pnt LineOrigin, LineEnd;
328   DsgPrs::ComputeRadiusLine( myCenter, myEndOfArrow, myPosition, mydrawFromCenter,
329                             LineOrigin,LineEnd); 
330   Handle(AIS_DimensionOwner) own = new AIS_DimensionOwner(this,7);
331   own->SetShape(myFShape);
332   Handle( Select3D_SensitiveSegment ) seg = new Select3D_SensitiveSegment( own, LineOrigin, LineEnd );
333   aSelection->Add( seg );
334
335   // Text
336   Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
337   Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
338                                                                    myPosition.X(),
339                                                                    myPosition.Y(),
340                                                                    myPosition.Z(),
341                                                                    myPosition.X() + size,
342                                                                    myPosition.Y() + size,
343                                                                    myPosition.Z() + size );
344   aSelection->Add(box);
345 }
346
347 //=======================================================================
348 //function : ComputeRadius
349 //purpose  : 
350 //=======================================================================
351
352 void AIS_RadiusDimension::ComputeRadius( const Handle( Prs3d_Presentation )& aPresentation )
353 {
354    if (myAutomaticPosition)
355      {
356        InitFirstShape();
357        myEndOfArrow = ElCLib::Value( (myFirstPar + myLastPar)/2, myCircle );
358        if(mydrawFromCenter) {
359          myPosition = myCenter;
360        }
361        else 
362          {
363            gp_Vec v1(myCenter, myEndOfArrow);
364            myPosition = myCenter.Translated(v1 * 1.2);
365          }
366        myAutomaticPosition = Standard_True;
367        
368        if (myIsSetBndBox)
369          myPosition = AIS::TranslatePointToBound(myPosition, gce_MakeDir( myCenter, myEndOfArrow ),
370                                                  myBndBox );       
371      }
372    else
373      {
374        //!Automaticposition
375        myPosition = AIS::ProjectPointOnPlane( myPosition, myPlane->Pln() );
376        Standard_Real PosPar = ElCLib::Parameter( myCircle, myPosition );
377        if (!AIS::InDomain(myFirstPar, myLastPar, PosPar))
378          { // not in domain
379            Standard_Real otherpar = PosPar + M_PI;
380            if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
381            if (AIS::InDomain(myFirstPar, myLastPar, otherpar)){
382              PosPar = otherpar;// parameter on circle
383              myEndOfArrow = ElCLib::Value( PosPar, myCircle );
384            }
385            else {
386              Standard_Real Teta1 = Abs( PosPar - myFirstPar ), Teta2 = Abs( PosPar - myLastPar );
387              if (Teta1 > M_PI)
388                Teta1 = 2.0*M_PI - Teta1; 
389              if (Teta2 > M_PI)
390                Teta2 = 2.0*M_PI - Teta2; 
391              if (Teta1 < Teta2) 
392                {
393                  if(myFirstLine.Contains(myPosition,Precision::Confusion()))
394                    PosPar = myFirstPar;
395                  else
396                    PosPar = myLastPar;
397                }
398              else
399                {
400                  if(myLastLine.Contains(myPosition,Precision::Confusion()))
401                    PosPar = myLastPar; 
402                  else 
403                    PosPar = myFirstPar;
404                }
405              myEndOfArrow = ElCLib::Value( PosPar, myCircle );
406              gp_Lin RadiusLine = gce_MakeLin( myCenter, myEndOfArrow );
407              // project on radius line
408              myPosition = ElCLib::Value( ElCLib::Parameter( RadiusLine, myPosition ), RadiusLine );
409            }
410          }
411        else
412          myEndOfArrow = ElCLib::Value( PosPar, myCircle );
413      }
414    
415    Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
416    Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
417    // size
418 #ifdef BUC60915
419    if( !myArrowSizeIsDefined ) {
420      myArrowSize = Min(myArrowSize,myVal/5.);
421    }
422    arr->SetLength(myArrowSize);
423 #else
424    if (myVal/5. > myArrowSize) 
425      arr->SetLength(myArrowSize);
426    else 
427      arr->SetLength(myVal/5.);
428 #endif
429    
430    DsgPrs_RadiusPresentation::Add( aPresentation, myDrawer, myText, myPosition,
431                                   myCenter, myEndOfArrow, mySymbolPrs, mydrawFromCenter );
432  }