1 // Created on: 1996-12-05
2 // Created by: Jacques MINOT/Odile Olivier/Sergey ZARITCHNY
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <AIS_DiameterDimension.hxx>
20 #include <BRepLib_MakeEdge.hxx>
22 #include <GeomAPI_IntCS.hxx>
23 #include <Geom_Circle.hxx>
24 #include <Geom_Plane.hxx>
25 #include <gce_MakeDir.hxx>
26 #include <Standard_ProgramError.hxx>
29 IMPLEMENT_STANDARD_RTTIEXT(AIS_DiameterDimension,AIS_Dimension)
33 static const Standard_ExtCharacter THE_DIAMETER_SYMBOL (0x00D8);
36 //=======================================================================
37 //function : Constructor
39 //=======================================================================
40 AIS_DiameterDimension::AIS_DiameterDimension (const gp_Circ& theCircle)
41 : AIS_Dimension (AIS_KOD_DIAMETER)
43 SetMeasuredGeometry (theCircle);
44 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
45 SetDisplaySpecialSymbol (AIS_DSS_Before);
49 //=======================================================================
50 //function : Constructor
52 //=======================================================================
53 AIS_DiameterDimension::AIS_DiameterDimension (const gp_Circ& theCircle,
54 const gp_Pln& thePlane)
55 : AIS_Dimension (AIS_KOD_DIAMETER)
57 SetCustomPlane (thePlane);
58 SetMeasuredGeometry (theCircle);
59 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
60 SetDisplaySpecialSymbol (AIS_DSS_Before);
64 //=======================================================================
65 //function : Constructor
67 //=======================================================================
68 AIS_DiameterDimension::AIS_DiameterDimension (const TopoDS_Shape& theShape)
69 : AIS_Dimension (AIS_KOD_DIAMETER)
71 SetMeasuredGeometry (theShape);
72 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
73 SetDisplaySpecialSymbol (AIS_DSS_Before);
77 //=======================================================================
78 //function : Constructor
80 //=======================================================================
81 AIS_DiameterDimension::AIS_DiameterDimension (const TopoDS_Shape& theShape,
82 const gp_Pln& thePlane)
83 : AIS_Dimension (AIS_KOD_DIAMETER)
85 SetCustomPlane (thePlane);
86 SetMeasuredGeometry (theShape);
87 SetSpecialSymbol (THE_DIAMETER_SYMBOL);
88 SetDisplaySpecialSymbol (AIS_DSS_Before);
92 //=======================================================================
93 //function : AnchorPoint
95 //=======================================================================
96 gp_Pnt AIS_DiameterDimension::AnchorPoint()
103 return myAnchorPoint;
106 //=======================================================================
107 //function : SetMeasuredGeometry
109 //=======================================================================
110 void AIS_DiameterDimension::SetMeasuredGeometry (const gp_Circ& theCircle)
112 myCircle = theCircle;
113 myGeometryType = GeometryType_Edge;
114 myShape = BRepLib_MakeEdge (theCircle);
115 myAnchorPoint = gp::Origin();
116 myIsGeometryValid = IsValidCircle (myCircle);
118 if (myIsGeometryValid && myIsPlaneCustom)
120 ComputeAnchorPoint();
122 else if (!myIsPlaneCustom)
125 myAnchorPoint = ElCLib::Value (0.0, myCircle);
131 //=======================================================================
132 //function : SetMeasuredGeometry
134 //=======================================================================
135 void AIS_DiameterDimension::SetMeasuredGeometry (const TopoDS_Shape& theShape)
137 gp_Pnt aDummyPnt (gp::Origin());
138 Standard_Boolean isClosed = Standard_False;
140 myGeometryType = GeometryType_UndefShapes;
142 myAnchorPoint = gp::Origin();
143 myIsGeometryValid = InitCircularDimension (theShape, myCircle, aDummyPnt, isClosed)
144 && IsValidCircle (myCircle)
147 if (myIsGeometryValid && myIsPlaneCustom)
149 ComputeAnchorPoint();
151 else if (!myIsPlaneCustom)
154 myAnchorPoint = ElCLib::Value (0.0, myCircle);
160 //=======================================================================
161 //function : CheckPlane
163 //=======================================================================
164 Standard_Boolean AIS_DiameterDimension::CheckPlane (const gp_Pln& thePlane) const
166 // Check if the circle center point belongs to plane.
167 if (!thePlane.Contains (myCircle.Location(), Precision::Confusion()))
169 return Standard_False;
172 return Standard_True;
175 //=======================================================================
176 //function : ComputePlane
178 //=======================================================================
179 void AIS_DiameterDimension::ComputePlane()
181 if (!myIsGeometryValid)
186 myPlane = gp_Pln (gp_Ax3 (myCircle.Position()));
189 //=======================================================================
190 //function : ComputeAnchorPoint
192 //=======================================================================
193 void AIS_DiameterDimension::ComputeAnchorPoint()
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())
201 myIsGeometryValid = Standard_False;
205 // The circle lays on the plane.
206 if (anIntersector.NbPoints() != 2)
208 myAnchorPoint = ElCLib::Value (0.0, myCircle);
209 myIsGeometryValid = Standard_True;
213 gp_Pnt aFirstPoint = anIntersector.Point (1);
214 gp_Pnt aSecondPoint = anIntersector.Point (2);
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)
227 //=======================================================================
228 //function : GetModelUnits
230 //=======================================================================
231 const TCollection_AsciiString& AIS_DiameterDimension::GetModelUnits() const
233 return myDrawer->DimLengthModelUnits();
236 //=======================================================================
237 //function : GetDisplayUnits
239 //=======================================================================
240 const TCollection_AsciiString& AIS_DiameterDimension::GetDisplayUnits() const
242 return myDrawer->DimLengthDisplayUnits();
245 //=======================================================================
246 //function : SetModelUnits
248 //=======================================================================
249 void AIS_DiameterDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
251 myDrawer->SetDimLengthModelUnits (theUnits);
254 //=======================================================================
255 //function : SetDisplayUnits
257 //=======================================================================
258 void AIS_DiameterDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
260 myDrawer->SetDimLengthDisplayUnits (theUnits);
263 //=======================================================================
264 //function : ComputeValue
266 //=======================================================================
267 Standard_Real AIS_DiameterDimension::ComputeValue() const
274 return myCircle.Radius() * 2.0;
277 //=======================================================================
280 //=======================================================================
281 void AIS_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
282 const Handle(Prs3d_Presentation)& thePresentation,
283 const Standard_Integer theMode)
285 mySelectionGeom.Clear (theMode);
292 gp_Pnt aFirstPnt (gp::Origin());
293 gp_Pnt aSecondPnt (gp::Origin());
294 ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
296 DrawLinearDimension (thePresentation, theMode, aFirstPnt, aSecondPnt);
299 //=======================================================================
300 //function : ComputeFlyoutSelection
302 //=======================================================================
303 void AIS_DiameterDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
304 const Handle(SelectMgr_EntityOwner)& theEntityOwner)
311 gp_Pnt aFirstPnt (gp::Origin());
312 gp_Pnt aSecondPnt (gp::Origin());
313 ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt);
315 ComputeLinearFlyouts (theSelection, theEntityOwner, aFirstPnt, aSecondPnt);
318 //=======================================================================
319 //function : ComputeSidePoints
321 //=======================================================================
322 void AIS_DiameterDimension::ComputeSidePoints (const gp_Circ& theCircle,
324 gp_Pnt& theSecondPnt)
326 theFirstPnt = AnchorPoint();
328 gp_Vec aRadiusVector (theCircle.Location(), theFirstPnt);
329 theSecondPnt = theCircle.Location().Translated (-aRadiusVector);
332 //=======================================================================
333 //function : IsValidCircle
335 //=======================================================================
336 Standard_Boolean AIS_DiameterDimension::IsValidCircle (const gp_Circ& theCircle) const
338 return (theCircle.Radius() * 2.0) > Precision::Confusion();
341 //=======================================================================
342 //function : IsValidAnchor
344 //=======================================================================
345 Standard_Boolean AIS_DiameterDimension::IsValidAnchor (const gp_Circ& theCircle,
346 const gp_Pnt& theAnchor) const
348 gp_Pln aCirclePlane (theCircle.Location(), theCircle.Axis().Direction());
349 Standard_Real anAnchorDist = theAnchor.Distance (theCircle.Location());
350 Standard_Real aRadius = myCircle.Radius();
352 return Abs (anAnchorDist - aRadius) > Precision::Confusion()
353 && aCirclePlane.Contains (theAnchor, Precision::Confusion());
356 //=======================================================================
357 //function : GetTextPosition
359 //=======================================================================
360 const gp_Pnt AIS_DiameterDimension::GetTextPosition() const
362 if (IsTextPositionCustom())
364 return myFixedTextPosition;
367 // Counts text position according to the dimension parameters
368 return GetTextPositionForLinear (myAnchorPoint, myCircle.Location());
371 //=======================================================================
372 //function : GetTextPosition
374 //=======================================================================
375 void AIS_DiameterDimension::SetTextPosition (const gp_Pnt& theTextPos)
382 myIsTextPositionFixed = Standard_True;
383 myFixedTextPosition = theTextPos;