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 |
29 | IMPLEMENT_STANDARD_RTTIEXT(AIS_DiameterDimension,AIS_Dimension) |
30 | |
d7bffd44 |
31 | namespace |
32 | { |
33 | static const Standard_ExtCharacter THE_DIAMETER_SYMBOL (0x00D8); |
a3f6f591 |
34 | } |
d7bffd44 |
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 | { |
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 |
135 | void 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 | //======================================================================= |
164 | Standard_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 | //======================================================================= |
179 | void 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 |
193 | void 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 | //======================================================================= |
231 | const TCollection_AsciiString& AIS_DiameterDimension::GetModelUnits() const |
232 | { |
233 | return myDrawer->DimLengthModelUnits(); |
234 | } |
235 | |
236 | //======================================================================= |
237 | //function : GetDisplayUnits |
238 | //purpose : |
239 | //======================================================================= |
240 | const TCollection_AsciiString& AIS_DiameterDimension::GetDisplayUnits() const |
241 | { |
242 | return myDrawer->DimLengthDisplayUnits(); |
243 | } |
244 | |
245 | //======================================================================= |
246 | //function : SetModelUnits |
247 | //purpose : |
248 | //======================================================================= |
249 | void AIS_DiameterDimension::SetModelUnits (const TCollection_AsciiString& theUnits) |
250 | { |
251 | myDrawer->SetDimLengthModelUnits (theUnits); |
252 | } |
253 | |
254 | //======================================================================= |
255 | //function : SetDisplayUnits |
256 | //purpose : |
257 | //======================================================================= |
258 | void AIS_DiameterDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits) |
259 | { |
260 | myDrawer->SetDimLengthDisplayUnits (theUnits); |
261 | } |
262 | |
263 | //======================================================================= |
264 | //function : ComputeValue |
265 | //purpose : |
266 | //======================================================================= |
267 | Standard_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 |
281 | void 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 | //======================================================================= |
304 | void 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 |
323 | void 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 |
337 | Standard_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 | //======================================================================= |
346 | Standard_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 | //======================================================================= |
361 | const 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 | //======================================================================= |
376 | void 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 | } |