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