0027916: Visualization - access violation occurs within AIS_ColoredShape::Compute...
[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
92efcf78 29IMPLEMENT_STANDARD_RTTIEXT(AIS_DiameterDimension,AIS_Dimension)
30
d7bffd44 31namespace
32{
33 static const Standard_ExtCharacter THE_DIAMETER_SYMBOL (0x00D8);
a3f6f591 34}
d7bffd44 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{
91b16a64 112 myCircle = theCircle;
113 myGeometryType = GeometryType_Edge;
114 myShape = BRepLib_MakeEdge (theCircle);
115 myAnchorPoint = gp::Origin();
116 myIsGeometryValid = IsValidCircle (myCircle);
60bf98ae 117
91b16a64 118 if (myIsGeometryValid && myIsPlaneCustom)
60bf98ae 119 {
120 ComputeAnchorPoint();
121 }
122 else if (!myIsPlaneCustom)
a6eb515f 123 {
60bf98ae 124 ComputePlane();
125 myAnchorPoint = ElCLib::Value (0.0, myCircle);
a6eb515f 126 }
60bf98ae 127
60bf98ae 128 SetToUpdate();
7fd59977 129}
130
7fd59977 131//=======================================================================
60bf98ae 132//function : SetMeasuredGeometry
133//purpose :
7fd59977 134//=======================================================================
60bf98ae 135void AIS_DiameterDimension::SetMeasuredGeometry (const TopoDS_Shape& theShape)
136{
137 gp_Pnt aDummyPnt (gp::Origin());
138 Standard_Boolean isClosed = Standard_False;
7fd59977 139
91b16a64 140 myGeometryType = GeometryType_UndefShapes;
141 myShape = theShape;
142 myAnchorPoint = gp::Origin();
143 myIsGeometryValid = InitCircularDimension (theShape, myCircle, aDummyPnt, isClosed)
144 && IsValidCircle (myCircle)
145 && isClosed;
60bf98ae 146
91b16a64 147 if (myIsGeometryValid && myIsPlaneCustom)
60bf98ae 148 {
149 ComputeAnchorPoint();
150 }
151 else if (!myIsPlaneCustom)
152 {
153 ComputePlane();
154 myAnchorPoint = ElCLib::Value (0.0, myCircle);
155 }
156
60bf98ae 157 SetToUpdate();
158}
159
160//=======================================================================
161//function : CheckPlane
162//purpose :
163//=======================================================================
164Standard_Boolean AIS_DiameterDimension::CheckPlane (const gp_Pln& thePlane) const
7fd59977 165{
60bf98ae 166 // Check if the circle center point belongs to plane.
167 if (!thePlane.Contains (myCircle.Location(), Precision::Confusion()))
168 {
169 return Standard_False;
170 }
171
172 return Standard_True;
7fd59977 173}
174
175//=======================================================================
60bf98ae 176//function : ComputePlane
177//purpose :
178//=======================================================================
179void AIS_DiameterDimension::ComputePlane()
180{
91b16a64 181 if (!myIsGeometryValid)
60bf98ae 182 {
183 return;
184 }
185
186 myPlane = gp_Pln (gp_Ax3 (myCircle.Position()));
187}
188
189//=======================================================================
190//function : ComputeAnchorPoint
7fd59977 191//purpose :
192//=======================================================================
60bf98ae 193void AIS_DiameterDimension::ComputeAnchorPoint()
194{
195 // Anchor point is an intersection of dimension plane and circle.
196 Handle(Geom_Circle) aCircle = new Geom_Circle (myCircle);
197 Handle(Geom_Plane) aPlane = new Geom_Plane (myPlane);
198 GeomAPI_IntCS anIntersector (aCircle, aPlane);
199 if (!anIntersector.IsDone())
200 {
91b16a64 201 myIsGeometryValid = Standard_False;
60bf98ae 202 return;
203 }
7fd59977 204
60bf98ae 205 // The circle lays on the plane.
206 if (anIntersector.NbPoints() != 2)
207 {
208 myAnchorPoint = ElCLib::Value (0.0, myCircle);
91b16a64 209 myIsGeometryValid = Standard_True;
60bf98ae 210 return;
211 }
212
213 gp_Pnt aFirstPoint = anIntersector.Point (1);
214 gp_Pnt aSecondPoint = anIntersector.Point (2);
215
216 // Choose one of two intersection points that stands with
217 // positive direction of flyout.
218 // An anchor point is supposed to be the left attachment point.
219 gp_Dir aFirstDir = gce_MakeDir (aFirstPoint, myCircle.Location());
220 gp_Dir aDir = myPlane.Axis().Direction() ^ aFirstDir;
221 myAnchorPoint = (gp_Vec (aDir) * gp_Vec(myCircle.Position().Direction()) > 0.0)
222 ? aFirstPoint
223 : aSecondPoint;
224
225}
226
227//=======================================================================
228//function : GetModelUnits
229//purpose :
230//=======================================================================
231const TCollection_AsciiString& AIS_DiameterDimension::GetModelUnits() const
232{
233 return myDrawer->DimLengthModelUnits();
234}
235
236//=======================================================================
237//function : GetDisplayUnits
238//purpose :
239//=======================================================================
240const TCollection_AsciiString& AIS_DiameterDimension::GetDisplayUnits() const
241{
242 return myDrawer->DimLengthDisplayUnits();
243}
244
245//=======================================================================
246//function : SetModelUnits
247//purpose :
248//=======================================================================
249void AIS_DiameterDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
250{
251 myDrawer->SetDimLengthModelUnits (theUnits);
252}
253
254//=======================================================================
255//function : SetDisplayUnits
256//purpose :
257//=======================================================================
258void AIS_DiameterDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
259{
260 myDrawer->SetDimLengthDisplayUnits (theUnits);
261}
262
263//=======================================================================
264//function : ComputeValue
265//purpose :
266//=======================================================================
267Standard_Real AIS_DiameterDimension::ComputeValue() const
268{
269 if (!IsValid())
270 {
271 return 0.0;
272 }
273
274 return myCircle.Radius() * 2.0;
275}
276
277//=======================================================================
278//function : Compute
279//purpose :
280//=======================================================================
a6eb515f 281void AIS_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
282 const Handle(Prs3d_Presentation)& thePresentation,
283 const Standard_Integer theMode)
7fd59977 284{
fe83e1ea 285 mySelectionGeom.Clear (theMode);
a6eb515f 286
60bf98ae 287 if (!IsValid())
a6eb515f 288 {
60bf98ae 289 return;
7fd59977 290 }
7fd59977 291
60bf98ae 292 gp_Pnt aFirstPnt (gp::Origin());
293 gp_Pnt aSecondPnt (gp::Origin());
af203d54 294 ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
60bf98ae 295
296 DrawLinearDimension (thePresentation, theMode, aFirstPnt, aSecondPnt);
297}
298
299//=======================================================================
300//function : ComputeFlyoutSelection
301//purpose :
302//=======================================================================
303void AIS_DiameterDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
304 const Handle(SelectMgr_EntityOwner)& theEntityOwner)
305{
306 if (!IsValid())
a6eb515f 307 {
60bf98ae 308 return;
7fd59977 309 }
310
60bf98ae 311 gp_Pnt aFirstPnt (gp::Origin());
312 gp_Pnt aSecondPnt (gp::Origin());
af203d54 313 ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
60bf98ae 314
315 ComputeLinearFlyouts (theSelection, theEntityOwner, aFirstPnt, aSecondPnt);
7fd59977 316}
317
318//=======================================================================
60bf98ae 319//function : ComputeSidePoints
7fd59977 320//purpose :
321//=======================================================================
af203d54 322void AIS_DiameterDimension::ComputeSidePoints (const gp_Circ& theCircle,
60bf98ae 323 gp_Pnt& theFirstPnt,
324 gp_Pnt& theSecondPnt)
7fd59977 325{
60bf98ae 326 theFirstPnt = AnchorPoint();
327
af203d54 328 gp_Vec aRadiusVector (theCircle.Location(), theFirstPnt);
329 theSecondPnt = theCircle.Location().Translated (-aRadiusVector);
7fd59977 330}
331
7fd59977 332//=======================================================================
60bf98ae 333//function : IsValidCircle
7fd59977 334//purpose :
335//=======================================================================
60bf98ae 336Standard_Boolean AIS_DiameterDimension::IsValidCircle (const gp_Circ& theCircle) const
337{
338 return (theCircle.Radius() * 2.0) > Precision::Confusion();
339}
7fd59977 340
60bf98ae 341//=======================================================================
342//function : IsValidAnchor
343//purpose :
344//=======================================================================
345Standard_Boolean AIS_DiameterDimension::IsValidAnchor (const gp_Circ& theCircle,
346 const gp_Pnt& theAnchor) const
7fd59977 347{
60bf98ae 348 gp_Pln aCirclePlane (theCircle.Location(), theCircle.Axis().Direction());
349 Standard_Real anAnchorDist = theAnchor.Distance (theCircle.Location());
350 Standard_Real aRadius = myCircle.Radius();
351
352 return Abs (anAnchorDist - aRadius) > Precision::Confusion()
353 && aCirclePlane.Contains (theAnchor, Precision::Confusion());
7fd59977 354}
af203d54 355
356//=======================================================================
357//function : GetTextPosition
358//purpose :
359//=======================================================================
360const gp_Pnt AIS_DiameterDimension::GetTextPosition() const
361{
362 if (IsTextPositionCustom())
363 {
364 return myFixedTextPosition;
365 }
366
367 // Counts text position according to the dimension parameters
368 return GetTextPositionForLinear (myAnchorPoint, myCircle.Location());
369}
370
371//=======================================================================
372//function : GetTextPosition
373//purpose :
374//=======================================================================
375void AIS_DiameterDimension::SetTextPosition (const gp_Pnt& theTextPos)
376{
91b16a64 377 if (!IsValid())
af203d54 378 {
379 return;
380 }
381
382 myIsTextPositionFixed = Standard_True;
383 myFixedTextPosition = theTextPos;
384
385 SetToUpdate();
386}