0024425: Improve usage ergonomics of new dimension presentations
[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 #include <AIS_RadiusDimension.hxx>
22
23 #include <AIS.hxx>
24 #include <BRepLib_MakeEdge.hxx>
25 #include <ElCLib.hxx>
26 #include <gce_MakeDir.hxx>
27
28 IMPLEMENT_STANDARD_HANDLE (AIS_RadiusDimension, AIS_Dimension)
29 IMPLEMENT_STANDARD_RTTIEXT (AIS_RadiusDimension, AIS_Dimension)
30
31 namespace
32 {
33   static const Standard_ExtCharacter THE_RADIUS_SYMBOL ('R');
34 };
35
36 //=======================================================================
37 //function : Constructor
38 //purpose  : 
39 //=======================================================================
40 AIS_RadiusDimension::AIS_RadiusDimension (const gp_Circ& theCircle)
41 : AIS_Dimension (AIS_KOD_RADIUS)
42 {
43   SetMeasuredGeometry (theCircle);
44   SetSpecialSymbol (THE_RADIUS_SYMBOL);
45   SetDisplaySpecialSymbol (AIS_DSS_Before);
46   SetFlyout (0.0);
47 }
48
49 //=======================================================================
50 //function : Constructor
51 //purpose  : 
52 //=======================================================================
53 AIS_RadiusDimension::AIS_RadiusDimension (const gp_Circ& theCircle,
54                                           const gp_Pnt& theAttachPoint)
55 : AIS_Dimension (AIS_KOD_RADIUS)
56 {
57   SetMeasuredGeometry (theCircle, theAttachPoint);
58   SetSpecialSymbol (THE_RADIUS_SYMBOL);
59   SetDisplaySpecialSymbol (AIS_DSS_Before);
60   SetFlyout (0.0);
61 }
62
63 //=======================================================================
64 //function : Constructor
65 //purpose  :
66 //=======================================================================
67 AIS_RadiusDimension::AIS_RadiusDimension (const TopoDS_Shape& theShape)
68 : AIS_Dimension (AIS_KOD_RADIUS)
69 {
70   SetMeasuredGeometry (theShape);
71   SetSpecialSymbol (THE_RADIUS_SYMBOL);
72   SetDisplaySpecialSymbol (AIS_DSS_Before);
73   SetFlyout (0.0);
74 }
75
76 //=======================================================================
77 //function : SetMeasuredGeometry
78 //purpose  : 
79 //=======================================================================
80 void AIS_RadiusDimension::SetMeasuredGeometry (const gp_Circ& theCircle)
81 {
82   myCircle       = theCircle;
83   myGeometryType = GeometryType_Edge;
84   myShape        = BRepLib_MakeEdge (theCircle);
85   myAnchorPoint  = ElCLib::Value (0, myCircle);
86   myIsValid      = IsValidCircle (myCircle);
87
88   if (myIsValid)
89   {
90     ComputePlane();
91   }
92
93   myIsValid &= CheckPlane (myPlane);
94
95   SetToUpdate();
96 }
97
98 //=======================================================================
99 //function : SetMeasuredGeometry
100 //purpose  : 
101 //=======================================================================
102 void AIS_RadiusDimension::SetMeasuredGeometry (const gp_Circ& theCircle,
103                                                const gp_Pnt&  theAnchorPoint)
104 {
105   myCircle       = theCircle;
106   myGeometryType = GeometryType_Edge;
107   myShape        = BRepLib_MakeEdge (theCircle);
108   myAnchorPoint  = theAnchorPoint;
109   myIsValid      = IsValidCircle (myCircle) && IsValidAnchor (myCircle, theAnchorPoint);
110
111   if (myIsValid)
112   {
113     ComputePlane();
114   }
115
116   myIsValid &= CheckPlane (myPlane);
117
118   SetToUpdate();
119 }
120
121 //=======================================================================
122 //function : SetMeasuredGeometry
123 //purpose  : 
124 //=======================================================================
125 void AIS_RadiusDimension::SetMeasuredGeometry (const TopoDS_Shape& theShape)
126 {
127   Standard_Boolean isClosed = Standard_False;
128   myShape        = theShape;
129   myGeometryType = GeometryType_UndefShapes;
130   myIsValid      = InitCircularDimension (theShape, myCircle, myAnchorPoint, isClosed) 
131                 && IsValidCircle (myCircle);
132
133   if (myIsValid)
134   {
135     ComputePlane();
136   }
137
138   myIsValid &= CheckPlane (myPlane);
139
140   SetToUpdate();
141 }
142
143 //=======================================================================
144 //function : CheckPlane
145 //purpose  : 
146 //=======================================================================
147 Standard_Boolean AIS_RadiusDimension::CheckPlane (const gp_Pln& thePlane) const
148 {
149   // Check if anchor point and circle center point belong to plane.
150   if (!thePlane.Contains (myAnchorPoint, Precision::Confusion()) &&
151       !thePlane.Contains (myCircle.Location(), Precision::Confusion()))
152   {
153     return Standard_False;
154   }
155
156   return Standard_True;
157 }
158
159 //=======================================================================
160 //function : ComputePlane
161 //purpose  : 
162 //=======================================================================
163 void AIS_RadiusDimension::ComputePlane()
164 {
165   if (!IsValid())
166   {
167     return;
168   }
169
170   gp_Dir aDimensionX = gce_MakeDir (myAnchorPoint, myCircle.Location());
171
172   myPlane = gp_Pln (gp_Ax3 (myCircle.Location(),
173                             myCircle.Axis().Direction(),
174                             aDimensionX));
175 }
176
177 //=======================================================================
178 //function : GetModelUnits
179 //purpose  :
180 //=======================================================================
181 const TCollection_AsciiString& AIS_RadiusDimension::GetModelUnits() const
182 {
183   return myDrawer->DimLengthModelUnits();
184 }
185
186 //=======================================================================
187 //function : GetDisplayUnits
188 //purpose  :
189 //=======================================================================
190 const TCollection_AsciiString& AIS_RadiusDimension::GetDisplayUnits() const
191 {
192   return myDrawer->DimLengthDisplayUnits();
193 }
194
195 //=======================================================================
196 //function : SetModelUnits
197 //purpose  :
198 //=======================================================================
199 void AIS_RadiusDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
200 {
201   myDrawer->SetDimLengthModelUnits (theUnits);
202 }
203
204 //=======================================================================
205 //function : SetDisplayUnits
206 //purpose  :
207 //=======================================================================
208 void AIS_RadiusDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
209 {
210   myDrawer->SetDimLengthDisplayUnits(theUnits);
211 }
212
213 //=======================================================================
214 //function : ComputeValue
215 //purpose  : 
216 //=======================================================================
217 Standard_Real AIS_RadiusDimension::ComputeValue() const
218 {
219   if (!IsValid())
220   {
221     return 0.0;
222   }
223
224   return myCircle.Radius();
225 }
226
227 //=======================================================================
228 //function : Compute
229 //purpose  : 
230 //=======================================================================
231 void AIS_RadiusDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
232                                    const Handle(Prs3d_Presentation)& thePresentation,
233                                    const Standard_Integer theMode)
234 {
235   thePresentation->Clear();
236   mySelectionGeom.Clear (theMode);
237
238   if (!IsValid())
239   {
240     return;
241   }
242
243   DrawLinearDimension (thePresentation, theMode, myAnchorPoint, myCircle.Location(), Standard_True);
244 }
245
246 //=======================================================================
247 //function : IsValidCircle
248 //purpose  : 
249 //=======================================================================
250 Standard_Boolean AIS_RadiusDimension::IsValidCircle (const gp_Circ& theCircle) const
251 {
252   return theCircle.Radius() > Precision::Confusion();
253 }
254
255 //=======================================================================
256 //function : IsValidAnchor
257 //purpose  : 
258 //=======================================================================
259 Standard_Boolean AIS_RadiusDimension::IsValidAnchor (const gp_Circ& theCircle,
260                                                      const gp_Pnt& theAnchor) const
261 {
262   gp_Pln aCirclePlane (theCircle.Location(), theCircle.Axis().Direction());
263   Standard_Real anAnchorDist = theAnchor.Distance (theCircle.Location());
264   Standard_Real aRadius      = myCircle.Radius();
265
266   return Abs (anAnchorDist - aRadius) > Precision::Confusion()
267       && aCirclePlane.Contains (theAnchor, Precision::Confusion());
268 }