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 | |
787ff240 |
17 | #include <PrsDim_DiameterDimension.hxx> |
60bf98ae |
18 | |
787ff240 |
19 | #include <PrsDim.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 | |
787ff240 |
28 | IMPLEMENT_STANDARD_RTTIEXT(PrsDim_DiameterDimension, PrsDim_Dimension) |
92efcf78 |
29 | |
d7bffd44 |
30 | namespace |
31 | { |
32 | static const Standard_ExtCharacter THE_DIAMETER_SYMBOL (0x00D8); |
a3f6f591 |
33 | } |
d7bffd44 |
34 | |
7fd59977 |
35 | //======================================================================= |
36 | //function : Constructor |
37 | //purpose : |
38 | //======================================================================= |
787ff240 |
39 | PrsDim_DiameterDimension::PrsDim_DiameterDimension (const gp_Circ& theCircle) |
40 | : PrsDim_Dimension (PrsDim_KOD_DIAMETER) |
60bf98ae |
41 | { |
42 | SetMeasuredGeometry (theCircle); |
43 | SetSpecialSymbol (THE_DIAMETER_SYMBOL); |
787ff240 |
44 | SetDisplaySpecialSymbol (PrsDim_DisplaySpecialSymbol_Before); |
60bf98ae |
45 | SetFlyout (0.0); |
46 | } |
7fd59977 |
47 | |
60bf98ae |
48 | //======================================================================= |
49 | //function : Constructor |
50 | //purpose : |
51 | //======================================================================= |
787ff240 |
52 | PrsDim_DiameterDimension::PrsDim_DiameterDimension (const gp_Circ& theCircle, |
53 | const gp_Pln& thePlane) |
54 | : PrsDim_Dimension (PrsDim_KOD_DIAMETER) |
7fd59977 |
55 | { |
60bf98ae |
56 | SetCustomPlane (thePlane); |
57 | SetMeasuredGeometry (theCircle); |
d7bffd44 |
58 | SetSpecialSymbol (THE_DIAMETER_SYMBOL); |
787ff240 |
59 | SetDisplaySpecialSymbol (PrsDim_DisplaySpecialSymbol_Before); |
d7bffd44 |
60 | SetFlyout (0.0); |
7fd59977 |
61 | } |
62 | |
63 | //======================================================================= |
64 | //function : Constructor |
65 | //purpose : |
66 | //======================================================================= |
787ff240 |
67 | PrsDim_DiameterDimension::PrsDim_DiameterDimension (const TopoDS_Shape& theShape) |
68 | : PrsDim_Dimension (PrsDim_KOD_DIAMETER) |
60bf98ae |
69 | { |
70 | SetMeasuredGeometry (theShape); |
71 | SetSpecialSymbol (THE_DIAMETER_SYMBOL); |
787ff240 |
72 | SetDisplaySpecialSymbol (PrsDim_DisplaySpecialSymbol_Before); |
60bf98ae |
73 | SetFlyout (0.0); |
74 | } |
7fd59977 |
75 | |
60bf98ae |
76 | //======================================================================= |
77 | //function : Constructor |
78 | //purpose : |
79 | //======================================================================= |
787ff240 |
80 | PrsDim_DiameterDimension::PrsDim_DiameterDimension (const TopoDS_Shape& theShape, |
81 | const gp_Pln& thePlane) |
82 | : PrsDim_Dimension (PrsDim_KOD_DIAMETER) |
7fd59977 |
83 | { |
60bf98ae |
84 | SetCustomPlane (thePlane); |
85 | SetMeasuredGeometry (theShape); |
d7bffd44 |
86 | SetSpecialSymbol (THE_DIAMETER_SYMBOL); |
787ff240 |
87 | SetDisplaySpecialSymbol (PrsDim_DisplaySpecialSymbol_Before); |
d7bffd44 |
88 | SetFlyout (0.0); |
60bf98ae |
89 | } |
90 | |
91 | //======================================================================= |
92 | //function : AnchorPoint |
93 | //purpose : |
94 | //======================================================================= |
787ff240 |
95 | gp_Pnt PrsDim_DiameterDimension::AnchorPoint() |
60bf98ae |
96 | { |
97 | if (!IsValid()) |
a6eb515f |
98 | { |
60bf98ae |
99 | return gp::Origin(); |
a6eb515f |
100 | } |
60bf98ae |
101 | |
102 | return myAnchorPoint; |
103 | } |
104 | |
105 | //======================================================================= |
106 | //function : SetMeasuredGeometry |
107 | //purpose : |
108 | //======================================================================= |
787ff240 |
109 | void PrsDim_DiameterDimension::SetMeasuredGeometry (const gp_Circ& theCircle) |
60bf98ae |
110 | { |
91b16a64 |
111 | myCircle = theCircle; |
112 | myGeometryType = GeometryType_Edge; |
113 | myShape = BRepLib_MakeEdge (theCircle); |
114 | myAnchorPoint = gp::Origin(); |
115 | myIsGeometryValid = IsValidCircle (myCircle); |
60bf98ae |
116 | |
91b16a64 |
117 | if (myIsGeometryValid && myIsPlaneCustom) |
60bf98ae |
118 | { |
119 | ComputeAnchorPoint(); |
120 | } |
121 | else if (!myIsPlaneCustom) |
a6eb515f |
122 | { |
60bf98ae |
123 | ComputePlane(); |
124 | myAnchorPoint = ElCLib::Value (0.0, myCircle); |
a6eb515f |
125 | } |
60bf98ae |
126 | |
60bf98ae |
127 | SetToUpdate(); |
7fd59977 |
128 | } |
129 | |
7fd59977 |
130 | //======================================================================= |
60bf98ae |
131 | //function : SetMeasuredGeometry |
132 | //purpose : |
7fd59977 |
133 | //======================================================================= |
787ff240 |
134 | void PrsDim_DiameterDimension::SetMeasuredGeometry (const TopoDS_Shape& theShape) |
60bf98ae |
135 | { |
136 | gp_Pnt aDummyPnt (gp::Origin()); |
137 | Standard_Boolean isClosed = Standard_False; |
7fd59977 |
138 | |
91b16a64 |
139 | myGeometryType = GeometryType_UndefShapes; |
140 | myShape = theShape; |
141 | myAnchorPoint = gp::Origin(); |
142 | myIsGeometryValid = InitCircularDimension (theShape, myCircle, aDummyPnt, isClosed) |
143 | && IsValidCircle (myCircle) |
144 | && isClosed; |
60bf98ae |
145 | |
91b16a64 |
146 | if (myIsGeometryValid && myIsPlaneCustom) |
60bf98ae |
147 | { |
148 | ComputeAnchorPoint(); |
149 | } |
150 | else if (!myIsPlaneCustom) |
151 | { |
152 | ComputePlane(); |
153 | myAnchorPoint = ElCLib::Value (0.0, myCircle); |
154 | } |
155 | |
60bf98ae |
156 | SetToUpdate(); |
157 | } |
158 | |
159 | //======================================================================= |
160 | //function : CheckPlane |
161 | //purpose : |
162 | //======================================================================= |
787ff240 |
163 | Standard_Boolean PrsDim_DiameterDimension::CheckPlane (const gp_Pln& thePlane) const |
7fd59977 |
164 | { |
60bf98ae |
165 | // Check if the circle center point belongs to plane. |
166 | if (!thePlane.Contains (myCircle.Location(), Precision::Confusion())) |
167 | { |
168 | return Standard_False; |
169 | } |
170 | |
171 | return Standard_True; |
7fd59977 |
172 | } |
173 | |
174 | //======================================================================= |
60bf98ae |
175 | //function : ComputePlane |
176 | //purpose : |
177 | //======================================================================= |
787ff240 |
178 | void PrsDim_DiameterDimension::ComputePlane() |
60bf98ae |
179 | { |
91b16a64 |
180 | if (!myIsGeometryValid) |
60bf98ae |
181 | { |
182 | return; |
183 | } |
184 | |
185 | myPlane = gp_Pln (gp_Ax3 (myCircle.Position())); |
186 | } |
187 | |
188 | //======================================================================= |
189 | //function : ComputeAnchorPoint |
7fd59977 |
190 | //purpose : |
191 | //======================================================================= |
787ff240 |
192 | void PrsDim_DiameterDimension::ComputeAnchorPoint() |
60bf98ae |
193 | { |
194 | // Anchor point is an intersection of dimension plane and circle. |
195 | Handle(Geom_Circle) aCircle = new Geom_Circle (myCircle); |
196 | Handle(Geom_Plane) aPlane = new Geom_Plane (myPlane); |
197 | GeomAPI_IntCS anIntersector (aCircle, aPlane); |
198 | if (!anIntersector.IsDone()) |
199 | { |
91b16a64 |
200 | myIsGeometryValid = Standard_False; |
60bf98ae |
201 | return; |
202 | } |
7fd59977 |
203 | |
60bf98ae |
204 | // The circle lays on the plane. |
205 | if (anIntersector.NbPoints() != 2) |
206 | { |
207 | myAnchorPoint = ElCLib::Value (0.0, myCircle); |
91b16a64 |
208 | myIsGeometryValid = Standard_True; |
60bf98ae |
209 | return; |
210 | } |
211 | |
212 | gp_Pnt aFirstPoint = anIntersector.Point (1); |
213 | gp_Pnt aSecondPoint = anIntersector.Point (2); |
214 | |
215 | // Choose one of two intersection points that stands with |
216 | // positive direction of flyout. |
217 | // An anchor point is supposed to be the left attachment point. |
218 | gp_Dir aFirstDir = gce_MakeDir (aFirstPoint, myCircle.Location()); |
219 | gp_Dir aDir = myPlane.Axis().Direction() ^ aFirstDir; |
220 | myAnchorPoint = (gp_Vec (aDir) * gp_Vec(myCircle.Position().Direction()) > 0.0) |
221 | ? aFirstPoint |
222 | : aSecondPoint; |
223 | |
224 | } |
225 | |
226 | //======================================================================= |
227 | //function : GetModelUnits |
228 | //purpose : |
229 | //======================================================================= |
787ff240 |
230 | const TCollection_AsciiString& PrsDim_DiameterDimension::GetModelUnits() const |
60bf98ae |
231 | { |
232 | return myDrawer->DimLengthModelUnits(); |
233 | } |
234 | |
235 | //======================================================================= |
236 | //function : GetDisplayUnits |
237 | //purpose : |
238 | //======================================================================= |
787ff240 |
239 | const TCollection_AsciiString& PrsDim_DiameterDimension::GetDisplayUnits() const |
60bf98ae |
240 | { |
241 | return myDrawer->DimLengthDisplayUnits(); |
242 | } |
243 | |
244 | //======================================================================= |
245 | //function : SetModelUnits |
246 | //purpose : |
247 | //======================================================================= |
787ff240 |
248 | void PrsDim_DiameterDimension::SetModelUnits (const TCollection_AsciiString& theUnits) |
60bf98ae |
249 | { |
250 | myDrawer->SetDimLengthModelUnits (theUnits); |
251 | } |
252 | |
253 | //======================================================================= |
254 | //function : SetDisplayUnits |
255 | //purpose : |
256 | //======================================================================= |
787ff240 |
257 | void PrsDim_DiameterDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits) |
60bf98ae |
258 | { |
259 | myDrawer->SetDimLengthDisplayUnits (theUnits); |
260 | } |
261 | |
262 | //======================================================================= |
263 | //function : ComputeValue |
264 | //purpose : |
265 | //======================================================================= |
787ff240 |
266 | Standard_Real PrsDim_DiameterDimension::ComputeValue() const |
60bf98ae |
267 | { |
268 | if (!IsValid()) |
269 | { |
270 | return 0.0; |
271 | } |
272 | |
273 | return myCircle.Radius() * 2.0; |
274 | } |
275 | |
276 | //======================================================================= |
277 | //function : Compute |
278 | //purpose : |
279 | //======================================================================= |
decbff0d |
280 | void PrsDim_DiameterDimension::Compute (const Handle(PrsMgr_PresentationManager)& , |
281 | const Handle(Prs3d_Presentation)& thePresentation, |
787ff240 |
282 | const Standard_Integer theMode) |
7fd59977 |
283 | { |
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 | //======================================================================= |
787ff240 |
302 | void PrsDim_DiameterDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection, |
303 | const Handle(SelectMgr_EntityOwner)& theEntityOwner) |
60bf98ae |
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 | //======================================================================= |
787ff240 |
321 | void PrsDim_DiameterDimension::ComputeSidePoints (const gp_Circ& theCircle, |
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 | //======================================================================= |
787ff240 |
335 | Standard_Boolean PrsDim_DiameterDimension::IsValidCircle (const gp_Circ& theCircle) const |
60bf98ae |
336 | { |
337 | return (theCircle.Radius() * 2.0) > Precision::Confusion(); |
338 | } |
7fd59977 |
339 | |
60bf98ae |
340 | //======================================================================= |
341 | //function : IsValidAnchor |
342 | //purpose : |
343 | //======================================================================= |
787ff240 |
344 | Standard_Boolean PrsDim_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 | //======================================================================= |
787ff240 |
359 | gp_Pnt PrsDim_DiameterDimension::GetTextPosition() const |
af203d54 |
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 | //======================================================================= |
787ff240 |
374 | void PrsDim_DiameterDimension::SetTextPosition (const gp_Pnt& theTextPos) |
af203d54 |
375 | { |
91b16a64 |
376 | if (!IsValid()) |
af203d54 |
377 | { |
378 | return; |
379 | } |
380 | |
381 | myIsTextPositionFixed = Standard_True; |
382 | myFixedTextPosition = theTextPos; |
383 | |
384 | SetToUpdate(); |
385 | } |