0031456: Visualization - move out Dimensions and Relations from package AIS to PrsDims
[occt.git] / src / PrsDim / PrsDim_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
787ff240 17#include <PrsDim_DiameterDimension.hxx>
60bf98ae 18
787ff240 19#include <PrsDim.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
787ff240 28IMPLEMENT_STANDARD_RTTIEXT(PrsDim_DiameterDimension, PrsDim_Dimension)
92efcf78 29
d7bffd44 30namespace
31{
32 static const Standard_ExtCharacter THE_DIAMETER_SYMBOL (0x00D8);
a3f6f591 33}
d7bffd44 34
7fd59977 35//=======================================================================
36//function : Constructor
37//purpose :
38//=======================================================================
787ff240 39PrsDim_DiameterDimension::PrsDim_DiameterDimension (const gp_Circ& theCircle)
40: PrsDim_Dimension (PrsDim_KOD_DIAMETER)
60bf98ae 41{
42 SetMeasuredGeometry (theCircle);
43 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
787ff240 44 SetDisplaySpecialSymbol (PrsDim_DisplaySpecialSymbol_Before);
60bf98ae 45 SetFlyout (0.0);
46}
7fd59977 47
60bf98ae 48//=======================================================================
49//function : Constructor
50//purpose :
51//=======================================================================
787ff240 52PrsDim_DiameterDimension::PrsDim_DiameterDimension (const gp_Circ& theCircle,
53 const gp_Pln& thePlane)
54: PrsDim_Dimension (PrsDim_KOD_DIAMETER)
7fd59977 55{
60bf98ae 56 SetCustomPlane (thePlane);
57 SetMeasuredGeometry (theCircle);
d7bffd44 58 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
787ff240 59 SetDisplaySpecialSymbol (PrsDim_DisplaySpecialSymbol_Before);
d7bffd44 60 SetFlyout (0.0);
7fd59977 61}
62
63//=======================================================================
64//function : Constructor
65//purpose :
66//=======================================================================
787ff240 67PrsDim_DiameterDimension::PrsDim_DiameterDimension (const TopoDS_Shape& theShape)
68: PrsDim_Dimension (PrsDim_KOD_DIAMETER)
60bf98ae 69{
70 SetMeasuredGeometry (theShape);
71 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
787ff240 72 SetDisplaySpecialSymbol (PrsDim_DisplaySpecialSymbol_Before);
60bf98ae 73 SetFlyout (0.0);
74}
7fd59977 75
60bf98ae 76//=======================================================================
77//function : Constructor
78//purpose :
79//=======================================================================
787ff240 80PrsDim_DiameterDimension::PrsDim_DiameterDimension (const TopoDS_Shape& theShape,
81 const gp_Pln& thePlane)
82: PrsDim_Dimension (PrsDim_KOD_DIAMETER)
7fd59977 83{
60bf98ae 84 SetCustomPlane (thePlane);
85 SetMeasuredGeometry (theShape);
d7bffd44 86 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
787ff240 87 SetDisplaySpecialSymbol (PrsDim_DisplaySpecialSymbol_Before);
d7bffd44 88 SetFlyout (0.0);
60bf98ae 89}
90
91//=======================================================================
92//function : AnchorPoint
93//purpose :
94//=======================================================================
787ff240 95gp_Pnt PrsDim_DiameterDimension::AnchorPoint()
60bf98ae 96{
97 if (!IsValid())
a6eb515f 98 {
60bf98ae 99 return gp::Origin();
a6eb515f 100 }
60bf98ae 101
102 return myAnchorPoint;
103}
104
105//=======================================================================
106//function : SetMeasuredGeometry
107//purpose :
108//=======================================================================
787ff240 109void PrsDim_DiameterDimension::SetMeasuredGeometry (const gp_Circ& theCircle)
60bf98ae 110{
91b16a64 111 myCircle = theCircle;
112 myGeometryType = GeometryType_Edge;
113 myShape = BRepLib_MakeEdge (theCircle);
114 myAnchorPoint = gp::Origin();
115 myIsGeometryValid = IsValidCircle (myCircle);
60bf98ae 116
91b16a64 117 if (myIsGeometryValid && myIsPlaneCustom)
60bf98ae 118 {
119 ComputeAnchorPoint();
120 }
121 else if (!myIsPlaneCustom)
a6eb515f 122 {
60bf98ae 123 ComputePlane();
124 myAnchorPoint = ElCLib::Value (0.0, myCircle);
a6eb515f 125 }
60bf98ae 126
60bf98ae 127 SetToUpdate();
7fd59977 128}
129
130//=======================================================================
60bf98ae 131//function : SetMeasuredGeometry
132//purpose :
7fd59977 133//=======================================================================
787ff240 134void PrsDim_DiameterDimension::SetMeasuredGeometry (const TopoDS_Shape& theShape)
60bf98ae 135{
136 gp_Pnt aDummyPnt (gp::Origin());
137 Standard_Boolean isClosed = Standard_False;
7fd59977 138
91b16a64 139 myGeometryType = GeometryType_UndefShapes;
140 myShape = theShape;
141 myAnchorPoint = gp::Origin();
142 myIsGeometryValid = InitCircularDimension (theShape, myCircle, aDummyPnt, isClosed)
143 && IsValidCircle (myCircle)
144 && isClosed;
60bf98ae 145
91b16a64 146 if (myIsGeometryValid && myIsPlaneCustom)
60bf98ae 147 {
148 ComputeAnchorPoint();
149 }
150 else if (!myIsPlaneCustom)
151 {
152 ComputePlane();
153 myAnchorPoint = ElCLib::Value (0.0, myCircle);
154 }
155
60bf98ae 156 SetToUpdate();
157}
158
159//=======================================================================
160//function : CheckPlane
161//purpose :
162//=======================================================================
787ff240 163Standard_Boolean PrsDim_DiameterDimension::CheckPlane (const gp_Pln& thePlane) const
7fd59977 164{
60bf98ae 165 // Check if the circle center point belongs to plane.
166 if (!thePlane.Contains (myCircle.Location(), Precision::Confusion()))
167 {
168 return Standard_False;
169 }
170
171 return Standard_True;
7fd59977 172}
173
174//=======================================================================
60bf98ae 175//function : ComputePlane
176//purpose :
177//=======================================================================
787ff240 178void PrsDim_DiameterDimension::ComputePlane()
60bf98ae 179{
91b16a64 180 if (!myIsGeometryValid)
60bf98ae 181 {
182 return;
183 }
184
185 myPlane = gp_Pln (gp_Ax3 (myCircle.Position()));
186}
187
188//=======================================================================
189//function : ComputeAnchorPoint
7fd59977 190//purpose :
191//=======================================================================
787ff240 192void PrsDim_DiameterDimension::ComputeAnchorPoint()
60bf98ae 193{
194 // Anchor point is an intersection of dimension plane and circle.
195 Handle(Geom_Circle) aCircle = new Geom_Circle (myCircle);
196 Handle(Geom_Plane) aPlane = new Geom_Plane (myPlane);
197 GeomAPI_IntCS anIntersector (aCircle, aPlane);
198 if (!anIntersector.IsDone())
199 {
91b16a64 200 myIsGeometryValid = Standard_False;
60bf98ae 201 return;
202 }
7fd59977 203
60bf98ae 204 // The circle lays on the plane.
205 if (anIntersector.NbPoints() != 2)
206 {
207 myAnchorPoint = ElCLib::Value (0.0, myCircle);
91b16a64 208 myIsGeometryValid = Standard_True;
60bf98ae 209 return;
210 }
211
212 gp_Pnt aFirstPoint = anIntersector.Point (1);
213 gp_Pnt aSecondPoint = anIntersector.Point (2);
214
215 // Choose one of two intersection points that stands with
216 // positive direction of flyout.
217 // An anchor point is supposed to be the left attachment point.
218 gp_Dir aFirstDir = gce_MakeDir (aFirstPoint, myCircle.Location());
219 gp_Dir aDir = myPlane.Axis().Direction() ^ aFirstDir;
220 myAnchorPoint = (gp_Vec (aDir) * gp_Vec(myCircle.Position().Direction()) > 0.0)
221 ? aFirstPoint
222 : aSecondPoint;
223
224}
225
226//=======================================================================
227//function : GetModelUnits
228//purpose :
229//=======================================================================
787ff240 230const TCollection_AsciiString& PrsDim_DiameterDimension::GetModelUnits() const
60bf98ae 231{
232 return myDrawer->DimLengthModelUnits();
233}
234
235//=======================================================================
236//function : GetDisplayUnits
237//purpose :
238//=======================================================================
787ff240 239const TCollection_AsciiString& PrsDim_DiameterDimension::GetDisplayUnits() const
60bf98ae 240{
241 return myDrawer->DimLengthDisplayUnits();
242}
243
244//=======================================================================
245//function : SetModelUnits
246//purpose :
247//=======================================================================
787ff240 248void PrsDim_DiameterDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
60bf98ae 249{
250 myDrawer->SetDimLengthModelUnits (theUnits);
251}
252
253//=======================================================================
254//function : SetDisplayUnits
255//purpose :
256//=======================================================================
787ff240 257void PrsDim_DiameterDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
60bf98ae 258{
259 myDrawer->SetDimLengthDisplayUnits (theUnits);
260}
261
262//=======================================================================
263//function : ComputeValue
264//purpose :
265//=======================================================================
787ff240 266Standard_Real PrsDim_DiameterDimension::ComputeValue() const
60bf98ae 267{
268 if (!IsValid())
269 {
270 return 0.0;
271 }
272
273 return myCircle.Radius() * 2.0;
274}
275
276//=======================================================================
277//function : Compute
278//purpose :
279//=======================================================================
787ff240 280void PrsDim_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
281 const Handle(Prs3d_Presentation)& thePresentation,
282 const Standard_Integer theMode)
7fd59977 283{
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//=======================================================================
787ff240 302void PrsDim_DiameterDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
303 const Handle(SelectMgr_EntityOwner)& theEntityOwner)
60bf98ae 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//=======================================================================
787ff240 321void PrsDim_DiameterDimension::ComputeSidePoints (const gp_Circ& theCircle,
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//=======================================================================
787ff240 335Standard_Boolean PrsDim_DiameterDimension::IsValidCircle (const gp_Circ& theCircle) const
60bf98ae 336{
337 return (theCircle.Radius() * 2.0) > Precision::Confusion();
338}
7fd59977 339
60bf98ae 340//=======================================================================
341//function : IsValidAnchor
342//purpose :
343//=======================================================================
787ff240 344Standard_Boolean PrsDim_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//=======================================================================
787ff240 359gp_Pnt PrsDim_DiameterDimension::GetTextPosition() const
af203d54 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//=======================================================================
787ff240 374void PrsDim_DiameterDimension::SetTextPosition (const gp_Pnt& theTextPos)
af203d54 375{
91b16a64 376 if (!IsValid())
af203d54 377 {
378 return;
379 }
380
381 myIsTextPositionFixed = Standard_True;
382 myFixedTextPosition = theTextPos;
383
384 SetToUpdate();
385}