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 |
28 | IMPLEMENT_STANDARD_HANDLE (AIS_DiameterDimension, AIS_Dimension) |
29 | IMPLEMENT_STANDARD_RTTIEXT (AIS_DiameterDimension, AIS_Dimension) |
7fd59977 |
30 | |
d7bffd44 |
31 | namespace |
32 | { |
33 | static const Standard_ExtCharacter THE_DIAMETER_SYMBOL (0x00D8); |
34 | }; |
35 | |
7fd59977 |
36 | //======================================================================= |
37 | //function : Constructor |
38 | //purpose : |
39 | //======================================================================= |
60bf98ae |
40 | AIS_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 | //======================================================================= |
53 | AIS_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 |
68 | AIS_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 | //======================================================================= |
81 | AIS_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 | //======================================================================= |
96 | gp_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 | //======================================================================= |
110 | void 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 |
137 | void 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 | //======================================================================= |
168 | Standard_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 | //======================================================================= |
183 | void 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 |
197 | void 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 | //======================================================================= |
235 | const TCollection_AsciiString& AIS_DiameterDimension::GetModelUnits() const |
236 | { |
237 | return myDrawer->DimLengthModelUnits(); |
238 | } |
239 | |
240 | //======================================================================= |
241 | //function : GetDisplayUnits |
242 | //purpose : |
243 | //======================================================================= |
244 | const TCollection_AsciiString& AIS_DiameterDimension::GetDisplayUnits() const |
245 | { |
246 | return myDrawer->DimLengthDisplayUnits(); |
247 | } |
248 | |
249 | //======================================================================= |
250 | //function : SetModelUnits |
251 | //purpose : |
252 | //======================================================================= |
253 | void AIS_DiameterDimension::SetModelUnits (const TCollection_AsciiString& theUnits) |
254 | { |
255 | myDrawer->SetDimLengthModelUnits (theUnits); |
256 | } |
257 | |
258 | //======================================================================= |
259 | //function : SetDisplayUnits |
260 | //purpose : |
261 | //======================================================================= |
262 | void AIS_DiameterDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits) |
263 | { |
264 | myDrawer->SetDimLengthDisplayUnits (theUnits); |
265 | } |
266 | |
267 | //======================================================================= |
268 | //function : ComputeValue |
269 | //purpose : |
270 | //======================================================================= |
271 | Standard_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 |
285 | void 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()); |
af203d54 |
299 | ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt); |
60bf98ae |
300 | |
301 | DrawLinearDimension (thePresentation, theMode, aFirstPnt, aSecondPnt); |
302 | } |
303 | |
304 | //======================================================================= |
305 | //function : ComputeFlyoutSelection |
306 | //purpose : |
307 | //======================================================================= |
308 | void 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()); |
af203d54 |
318 | ComputeSidePoints (myCircle, aFirstPnt, aSecondPnt); |
60bf98ae |
319 | |
320 | ComputeLinearFlyouts (theSelection, theEntityOwner, aFirstPnt, aSecondPnt); |
7fd59977 |
321 | } |
322 | |
323 | //======================================================================= |
60bf98ae |
324 | //function : ComputeSidePoints |
7fd59977 |
325 | //purpose : |
326 | //======================================================================= |
af203d54 |
327 | void AIS_DiameterDimension::ComputeSidePoints (const gp_Circ& theCircle, |
60bf98ae |
328 | gp_Pnt& theFirstPnt, |
329 | gp_Pnt& theSecondPnt) |
7fd59977 |
330 | { |
60bf98ae |
331 | theFirstPnt = AnchorPoint(); |
332 | |
af203d54 |
333 | gp_Vec aRadiusVector (theCircle.Location(), theFirstPnt); |
334 | theSecondPnt = theCircle.Location().Translated (-aRadiusVector); |
7fd59977 |
335 | } |
336 | |
7fd59977 |
337 | //======================================================================= |
60bf98ae |
338 | //function : IsValidCircle |
7fd59977 |
339 | //purpose : |
340 | //======================================================================= |
60bf98ae |
341 | Standard_Boolean AIS_DiameterDimension::IsValidCircle (const gp_Circ& theCircle) const |
342 | { |
343 | return (theCircle.Radius() * 2.0) > Precision::Confusion(); |
344 | } |
7fd59977 |
345 | |
60bf98ae |
346 | //======================================================================= |
347 | //function : IsValidAnchor |
348 | //purpose : |
349 | //======================================================================= |
350 | Standard_Boolean AIS_DiameterDimension::IsValidAnchor (const gp_Circ& theCircle, |
351 | const gp_Pnt& theAnchor) const |
7fd59977 |
352 | { |
60bf98ae |
353 | gp_Pln aCirclePlane (theCircle.Location(), theCircle.Axis().Direction()); |
354 | Standard_Real anAnchorDist = theAnchor.Distance (theCircle.Location()); |
355 | Standard_Real aRadius = myCircle.Radius(); |
356 | |
357 | return Abs (anAnchorDist - aRadius) > Precision::Confusion() |
358 | && aCirclePlane.Contains (theAnchor, Precision::Confusion()); |
7fd59977 |
359 | } |
af203d54 |
360 | |
361 | //======================================================================= |
362 | //function : GetTextPosition |
363 | //purpose : |
364 | //======================================================================= |
365 | const gp_Pnt AIS_DiameterDimension::GetTextPosition() const |
366 | { |
367 | if (IsTextPositionCustom()) |
368 | { |
369 | return myFixedTextPosition; |
370 | } |
371 | |
372 | // Counts text position according to the dimension parameters |
373 | return GetTextPositionForLinear (myAnchorPoint, myCircle.Location()); |
374 | } |
375 | |
376 | //======================================================================= |
377 | //function : GetTextPosition |
378 | //purpose : |
379 | //======================================================================= |
380 | void AIS_DiameterDimension::SetTextPosition (const gp_Pnt& theTextPos) |
381 | { |
382 | if (!myIsValid) |
383 | { |
384 | return; |
385 | } |
386 | |
387 | myIsTextPositionFixed = Standard_True; |
388 | myFixedTextPosition = theTextPos; |
389 | |
390 | SetToUpdate(); |
391 | } |