0024624: Lost word in license statement in source files
[occt.git] / src / AIS / AIS_DiameterDimension.cxx
1 // Created on: 1996-12-05
2 // Created by: Jacques MINOT/Odile Olivier/Sergey ZARITCHNY
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <AIS_DiameterDimension.hxx>
18
19 #include <AIS.hxx>
20 #include <BRepLib_MakeEdge.hxx>
21 #include <ElCLib.hxx>
22 #include <GeomAPI_IntCS.hxx>
23 #include <Geom_Circle.hxx>
24 #include <Geom_Plane.hxx>
25 #include <gce_MakeDir.hxx>
26 #include <Standard_ProgramError.hxx>
27
28 IMPLEMENT_STANDARD_HANDLE (AIS_DiameterDimension, AIS_Dimension)
29 IMPLEMENT_STANDARD_RTTIEXT (AIS_DiameterDimension, AIS_Dimension)
30
31 namespace
32 {
33   static const Standard_ExtCharacter THE_DIAMETER_SYMBOL (0x00D8);
34 };
35
36 //=======================================================================
37 //function : Constructor
38 //purpose  : 
39 //=======================================================================
40 AIS_DiameterDimension::AIS_DiameterDimension (const gp_Circ& theCircle)
41 : AIS_Dimension (AIS_KOD_DIAMETER)
42 {
43   SetMeasuredGeometry (theCircle);
44   SetSpecialSymbol (THE_DIAMETER_SYMBOL);
45   SetDisplaySpecialSymbol (AIS_DSS_Before);
46   SetFlyout (0.0);
47 }
48
49 //=======================================================================
50 //function : Constructor
51 //purpose  : 
52 //=======================================================================
53 AIS_DiameterDimension::AIS_DiameterDimension (const gp_Circ& theCircle,
54                                               const gp_Pln& thePlane)
55 : AIS_Dimension (AIS_KOD_DIAMETER)
56 {
57   SetCustomPlane (thePlane);
58   SetMeasuredGeometry (theCircle);
59   SetSpecialSymbol (THE_DIAMETER_SYMBOL);
60   SetDisplaySpecialSymbol (AIS_DSS_Before);
61   SetFlyout (0.0);
62 }
63
64 //=======================================================================
65 //function : Constructor
66 //purpose  : 
67 //=======================================================================
68 AIS_DiameterDimension::AIS_DiameterDimension (const TopoDS_Shape& theShape)
69 : AIS_Dimension (AIS_KOD_DIAMETER)
70 {
71   SetMeasuredGeometry (theShape);
72   SetSpecialSymbol (THE_DIAMETER_SYMBOL);
73   SetDisplaySpecialSymbol (AIS_DSS_Before);
74   SetFlyout (0.0);
75 }
76
77 //=======================================================================
78 //function : Constructor
79 //purpose  : 
80 //=======================================================================
81 AIS_DiameterDimension::AIS_DiameterDimension (const TopoDS_Shape& theShape,
82                                               const gp_Pln& thePlane)
83 : AIS_Dimension (AIS_KOD_DIAMETER)
84 {
85   SetCustomPlane (thePlane);
86   SetMeasuredGeometry (theShape);
87   SetSpecialSymbol (THE_DIAMETER_SYMBOL);
88   SetDisplaySpecialSymbol (AIS_DSS_Before);
89   SetFlyout (0.0);
90 }
91
92 //=======================================================================
93 //function : AnchorPoint
94 //purpose  : 
95 //=======================================================================
96 gp_Pnt AIS_DiameterDimension::AnchorPoint()
97 {
98   if (!IsValid())
99   {
100     return gp::Origin();
101   }
102
103   return myAnchorPoint;
104 }
105
106 //=======================================================================
107 //function : SetMeasuredGeometry
108 //purpose  : 
109 //=======================================================================
110 void AIS_DiameterDimension::SetMeasuredGeometry (const gp_Circ& theCircle)
111 {
112   myCircle       = theCircle;
113   myGeometryType = GeometryType_Edge;
114   myShape        = BRepLib_MakeEdge (theCircle);
115   myAnchorPoint  = gp::Origin();
116   myIsValid      = IsValidCircle (myCircle);
117
118   if (myIsValid && myIsPlaneCustom)
119   {
120     ComputeAnchorPoint();
121   }
122   else if (!myIsPlaneCustom)
123   {
124     ComputePlane();
125     myAnchorPoint = ElCLib::Value (0.0, myCircle);
126   }
127
128   myIsValid &= CheckPlane (myPlane);
129
130   SetToUpdate();
131 }
132
133 //=======================================================================
134 //function : SetMeasuredGeometry
135 //purpose  : 
136 //=======================================================================
137 void AIS_DiameterDimension::SetMeasuredGeometry (const TopoDS_Shape& theShape)
138 {
139   gp_Pnt aDummyPnt (gp::Origin());
140   Standard_Boolean isClosed = Standard_False;
141
142   myGeometryType = GeometryType_UndefShapes;
143   myShape        = theShape;
144   myAnchorPoint  = gp::Origin();
145   myIsValid      = InitCircularDimension (theShape, myCircle, aDummyPnt, isClosed)
146                  && IsValidCircle (myCircle)
147                  && isClosed;
148
149   if (myIsValid && myIsPlaneCustom)
150   {
151     ComputeAnchorPoint();
152   }
153   else if (!myIsPlaneCustom)
154   {
155     ComputePlane();
156     myAnchorPoint = ElCLib::Value (0.0, myCircle);
157   }
158
159   myIsValid &= CheckPlane (myPlane);
160
161   SetToUpdate();
162 }
163
164 //=======================================================================
165 //function : CheckPlane
166 //purpose  : 
167 //=======================================================================
168 Standard_Boolean AIS_DiameterDimension::CheckPlane (const gp_Pln& thePlane) const
169 {
170   // Check if the circle center point belongs to plane.
171   if (!thePlane.Contains (myCircle.Location(), Precision::Confusion()))
172   {
173     return Standard_False;
174   }
175
176   return Standard_True;
177 }
178
179 //=======================================================================
180 //function : ComputePlane
181 //purpose  : 
182 //=======================================================================
183 void AIS_DiameterDimension::ComputePlane()
184 {
185   if (!IsValid())
186   {
187     return;
188   }
189
190   myPlane = gp_Pln (gp_Ax3 (myCircle.Position()));
191 }
192
193 //=======================================================================
194 //function : ComputeAnchorPoint
195 //purpose  : 
196 //=======================================================================
197 void AIS_DiameterDimension::ComputeAnchorPoint()
198 {
199   // Anchor point is an intersection of dimension plane and circle.
200   Handle(Geom_Circle) aCircle = new Geom_Circle (myCircle);
201   Handle(Geom_Plane) aPlane = new Geom_Plane (myPlane);
202   GeomAPI_IntCS anIntersector (aCircle, aPlane);
203   if (!anIntersector.IsDone())
204   {
205     myIsValid = Standard_False;
206     return;
207   }
208
209   // The circle lays on the plane.
210   if (anIntersector.NbPoints() != 2)
211   {
212     myAnchorPoint = ElCLib::Value (0.0, myCircle);
213     myIsValid = Standard_True;
214     return;
215   }
216
217   gp_Pnt aFirstPoint = anIntersector.Point (1);
218   gp_Pnt aSecondPoint = anIntersector.Point (2);
219
220   // Choose one of two intersection points that stands with
221   // positive direction of flyout.
222   // An anchor point is supposed to be the left attachment point.
223   gp_Dir aFirstDir = gce_MakeDir (aFirstPoint, myCircle.Location());
224   gp_Dir aDir = myPlane.Axis().Direction() ^ aFirstDir;
225   myAnchorPoint = (gp_Vec (aDir) * gp_Vec(myCircle.Position().Direction()) > 0.0)
226                   ? aFirstPoint
227                   : aSecondPoint;
228
229 }
230
231 //=======================================================================
232 //function : GetModelUnits
233 //purpose  :
234 //=======================================================================
235 const TCollection_AsciiString& AIS_DiameterDimension::GetModelUnits() const
236 {
237   return myDrawer->DimLengthModelUnits();
238 }
239
240 //=======================================================================
241 //function : GetDisplayUnits
242 //purpose  :
243 //=======================================================================
244 const TCollection_AsciiString& AIS_DiameterDimension::GetDisplayUnits() const
245 {
246   return myDrawer->DimLengthDisplayUnits();
247 }
248
249 //=======================================================================
250 //function : SetModelUnits
251 //purpose  :
252 //=======================================================================
253 void AIS_DiameterDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
254 {
255   myDrawer->SetDimLengthModelUnits (theUnits);
256 }
257
258 //=======================================================================
259 //function : SetDisplayUnits
260 //purpose  :
261 //=======================================================================
262 void AIS_DiameterDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
263 {
264   myDrawer->SetDimLengthDisplayUnits (theUnits);
265 }
266
267 //=======================================================================
268 //function : ComputeValue
269 //purpose  : 
270 //=======================================================================
271 Standard_Real AIS_DiameterDimension::ComputeValue() const
272 {
273   if (!IsValid())
274   {
275     return 0.0;
276   }
277
278   return myCircle.Radius() * 2.0;
279 }
280
281 //=======================================================================
282 //function : Compute
283 //purpose  : 
284 //=======================================================================
285 void AIS_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
286                                      const Handle(Prs3d_Presentation)& thePresentation, 
287                                      const Standard_Integer theMode)
288 {
289   thePresentation->Clear();
290   mySelectionGeom.Clear (theMode);
291
292   if (!IsValid())
293   {
294     return;
295   }
296
297   gp_Pnt aFirstPnt (gp::Origin());
298   gp_Pnt aSecondPnt (gp::Origin());
299   ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
300
301   DrawLinearDimension (thePresentation, theMode, aFirstPnt, aSecondPnt);
302 }
303
304 //=======================================================================
305 //function : ComputeFlyoutSelection
306 //purpose  : 
307 //=======================================================================
308 void AIS_DiameterDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
309                                                     const Handle(SelectMgr_EntityOwner)& theEntityOwner)
310 {
311   if (!IsValid())
312   {
313     return;
314   }
315
316   gp_Pnt aFirstPnt (gp::Origin());
317   gp_Pnt aSecondPnt (gp::Origin());
318   ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
319
320   ComputeLinearFlyouts (theSelection, theEntityOwner, aFirstPnt, aSecondPnt);
321 }
322
323 //=======================================================================
324 //function : ComputeSidePoints
325 //purpose  : 
326 //=======================================================================
327 void AIS_DiameterDimension::ComputeSidePoints (const gp_Circ& theCircle,
328                                                gp_Pnt& theFirstPnt,
329                                                gp_Pnt& theSecondPnt)
330 {
331   theFirstPnt = AnchorPoint();
332
333   gp_Vec aRadiusVector (theCircle.Location(), theFirstPnt);
334   theSecondPnt = theCircle.Location().Translated (-aRadiusVector);
335 }
336
337 //=======================================================================
338 //function : IsValidCircle
339 //purpose  : 
340 //=======================================================================
341 Standard_Boolean AIS_DiameterDimension::IsValidCircle (const gp_Circ& theCircle) const
342 {
343   return (theCircle.Radius() * 2.0) > Precision::Confusion();
344 }
345
346 //=======================================================================
347 //function : IsValidAnchor
348 //purpose  : 
349 //=======================================================================
350 Standard_Boolean AIS_DiameterDimension::IsValidAnchor (const gp_Circ& theCircle,
351                                                        const gp_Pnt& theAnchor) const
352 {
353   gp_Pln aCirclePlane (theCircle.Location(), theCircle.Axis().Direction());
354   Standard_Real anAnchorDist = theAnchor.Distance (theCircle.Location());
355   Standard_Real aRadius      = myCircle.Radius();
356
357   return Abs (anAnchorDist - aRadius) > Precision::Confusion()
358       && aCirclePlane.Contains (theAnchor, Precision::Confusion());
359 }
360
361 //=======================================================================
362 //function : GetTextPosition
363 //purpose  : 
364 //=======================================================================
365 const gp_Pnt AIS_DiameterDimension::GetTextPosition() const
366 {
367   if (IsTextPositionCustom())
368   {
369     return myFixedTextPosition;
370   }
371   
372   // Counts text position according to the dimension parameters
373   return GetTextPositionForLinear (myAnchorPoint, myCircle.Location());
374 }
375
376 //=======================================================================
377 //function : GetTextPosition
378 //purpose  : 
379 //=======================================================================
380 void AIS_DiameterDimension::SetTextPosition (const gp_Pnt& theTextPos)
381 {
382   if (!myIsValid)
383   {
384     return;
385   }
386
387   myIsTextPositionFixed = Standard_True;
388   myFixedTextPosition = theTextPos;
389
390   SetToUpdate();
391 }