0024428: Implementation of LGPL license
[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//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public 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.
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
60bf98ae 28IMPLEMENT_STANDARD_HANDLE (AIS_DiameterDimension, AIS_Dimension)
29IMPLEMENT_STANDARD_RTTIEXT (AIS_DiameterDimension, AIS_Dimension)
7fd59977 30
d7bffd44 31namespace
32{
33 static const Standard_ExtCharacter THE_DIAMETER_SYMBOL (0x00D8);
34};
35
7fd59977 36//=======================================================================
37//function : Constructor
38//purpose :
39//=======================================================================
60bf98ae 40AIS_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}
7fd59977 48
60bf98ae 49//=======================================================================
50//function : Constructor
51//purpose :
52//=======================================================================
53AIS_DiameterDimension::AIS_DiameterDimension (const gp_Circ& theCircle,
54 const gp_Pln& thePlane)
55: AIS_Dimension (AIS_KOD_DIAMETER)
7fd59977 56{
60bf98ae 57 SetCustomPlane (thePlane);
58 SetMeasuredGeometry (theCircle);
d7bffd44 59 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
a6eb515f 60 SetDisplaySpecialSymbol (AIS_DSS_Before);
d7bffd44 61 SetFlyout (0.0);
7fd59977 62}
63
64//=======================================================================
65//function : Constructor
66//purpose :
67//=======================================================================
60bf98ae 68AIS_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}
7fd59977 76
60bf98ae 77//=======================================================================
78//function : Constructor
79//purpose :
80//=======================================================================
81AIS_DiameterDimension::AIS_DiameterDimension (const TopoDS_Shape& theShape,
82 const gp_Pln& thePlane)
83: AIS_Dimension (AIS_KOD_DIAMETER)
7fd59977 84{
60bf98ae 85 SetCustomPlane (thePlane);
86 SetMeasuredGeometry (theShape);
d7bffd44 87 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
a6eb515f 88 SetDisplaySpecialSymbol (AIS_DSS_Before);
d7bffd44 89 SetFlyout (0.0);
60bf98ae 90}
91
92//=======================================================================
93//function : AnchorPoint
94//purpose :
95//=======================================================================
96gp_Pnt AIS_DiameterDimension::AnchorPoint()
97{
98 if (!IsValid())
a6eb515f 99 {
60bf98ae 100 return gp::Origin();
a6eb515f 101 }
60bf98ae 102
103 return myAnchorPoint;
104}
105
106//=======================================================================
107//function : SetMeasuredGeometry
108//purpose :
109//=======================================================================
110void 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)
a6eb515f 123 {
60bf98ae 124 ComputePlane();
125 myAnchorPoint = ElCLib::Value (0.0, myCircle);
a6eb515f 126 }
60bf98ae 127
128 myIsValid &= CheckPlane (myPlane);
129
130 SetToUpdate();
7fd59977 131}
132
7fd59977 133//=======================================================================
60bf98ae 134//function : SetMeasuredGeometry
135//purpose :
7fd59977 136//=======================================================================
60bf98ae 137void AIS_DiameterDimension::SetMeasuredGeometry (const TopoDS_Shape& theShape)
138{
139 gp_Pnt aDummyPnt (gp::Origin());
140 Standard_Boolean isClosed = Standard_False;
7fd59977 141
60bf98ae 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//=======================================================================
168Standard_Boolean AIS_DiameterDimension::CheckPlane (const gp_Pln& thePlane) const
7fd59977 169{
60bf98ae 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;
7fd59977 177}
178
179//=======================================================================
60bf98ae 180//function : ComputePlane
181//purpose :
182//=======================================================================
183void 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
7fd59977 195//purpose :
196//=======================================================================
60bf98ae 197void 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 }
7fd59977 208
60bf98ae 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//=======================================================================
235const TCollection_AsciiString& AIS_DiameterDimension::GetModelUnits() const
236{
237 return myDrawer->DimLengthModelUnits();
238}
239
240//=======================================================================
241//function : GetDisplayUnits
242//purpose :
243//=======================================================================
244const TCollection_AsciiString& AIS_DiameterDimension::GetDisplayUnits() const
245{
246 return myDrawer->DimLengthDisplayUnits();
247}
248
249//=======================================================================
250//function : SetModelUnits
251//purpose :
252//=======================================================================
253void AIS_DiameterDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
254{
255 myDrawer->SetDimLengthModelUnits (theUnits);
256}
257
258//=======================================================================
259//function : SetDisplayUnits
260//purpose :
261//=======================================================================
262void AIS_DiameterDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
263{
264 myDrawer->SetDimLengthDisplayUnits (theUnits);
265}
266
267//=======================================================================
268//function : ComputeValue
269//purpose :
270//=======================================================================
271Standard_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//=======================================================================
a6eb515f 285void AIS_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
286 const Handle(Prs3d_Presentation)& thePresentation,
287 const Standard_Integer theMode)
7fd59977 288{
a6eb515f 289 thePresentation->Clear();
fe83e1ea 290 mySelectionGeom.Clear (theMode);
a6eb515f 291
60bf98ae 292 if (!IsValid())
a6eb515f 293 {
60bf98ae 294 return;
7fd59977 295 }
7fd59977 296
60bf98ae 297 gp_Pnt aFirstPnt (gp::Origin());
298 gp_Pnt aSecondPnt (gp::Origin());
299 ComputeSidePoints (myCircle, GetPlane(), aFirstPnt, aSecondPnt);
300
301 DrawLinearDimension (thePresentation, theMode, aFirstPnt, aSecondPnt);
302}
303
304//=======================================================================
305//function : ComputeFlyoutSelection
306//purpose :
307//=======================================================================
308void AIS_DiameterDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
309 const Handle(SelectMgr_EntityOwner)& theEntityOwner)
310{
311 if (!IsValid())
a6eb515f 312 {
60bf98ae 313 return;
7fd59977 314 }
315
60bf98ae 316 gp_Pnt aFirstPnt (gp::Origin());
317 gp_Pnt aSecondPnt (gp::Origin());
318 ComputeSidePoints (myCircle, GetPlane(), aFirstPnt, aSecondPnt);
319
320 ComputeLinearFlyouts (theSelection, theEntityOwner, aFirstPnt, aSecondPnt);
7fd59977 321}
322
323//=======================================================================
60bf98ae 324//function : ComputeSidePoints
7fd59977 325//purpose :
326//=======================================================================
60bf98ae 327void AIS_DiameterDimension::ComputeSidePoints (const gp_Circ& /*theCircle*/,
328 const gp_Pln& /*thePlane*/,
329 gp_Pnt& theFirstPnt,
330 gp_Pnt& theSecondPnt)
7fd59977 331{
60bf98ae 332 theFirstPnt = AnchorPoint();
333
334 gp_Vec aRadiusVector (myCircle.Location(), theFirstPnt);
335 theSecondPnt = myCircle.Location().Translated (-aRadiusVector);
7fd59977 336}
337
7fd59977 338//=======================================================================
60bf98ae 339//function : IsValidCircle
7fd59977 340//purpose :
341//=======================================================================
60bf98ae 342Standard_Boolean AIS_DiameterDimension::IsValidCircle (const gp_Circ& theCircle) const
343{
344 return (theCircle.Radius() * 2.0) > Precision::Confusion();
345}
7fd59977 346
60bf98ae 347//=======================================================================
348//function : IsValidAnchor
349//purpose :
350//=======================================================================
351Standard_Boolean AIS_DiameterDimension::IsValidAnchor (const gp_Circ& theCircle,
352 const gp_Pnt& theAnchor) const
7fd59977 353{
60bf98ae 354 gp_Pln aCirclePlane (theCircle.Location(), theCircle.Axis().Direction());
355 Standard_Real anAnchorDist = theAnchor.Distance (theCircle.Location());
356 Standard_Real aRadius = myCircle.Radius();
357
358 return Abs (anAnchorDist - aRadius) > Precision::Confusion()
359 && aCirclePlane.Contains (theAnchor, Precision::Confusion());
7fd59977 360}