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