0027664: Incomplete intersection curve from the attached shapes
[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{
a6eb515f 285 thePresentation->Clear();
fe83e1ea 286 mySelectionGeom.Clear (theMode);
a6eb515f 287
60bf98ae 288 if (!IsValid())
a6eb515f 289 {
60bf98ae 290 return;
7fd59977 291 }
7fd59977 292
60bf98ae 293 gp_Pnt aFirstPnt (gp::Origin());
294 gp_Pnt aSecondPnt (gp::Origin());
af203d54 295 ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
60bf98ae 296
297 DrawLinearDimension (thePresentation, theMode, aFirstPnt, aSecondPnt);
298}
299
300//=======================================================================
301//function : ComputeFlyoutSelection
302//purpose :
303//=======================================================================
304void AIS_DiameterDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
305 const Handle(SelectMgr_EntityOwner)& theEntityOwner)
306{
307 if (!IsValid())
a6eb515f 308 {
60bf98ae 309 return;
7fd59977 310 }
311
60bf98ae 312 gp_Pnt aFirstPnt (gp::Origin());
313 gp_Pnt aSecondPnt (gp::Origin());
af203d54 314 ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
60bf98ae 315
316 ComputeLinearFlyouts (theSelection, theEntityOwner, aFirstPnt, aSecondPnt);
7fd59977 317}
318
319//=======================================================================
60bf98ae 320//function : ComputeSidePoints
7fd59977 321//purpose :
322//=======================================================================
af203d54 323void AIS_DiameterDimension::ComputeSidePoints (const gp_Circ& theCircle,
60bf98ae 324 gp_Pnt& theFirstPnt,
325 gp_Pnt& theSecondPnt)
7fd59977 326{
60bf98ae 327 theFirstPnt = AnchorPoint();
328
af203d54 329 gp_Vec aRadiusVector (theCircle.Location(), theFirstPnt);
330 theSecondPnt = theCircle.Location().Translated (-aRadiusVector);
7fd59977 331}
332
7fd59977 333//=======================================================================
60bf98ae 334//function : IsValidCircle
7fd59977 335//purpose :
336//=======================================================================
60bf98ae 337Standard_Boolean AIS_DiameterDimension::IsValidCircle (const gp_Circ& theCircle) const
338{
339 return (theCircle.Radius() * 2.0) > Precision::Confusion();
340}
7fd59977 341
60bf98ae 342//=======================================================================
343//function : IsValidAnchor
344//purpose :
345//=======================================================================
346Standard_Boolean AIS_DiameterDimension::IsValidAnchor (const gp_Circ& theCircle,
347 const gp_Pnt& theAnchor) const
7fd59977 348{
60bf98ae 349 gp_Pln aCirclePlane (theCircle.Location(), theCircle.Axis().Direction());
350 Standard_Real anAnchorDist = theAnchor.Distance (theCircle.Location());
351 Standard_Real aRadius = myCircle.Radius();
352
353 return Abs (anAnchorDist - aRadius) > Precision::Confusion()
354 && aCirclePlane.Contains (theAnchor, Precision::Confusion());
7fd59977 355}
af203d54 356
357//=======================================================================
358//function : GetTextPosition
359//purpose :
360//=======================================================================
361const gp_Pnt AIS_DiameterDimension::GetTextPosition() const
362{
363 if (IsTextPositionCustom())
364 {
365 return myFixedTextPosition;
366 }
367
368 // Counts text position according to the dimension parameters
369 return GetTextPositionForLinear (myAnchorPoint, myCircle.Location());
370}
371
372//=======================================================================
373//function : GetTextPosition
374//purpose :
375//=======================================================================
376void AIS_DiameterDimension::SetTextPosition (const gp_Pnt& theTextPos)
377{
91b16a64 378 if (!IsValid())
af203d54 379 {
380 return;
381 }
382
383 myIsTextPositionFixed = Standard_True;
384 myFixedTextPosition = theTextPos;
385
386 SetToUpdate();
387}