b311480e |
1 | // Created on: 1996-12-05 |
2 | // Created by: Arnaud BOUZY/Odile Olivier |
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_AngleDimension.hxx> |
7fd59977 |
18 | |
19 | #include <AIS.hxx> |
7fd59977 |
20 | #include <AIS_Drawer.hxx> |
7fd59977 |
21 | #include <BRepBuilderAPI_MakeFace.hxx> |
22 | #include <BRepAdaptor_Curve.hxx> |
23 | #include <BRepAdaptor_Surface.hxx> |
60bf98ae |
24 | #include <BRepLib_MakeVertex.hxx> |
25 | #include <BRep_Tool.hxx> |
7fd59977 |
26 | #include <ElCLib.hxx> |
60bf98ae |
27 | #include <GCPnts_UniformAbscissa.hxx> |
28 | #include <GC_MakeArcOfCircle.hxx> |
a6eb515f |
29 | #include <gce_MakeLin2d.hxx> |
60bf98ae |
30 | #include <gce_MakeLin.hxx> |
31 | #include <gce_MakeCirc.hxx> |
a6eb515f |
32 | #include <gce_MakeCone.hxx> |
fe83e1ea |
33 | #include <gce_MakePln.hxx> |
fe83e1ea |
34 | #include <gce_MakeDir.hxx> |
7fd59977 |
35 | #include <Geom_Circle.hxx> |
60bf98ae |
36 | #include <Geom_TrimmedCurve.hxx> |
7fd59977 |
37 | #include <Geom_ConicalSurface.hxx> |
38 | #include <Geom_SurfaceOfRevolution.hxx> |
7fd59977 |
39 | #include <Geom_OffsetSurface.hxx> |
a6eb515f |
40 | #include <Graphic3d_ArrayOfSegments.hxx> |
a6eb515f |
41 | #include <Graphic3d_Group.hxx> |
a6eb515f |
42 | #include <Graphic3d_ArrayOfPolylines.hxx> |
7fd59977 |
43 | #include <IntAna2d_AnaIntersection.hxx> |
7fd59977 |
44 | #include <ProjLib.hxx> |
a6eb515f |
45 | #include <Prs3d_Root.hxx> |
d7bffd44 |
46 | #include <Prs3d_ShadingAspect.hxx> |
a6eb515f |
47 | #include <PrsMgr_PresentationManager3d.hxx> |
62b6361a |
48 | #include <Select3D_SensitiveGroup.hxx> |
7fd59977 |
49 | #include <Select3D_SensitiveSegment.hxx> |
a6eb515f |
50 | #include <SelectMgr_Selection.hxx> |
af203d54 |
51 | #include <Standard_ProgramError.hxx> |
7fd59977 |
52 | #include <UnitsAPI.hxx> |
53 | |
a6eb515f |
54 | IMPLEMENT_STANDARD_HANDLE (AIS_AngleDimension, AIS_Dimension) |
55 | IMPLEMENT_STANDARD_RTTIEXT (AIS_AngleDimension, AIS_Dimension) |
7fd59977 |
56 | |
d7bffd44 |
57 | namespace |
58 | { |
fe83e1ea |
59 | static const TCollection_ExtendedString THE_EMPTY_LABEL_STRING; |
60 | static const Standard_Real THE_EMPTY_LABEL_WIDTH = 0.0; |
61 | static const Standard_ExtCharacter THE_DEGREE_SYMBOL (0x00B0); |
62 | static const Standard_Real THE_3D_TEXT_MARGIN = 0.1; |
d7bffd44 |
63 | }; |
64 | |
7fd59977 |
65 | //======================================================================= |
66 | //function : Constructor |
60bf98ae |
67 | //purpose : |
7fd59977 |
68 | //======================================================================= |
a6eb515f |
69 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge, |
70 | const TopoDS_Edge& theSecondEdge) |
60bf98ae |
71 | : AIS_Dimension (AIS_KOD_PLANEANGLE) |
7fd59977 |
72 | { |
60bf98ae |
73 | Init(); |
74 | SetMeasuredGeometry (theFirstEdge, theSecondEdge); |
7fd59977 |
75 | } |
76 | |
7fd59977 |
77 | //======================================================================= |
78 | //function : Constructor |
60bf98ae |
79 | //purpose : |
7fd59977 |
80 | //======================================================================= |
60bf98ae |
81 | AIS_AngleDimension::AIS_AngleDimension (const gp_Pnt& theFirstPoint, |
82 | const gp_Pnt& theSecondPoint, |
83 | const gp_Pnt& theThirdPoint) |
84 | : AIS_Dimension (AIS_KOD_PLANEANGLE) |
7fd59977 |
85 | { |
60bf98ae |
86 | Init(); |
87 | SetMeasuredGeometry (theFirstPoint, theSecondPoint, theThirdPoint); |
7fd59977 |
88 | } |
89 | |
90 | //======================================================================= |
91 | //function : Constructor |
60bf98ae |
92 | //purpose : |
7fd59977 |
93 | //======================================================================= |
60bf98ae |
94 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Vertex& theFirstVertex, |
95 | const TopoDS_Vertex& theSecondVertex, |
96 | const TopoDS_Vertex& theThirdVertex) |
97 | : AIS_Dimension (AIS_KOD_PLANEANGLE) |
7fd59977 |
98 | { |
60bf98ae |
99 | Init(); |
100 | SetMeasuredGeometry (theFirstVertex, theSecondVertex, theThirdVertex); |
7fd59977 |
101 | } |
102 | |
7fd59977 |
103 | //======================================================================= |
a6eb515f |
104 | //function : Constructor |
60bf98ae |
105 | //purpose : |
7fd59977 |
106 | //======================================================================= |
a6eb515f |
107 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theCone) |
60bf98ae |
108 | : AIS_Dimension (AIS_KOD_PLANEANGLE) |
7fd59977 |
109 | { |
60bf98ae |
110 | Init(); |
111 | SetMeasuredGeometry (theCone); |
7fd59977 |
112 | } |
113 | |
114 | //======================================================================= |
a6eb515f |
115 | //function : Constructor |
60bf98ae |
116 | //purpose : |
7fd59977 |
117 | //======================================================================= |
a6eb515f |
118 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theFirstFace, |
60bf98ae |
119 | const TopoDS_Face& theSecondFace) |
120 | : AIS_Dimension (AIS_KOD_PLANEANGLE) |
7fd59977 |
121 | { |
60bf98ae |
122 | Init(); |
123 | SetMeasuredGeometry (theFirstFace, theSecondFace); |
7fd59977 |
124 | } |
125 | |
7fd59977 |
126 | //======================================================================= |
60bf98ae |
127 | //function : Constructor |
7fd59977 |
128 | //purpose : |
129 | //======================================================================= |
60bf98ae |
130 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theFirstFace, |
131 | const TopoDS_Face& theSecondFace, |
132 | const gp_Pnt& thePoint) |
133 | : AIS_Dimension (AIS_KOD_PLANEANGLE) |
7fd59977 |
134 | { |
60bf98ae |
135 | Init(); |
136 | SetMeasuredGeometry (theFirstFace, theSecondFace, thePoint); |
7fd59977 |
137 | } |
138 | |
7fd59977 |
139 | //======================================================================= |
60bf98ae |
140 | //function : SetMeasuredGeometry |
141 | //purpose : |
7fd59977 |
142 | //======================================================================= |
60bf98ae |
143 | void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Edge& theFirstEdge, |
144 | const TopoDS_Edge& theSecondEdge) |
7fd59977 |
145 | { |
60bf98ae |
146 | gp_Pln aComputedPlane; |
147 | |
148 | myFirstShape = theFirstEdge; |
149 | mySecondShape = theSecondEdge; |
150 | myThirdShape = TopoDS_Shape(); |
151 | myGeometryType = GeometryType_Edges; |
152 | myIsValid = InitTwoEdgesAngle (aComputedPlane); |
153 | |
154 | if (myIsValid && !myIsPlaneCustom) |
155 | { |
af203d54 |
156 | ComputePlane(); |
60bf98ae |
157 | } |
158 | |
159 | myIsValid &= CheckPlane (myPlane); |
160 | |
161 | SetToUpdate(); |
7fd59977 |
162 | } |
163 | |
164 | //======================================================================= |
60bf98ae |
165 | //function : SetMeasuredGeometry |
166 | //purpose : |
7fd59977 |
167 | //======================================================================= |
60bf98ae |
168 | void AIS_AngleDimension::SetMeasuredGeometry (const gp_Pnt& theFirstPoint, |
169 | const gp_Pnt& theSecondPoint, |
170 | const gp_Pnt& theThirdPoint) |
7fd59977 |
171 | { |
60bf98ae |
172 | myFirstPoint = theFirstPoint; |
173 | myCenterPoint = theSecondPoint; |
174 | mySecondPoint = theThirdPoint; |
175 | myFirstShape = BRepLib_MakeVertex (myFirstPoint); |
176 | mySecondShape = BRepLib_MakeVertex (myCenterPoint); |
177 | myThirdShape = BRepLib_MakeVertex (mySecondPoint); |
178 | myGeometryType = GeometryType_Points; |
179 | myIsValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint); |
7fd59977 |
180 | |
60bf98ae |
181 | if (myIsValid && !myIsPlaneCustom) |
a6eb515f |
182 | { |
60bf98ae |
183 | ComputePlane(); |
184 | } |
a6eb515f |
185 | |
60bf98ae |
186 | myIsValid &= CheckPlane (myPlane); |
a6eb515f |
187 | |
60bf98ae |
188 | SetToUpdate(); |
189 | } |
a6eb515f |
190 | |
60bf98ae |
191 | //======================================================================= |
192 | //function : SetMeasuredGeometry |
193 | //purpose : |
194 | //======================================================================= |
195 | void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Vertex& theFirstVertex, |
196 | const TopoDS_Vertex& theSecondVertex, |
197 | const TopoDS_Vertex& theThirdVertex) |
198 | { |
199 | myFirstShape = theFirstVertex; |
200 | mySecondShape = theSecondVertex; |
201 | myThirdShape = theThirdVertex; |
202 | myFirstPoint = BRep_Tool::Pnt (theFirstVertex); |
203 | myCenterPoint = BRep_Tool::Pnt (theSecondVertex); |
204 | mySecondPoint = BRep_Tool::Pnt (theThirdVertex); |
205 | myGeometryType = GeometryType_Points; |
206 | myIsValid = IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint); |
207 | |
208 | if (myIsValid && !myIsPlaneCustom) |
a6eb515f |
209 | { |
60bf98ae |
210 | ComputePlane(); |
7fd59977 |
211 | } |
7fd59977 |
212 | |
60bf98ae |
213 | myIsValid &= CheckPlane (myPlane); |
7fd59977 |
214 | |
60bf98ae |
215 | SetToUpdate(); |
216 | } |
7fd59977 |
217 | |
60bf98ae |
218 | //======================================================================= |
219 | //function : SetMeasuredGeometry |
220 | //purpose : |
221 | //======================================================================= |
222 | void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theCone) |
223 | { |
224 | myFirstShape = theCone; |
225 | mySecondShape = TopoDS_Shape(); |
226 | myThirdShape = TopoDS_Shape(); |
227 | myGeometryType = GeometryType_Face; |
228 | myIsValid = InitConeAngle(); |
7fd59977 |
229 | |
60bf98ae |
230 | if (myIsValid && !myIsPlaneCustom) |
a6eb515f |
231 | { |
60bf98ae |
232 | ComputePlane(); |
a6eb515f |
233 | } |
7fd59977 |
234 | |
60bf98ae |
235 | myIsValid &= CheckPlane (myPlane); |
236 | |
237 | SetToUpdate(); |
7fd59977 |
238 | } |
239 | |
240 | //======================================================================= |
60bf98ae |
241 | //function : SetMeasuredGeometry |
242 | //purpose : |
7fd59977 |
243 | //======================================================================= |
60bf98ae |
244 | void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace, |
245 | const TopoDS_Face& theSecondFace) |
7fd59977 |
246 | { |
60bf98ae |
247 | myFirstShape = theFirstFace; |
248 | mySecondShape = theSecondFace; |
249 | myThirdShape = TopoDS_Shape(); |
250 | myGeometryType = GeometryType_Faces; |
251 | myIsValid = InitTwoFacesAngle(); |
a6eb515f |
252 | |
60bf98ae |
253 | if (myIsValid && !myIsPlaneCustom) |
a6eb515f |
254 | { |
60bf98ae |
255 | ComputePlane(); |
7fd59977 |
256 | } |
60bf98ae |
257 | |
258 | myIsValid &= CheckPlane (myPlane); |
259 | |
260 | SetToUpdate(); |
7fd59977 |
261 | } |
262 | |
7fd59977 |
263 | //======================================================================= |
60bf98ae |
264 | //function : SetMeasuredGeometry |
7fd59977 |
265 | //purpose : |
266 | //======================================================================= |
60bf98ae |
267 | void AIS_AngleDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace, |
268 | const TopoDS_Face& theSecondFace, |
269 | const gp_Pnt& thePoint) |
7fd59977 |
270 | { |
60bf98ae |
271 | myFirstShape = theFirstFace; |
272 | mySecondShape = theSecondFace; |
273 | myThirdShape = TopoDS_Shape(); |
274 | myGeometryType = GeometryType_Faces; |
275 | myIsValid = InitTwoFacesAngle (thePoint); |
276 | |
277 | if (myIsValid && !myIsPlaneCustom) |
278 | { |
279 | ComputePlane(); |
280 | } |
281 | |
282 | myIsValid &= CheckPlane (myPlane); |
283 | |
284 | SetToUpdate(); |
7fd59977 |
285 | } |
286 | |
287 | //======================================================================= |
60bf98ae |
288 | //function : Init |
7fd59977 |
289 | //purpose : |
290 | //======================================================================= |
60bf98ae |
291 | void AIS_AngleDimension::Init() |
7fd59977 |
292 | { |
60bf98ae |
293 | SetSpecialSymbol (THE_DEGREE_SYMBOL); |
294 | SetDisplaySpecialSymbol (AIS_DSS_After); |
295 | SetFlyout (15.0); |
7fd59977 |
296 | } |
297 | |
7fd59977 |
298 | //======================================================================= |
60bf98ae |
299 | //function: GetCenterOnArc |
300 | //purpose : |
7fd59977 |
301 | //======================================================================= |
60bf98ae |
302 | gp_Pnt AIS_AngleDimension::GetCenterOnArc (const gp_Pnt& theFirstAttach, |
303 | const gp_Pnt& theSecondAttach, |
af203d54 |
304 | const gp_Pnt& theCenter) const |
7fd59977 |
305 | { |
60bf98ae |
306 | // construct plane where the circle and the arc are located |
307 | gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter); |
308 | if (!aConstructPlane.IsDone()) |
a6eb515f |
309 | { |
60bf98ae |
310 | return gp::Origin(); |
7fd59977 |
311 | } |
60bf98ae |
312 | |
313 | gp_Pln aPlane = aConstructPlane.Value(); |
7fd59977 |
314 | |
60bf98ae |
315 | Standard_Real aRadius = theFirstAttach.Distance (theCenter); |
7fd59977 |
316 | |
60bf98ae |
317 | // construct circle forming the arc |
318 | gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius); |
319 | if (!aConstructCircle.IsDone()) |
a6eb515f |
320 | { |
60bf98ae |
321 | return gp::Origin(); |
7fd59977 |
322 | } |
323 | |
60bf98ae |
324 | gp_Circ aCircle = aConstructCircle.Value(); |
325 | |
326 | // compute angle parameters of arc end-points on circle |
327 | Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach); |
328 | Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach); |
329 | ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd); |
7fd59977 |
330 | |
60bf98ae |
331 | return ElCLib::Value ((aParamBeg + aParamEnd) * 0.5, aCircle); |
332 | } |
333 | |
334 | //======================================================================= |
335 | //function : DrawArc |
336 | //purpose : draws the arc between two attach points |
337 | //======================================================================= |
338 | void AIS_AngleDimension::DrawArc (const Handle(Prs3d_Presentation)& thePresentation, |
339 | const gp_Pnt& theFirstAttach, |
340 | const gp_Pnt& theSecondAttach, |
341 | const gp_Pnt& theCenter, |
342 | const Standard_Real theRadius, |
343 | const Standard_Integer theMode) |
344 | { |
345 | // construct plane where the circle and the arc are located |
346 | gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter); |
347 | if (!aConstructPlane.IsDone()) |
a6eb515f |
348 | { |
60bf98ae |
349 | return; |
7fd59977 |
350 | } |
60bf98ae |
351 | |
352 | gp_Pln aPlane = aConstructPlane.Value(); |
353 | |
354 | // construct circle forming the arc |
355 | gce_MakeCirc aConstructCircle (theCenter, aPlane, theRadius); |
356 | if (!aConstructCircle.IsDone()) |
a6eb515f |
357 | { |
60bf98ae |
358 | return; |
7fd59977 |
359 | } |
360 | |
60bf98ae |
361 | gp_Circ aCircle = aConstructCircle.Value(); |
362 | |
363 | // construct the arc |
364 | GC_MakeArcOfCircle aConstructArc (aCircle, theFirstAttach, theSecondAttach, Standard_True); |
365 | if (!aConstructArc.IsDone()) |
a6eb515f |
366 | { |
60bf98ae |
367 | return; |
7fd59977 |
368 | } |
369 | |
60bf98ae |
370 | // generate points with specified deflection |
371 | const Handle(Geom_TrimmedCurve)& anArcCurve = aConstructArc.Value(); |
372 | |
373 | GeomAdaptor_Curve anArcAdaptor (anArcCurve, anArcCurve->FirstParameter(), anArcCurve->LastParameter()); |
7fd59977 |
374 | |
60bf98ae |
375 | // compute number of discretization elements in old-fanshioned way |
376 | gp_Vec aCenterToFirstVec (theCenter, theFirstAttach); |
377 | gp_Vec aCenterToSecondVec (theCenter, theSecondAttach); |
378 | const Standard_Real anAngle = aCenterToFirstVec.Angle (aCenterToSecondVec); |
379 | const Standard_Integer aNbPoints = Max (4, Standard_Integer (50.0 * anAngle / M_PI)); |
a6eb515f |
380 | |
60bf98ae |
381 | GCPnts_UniformAbscissa aMakePnts (anArcAdaptor, aNbPoints); |
382 | if (!aMakePnts.IsDone()) |
383 | { |
384 | return; |
7fd59977 |
385 | } |
386 | |
60bf98ae |
387 | // init data arrays for graphical and selection primitives |
388 | Handle(Graphic3d_ArrayOfPolylines) aPrimSegments = new Graphic3d_ArrayOfPolylines (aNbPoints); |
7fd59977 |
389 | |
60bf98ae |
390 | SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve(); |
a6eb515f |
391 | |
60bf98ae |
392 | // load data into arrays |
393 | for (Standard_Integer aPntIt = 1; aPntIt <= aMakePnts.NbPoints(); ++aPntIt) |
a6eb515f |
394 | { |
60bf98ae |
395 | gp_Pnt aPnt = anArcAdaptor.Value (aMakePnts.Parameter (aPntIt)); |
7fd59977 |
396 | |
60bf98ae |
397 | aPrimSegments->AddVertex (aPnt); |
7fd59977 |
398 | |
60bf98ae |
399 | aSensitiveCurve.Append (aPnt); |
a6eb515f |
400 | } |
7fd59977 |
401 | |
60bf98ae |
402 | // add display presentation |
403 | if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All) |
404 | { |
405 | Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True); |
406 | } |
407 | Handle(Graphic3d_AspectLine3d) aDimensionLineStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect(); |
408 | Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionLineStyle); |
409 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments); |
410 | if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All) |
411 | { |
412 | Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False); |
413 | } |
7fd59977 |
414 | } |
a6eb515f |
415 | |
7fd59977 |
416 | //======================================================================= |
60bf98ae |
417 | //function: DrawArcWithText |
a6eb515f |
418 | //purpose : |
7fd59977 |
419 | //======================================================================= |
60bf98ae |
420 | void AIS_AngleDimension::DrawArcWithText (const Handle(Prs3d_Presentation)& thePresentation, |
a6eb515f |
421 | const gp_Pnt& theFirstAttach, |
422 | const gp_Pnt& theSecondAttach, |
60bf98ae |
423 | const gp_Pnt& theCenter, |
a6eb515f |
424 | const TCollection_ExtendedString& theText, |
fe83e1ea |
425 | const Standard_Real theTextWidth, |
426 | const Standard_Integer theMode, |
d7bffd44 |
427 | const Standard_Integer theLabelPosition) |
7fd59977 |
428 | { |
fe83e1ea |
429 | // construct plane where the circle and the arc are located |
60bf98ae |
430 | gce_MakePln aConstructPlane (theFirstAttach, theSecondAttach, theCenter); |
fe83e1ea |
431 | if (!aConstructPlane.IsDone()) |
432 | { |
433 | return; |
434 | } |
60bf98ae |
435 | |
fe83e1ea |
436 | gp_Pln aPlane = aConstructPlane.Value(); |
a6eb515f |
437 | |
60bf98ae |
438 | Standard_Real aRadius = theFirstAttach.Distance (myCenterPoint); |
a6eb515f |
439 | |
fe83e1ea |
440 | // construct circle forming the arc |
60bf98ae |
441 | gce_MakeCirc aConstructCircle (theCenter, aPlane, aRadius); |
fe83e1ea |
442 | if (!aConstructCircle.IsDone()) |
443 | { |
444 | return; |
445 | } |
a6eb515f |
446 | |
fe83e1ea |
447 | gp_Circ aCircle = aConstructCircle.Value(); |
a6eb515f |
448 | |
fe83e1ea |
449 | // compute angle parameters of arc end-points on circle |
450 | Standard_Real aParamBeg = ElCLib::Parameter (aCircle, theFirstAttach); |
451 | Standard_Real aParamEnd = ElCLib::Parameter (aCircle, theSecondAttach); |
60bf98ae |
452 | ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd); |
a6eb515f |
453 | |
fe83e1ea |
454 | // middle point of arc parameter on circle |
455 | Standard_Real aParamMid = (aParamBeg + aParamEnd) * 0.5; |
a6eb515f |
456 | |
fe83e1ea |
457 | // add text graphical primitives |
458 | if (theMode == ComputeMode_All || theMode == ComputeMode_Text) |
459 | { |
460 | gp_Pnt aTextPos = ElCLib::Value (aParamMid, aCircle); |
60bf98ae |
461 | gp_Dir aTextDir = gce_MakeDir (theFirstAttach, theSecondAttach); |
fe83e1ea |
462 | |
463 | // Drawing text |
60bf98ae |
464 | DrawText (thePresentation, |
fe83e1ea |
465 | aTextPos, |
466 | aTextDir, |
467 | theText, |
468 | theLabelPosition); |
469 | } |
a6eb515f |
470 | |
fe83e1ea |
471 | if (theMode != ComputeMode_All && theMode != ComputeMode_Line) |
472 | { |
473 | return; |
474 | } |
a6eb515f |
475 | |
fe83e1ea |
476 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
a6eb515f |
477 | |
fe83e1ea |
478 | Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center |
479 | && aDimensionAspect->IsText3d(); |
a6eb515f |
480 | |
fe83e1ea |
481 | if (isLineBreak) |
a6eb515f |
482 | { |
fe83e1ea |
483 | // compute gap for label as parameteric size of sector on circle segment |
484 | Standard_Real aSectorOnCircle = theTextWidth / aRadius; |
485 | |
486 | gp_Pnt aTextPntBeg = ElCLib::Value (aParamMid - aSectorOnCircle * 0.5, aCircle); |
487 | gp_Pnt aTextPntEnd = ElCLib::Value (aParamMid + aSectorOnCircle * 0.5, aCircle); |
488 | |
489 | // Drawing arcs |
60bf98ae |
490 | DrawArc (thePresentation, theFirstAttach, aTextPntBeg, theCenter, aRadius, theMode); |
491 | DrawArc (thePresentation, theSecondAttach, aTextPntEnd, theCenter, aRadius, theMode); |
fe83e1ea |
492 | } |
493 | else |
494 | { |
60bf98ae |
495 | DrawArc (thePresentation, theFirstAttach, theSecondAttach, theCenter, aRadius, theMode); |
7fd59977 |
496 | } |
a6eb515f |
497 | } |
7fd59977 |
498 | |
a6eb515f |
499 | //======================================================================= |
60bf98ae |
500 | //function : CheckPlane |
501 | //purpose : |
a6eb515f |
502 | //======================================================================= |
60bf98ae |
503 | Standard_Boolean AIS_AngleDimension::CheckPlane (const gp_Pln& thePlane)const |
a6eb515f |
504 | { |
60bf98ae |
505 | if (!thePlane.Contains (myFirstPoint, Precision::Confusion()) && |
506 | !thePlane.Contains (mySecondPoint, Precision::Confusion()) && |
507 | !thePlane.Contains (myCenterPoint, Precision::Confusion())) |
fe83e1ea |
508 | { |
60bf98ae |
509 | return Standard_False; |
fe83e1ea |
510 | } |
511 | |
60bf98ae |
512 | return Standard_True; |
513 | } |
a6eb515f |
514 | |
60bf98ae |
515 | //======================================================================= |
516 | //function : ComputePlane |
517 | //purpose : |
518 | //======================================================================= |
519 | void AIS_AngleDimension::ComputePlane() |
520 | { |
521 | if (!IsValid()) |
a6eb515f |
522 | { |
fe83e1ea |
523 | return; |
7fd59977 |
524 | } |
7fd59977 |
525 | |
60bf98ae |
526 | gp_Vec aFirstVec = gp_Vec (myCenterPoint, myFirstPoint).Normalized(); |
527 | gp_Vec aSecondVec = gp_Vec (myCenterPoint, mySecondPoint).Normalized(); |
528 | gp_Vec aDirectionN = aSecondVec.Crossed (aFirstVec).Normalized(); |
529 | gp_Vec aDirectionY = (aFirstVec + aSecondVec).Normalized(); |
530 | gp_Vec aDirectionX = aDirectionY.Crossed (aDirectionN).Normalized(); |
fe83e1ea |
531 | |
60bf98ae |
532 | myPlane = gp_Pln (gp_Ax3 (myCenterPoint, gp_Dir (aDirectionN), gp_Dir (aDirectionX))); |
533 | } |
7fd59977 |
534 | |
60bf98ae |
535 | //======================================================================= |
536 | //function : GetModelUnits |
537 | //purpose : |
538 | //======================================================================= |
539 | const TCollection_AsciiString& AIS_AngleDimension::GetModelUnits() const |
540 | { |
541 | return myDrawer->DimAngleModelUnits(); |
542 | } |
fe83e1ea |
543 | |
60bf98ae |
544 | //======================================================================= |
545 | //function : GetDisplayUnits |
546 | //purpose : |
547 | //======================================================================= |
548 | const TCollection_AsciiString& AIS_AngleDimension::GetDisplayUnits() const |
549 | { |
550 | return myDrawer->DimAngleDisplayUnits(); |
551 | } |
fe83e1ea |
552 | |
60bf98ae |
553 | //======================================================================= |
554 | //function : SetModelUnits |
555 | //purpose : |
556 | //======================================================================= |
557 | void AIS_AngleDimension::SetModelUnits (const TCollection_AsciiString& theUnits) |
558 | { |
559 | myDrawer->SetDimAngleModelUnits (theUnits); |
560 | } |
fe83e1ea |
561 | |
60bf98ae |
562 | //======================================================================= |
563 | //function : SetDisplayUnits |
564 | //purpose : |
565 | //======================================================================= |
566 | void AIS_AngleDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits) |
567 | { |
568 | myDrawer->SetDimAngleDisplayUnits (theUnits); |
569 | } |
570 | |
571 | //======================================================================= |
572 | //function : ComputeValue |
573 | //purpose : |
574 | //======================================================================= |
575 | Standard_Real AIS_AngleDimension::ComputeValue() const |
576 | { |
577 | if (!IsValid()) |
a6eb515f |
578 | { |
60bf98ae |
579 | return 0.0; |
7fd59977 |
580 | } |
60bf98ae |
581 | |
582 | gp_Vec aVec1 (myCenterPoint, myFirstPoint); |
583 | gp_Vec aVec2 (myCenterPoint, mySecondPoint); |
584 | |
585 | Standard_Real anAngle = aVec2.AngleWithRef (aVec1, GetPlane().Axis().Direction()); |
586 | |
af203d54 |
587 | return anAngle > 0.0 ? anAngle : (2.0 * M_PI + anAngle); |
7fd59977 |
588 | } |
589 | |
7fd59977 |
590 | //======================================================================= |
a6eb515f |
591 | //function : Compute |
592 | //purpose : Having three gp_Pnt points compute presentation |
7fd59977 |
593 | //======================================================================= |
a6eb515f |
594 | void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/, |
595 | const Handle(Prs3d_Presentation)& thePresentation, |
596 | const Standard_Integer theMode) |
597 | { |
598 | thePresentation->Clear(); |
fe83e1ea |
599 | mySelectionGeom.Clear (theMode); |
7fd59977 |
600 | |
60bf98ae |
601 | if (!IsValid()) |
a6eb515f |
602 | { |
a6eb515f |
603 | return; |
60bf98ae |
604 | } |
7fd59977 |
605 | |
a6eb515f |
606 | // Parameters for presentation |
607 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
d7bffd44 |
608 | |
60bf98ae |
609 | Prs3d_Root::CurrentGroup(thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect()); |
d7bffd44 |
610 | |
a6eb515f |
611 | Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length(); |
d7bffd44 |
612 | |
60bf98ae |
613 | // prepare label string and compute its geometrical width |
614 | Standard_Real aLabelWidth; |
615 | TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth); |
d7bffd44 |
616 | |
fe83e1ea |
617 | // add margins to label width |
618 | if (aDimensionAspect->IsText3d()) |
619 | { |
60bf98ae |
620 | aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0; |
d7bffd44 |
621 | } |
622 | |
af203d54 |
623 | // Get parameters from aspect or adjust it according with custom text position |
624 | Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize(); |
625 | Prs3d_DimensionTextHorizontalPosition aHorisontalTextPos = aDimensionAspect->TextHorizontalPosition(); |
7fd59977 |
626 | |
af203d54 |
627 | if (IsTextPositionCustom()) |
d7bffd44 |
628 | { |
af203d54 |
629 | AdjustParameters (myFixedTextPosition,anExtensionSize, aHorisontalTextPos); |
630 | } |
fe83e1ea |
631 | |
af203d54 |
632 | // Handle user-defined and automatic arrow placement |
633 | Standard_Boolean isArrowsExternal = Standard_False; |
634 | Standard_Integer aLabelPosition = LabelPosition_None; |
fe83e1ea |
635 | |
af203d54 |
636 | FitTextAlignment (aHorisontalTextPos, aLabelPosition, isArrowsExternal); |
d7bffd44 |
637 | |
af203d54 |
638 | gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout()); |
639 | gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout()); |
7fd59977 |
640 | |
a6eb515f |
641 | //Arrows positions and directions |
60bf98ae |
642 | gp_Vec aWPDir = gp_Vec (GetPlane().Axis().Direction()); |
d7bffd44 |
643 | |
60bf98ae |
644 | gp_Dir aFirstExtensionDir = aWPDir ^ gp_Vec (myCenterPoint, aFirstAttach); |
645 | gp_Dir aSecondExtensionDir = aWPDir.Reversed() ^ gp_Vec (myCenterPoint, aSecondAttach); |
7fd59977 |
646 | |
d7bffd44 |
647 | gp_Vec aFirstArrowVec = gp_Vec (aFirstExtensionDir) * anArrowLength; |
648 | gp_Vec aSecondArrowVec = gp_Vec (aSecondExtensionDir) * anArrowLength; |
7fd59977 |
649 | |
d7bffd44 |
650 | gp_Pnt aFirstArrowBegin (0.0, 0.0, 0.0); |
651 | gp_Pnt aFirstArrowEnd (0.0, 0.0, 0.0); |
652 | gp_Pnt aSecondArrowBegin (0.0, 0.0, 0.0); |
653 | gp_Pnt aSecondArrowEnd (0.0, 0.0, 0.0); |
654 | |
655 | if (isArrowsExternal) |
a6eb515f |
656 | { |
657 | aFirstArrowVec.Reverse(); |
658 | aSecondArrowVec.Reverse(); |
d7bffd44 |
659 | } |
660 | |
661 | aFirstArrowBegin = aFirstAttach; |
662 | aSecondArrowBegin = aSecondAttach; |
663 | aFirstArrowEnd = aFirstAttach.Translated (-aFirstArrowVec); |
664 | aSecondArrowEnd = aSecondAttach.Translated (-aSecondArrowVec); |
665 | |
d7bffd44 |
666 | // Group1: stenciling text and the angle dimension arc |
667 | Prs3d_Root::NewGroup (thePresentation); |
668 | |
d7bffd44 |
669 | Standard_Integer aHPosition = aLabelPosition & LabelPosition_HMask; |
670 | |
671 | // draw text label |
672 | switch (aHPosition) |
b8ddfc2f |
673 | { |
d7bffd44 |
674 | case LabelPosition_HCenter : |
a6eb515f |
675 | { |
d7bffd44 |
676 | Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center |
677 | && aDimensionAspect->IsText3d(); |
678 | |
679 | if (isLineBreak) |
680 | { |
60bf98ae |
681 | DrawArcWithText (thePresentation, |
d7bffd44 |
682 | aFirstAttach, |
683 | aSecondAttach, |
60bf98ae |
684 | myCenterPoint, |
685 | aLabelString, |
686 | aLabelWidth, |
fe83e1ea |
687 | theMode, |
d7bffd44 |
688 | aLabelPosition); |
689 | break; |
690 | } |
691 | |
fe83e1ea |
692 | // compute text primitives |
693 | if (theMode == ComputeMode_All || theMode == ComputeMode_Text) |
d7bffd44 |
694 | { |
60bf98ae |
695 | gp_Vec aDimensionDir (aFirstAttach, aSecondAttach); |
af203d54 |
696 | gp_Pnt aTextPos = IsTextPositionCustom() ? myFixedTextPosition |
697 | : GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint); |
60bf98ae |
698 | gp_Dir aTextDir = aDimensionDir; |
fe83e1ea |
699 | |
60bf98ae |
700 | DrawText (thePresentation, |
fe83e1ea |
701 | aTextPos, |
702 | aTextDir, |
60bf98ae |
703 | aLabelString, |
fe83e1ea |
704 | aLabelPosition); |
d7bffd44 |
705 | } |
706 | |
fe83e1ea |
707 | if (theMode == ComputeMode_All || theMode == ComputeMode_Line) |
708 | { |
60bf98ae |
709 | DrawArc (thePresentation, |
fe83e1ea |
710 | isArrowsExternal ? aFirstAttach : aFirstArrowEnd, |
711 | isArrowsExternal ? aSecondAttach : aSecondArrowEnd, |
60bf98ae |
712 | myCenterPoint, |
fe83e1ea |
713 | Abs (GetFlyout()), |
714 | theMode); |
715 | } |
a6eb515f |
716 | } |
d7bffd44 |
717 | break; |
718 | |
719 | case LabelPosition_Left : |
a6eb515f |
720 | { |
60bf98ae |
721 | DrawExtension (thePresentation, |
d7bffd44 |
722 | anExtensionSize, |
723 | isArrowsExternal ? aFirstArrowEnd : aFirstAttach, |
724 | aFirstExtensionDir, |
60bf98ae |
725 | aLabelString, |
726 | aLabelWidth, |
fe83e1ea |
727 | theMode, |
d7bffd44 |
728 | aLabelPosition); |
a6eb515f |
729 | } |
d7bffd44 |
730 | break; |
731 | |
732 | case LabelPosition_Right : |
a6eb515f |
733 | { |
60bf98ae |
734 | DrawExtension (thePresentation, |
d7bffd44 |
735 | anExtensionSize, |
736 | isArrowsExternal ? aSecondArrowEnd : aSecondAttach, |
737 | aSecondExtensionDir, |
60bf98ae |
738 | aLabelString, |
739 | aLabelWidth, |
fe83e1ea |
740 | theMode, |
d7bffd44 |
741 | aLabelPosition); |
a6eb515f |
742 | } |
d7bffd44 |
743 | break; |
744 | } |
745 | |
746 | // dimension arc without text |
fe83e1ea |
747 | if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && aHPosition != LabelPosition_HCenter) |
d7bffd44 |
748 | { |
749 | Prs3d_Root::NewGroup (thePresentation); |
750 | |
60bf98ae |
751 | DrawArc (thePresentation, |
d7bffd44 |
752 | isArrowsExternal ? aFirstAttach : aFirstArrowEnd, |
753 | isArrowsExternal ? aSecondAttach : aSecondArrowEnd, |
60bf98ae |
754 | myCenterPoint, |
d7bffd44 |
755 | Abs(GetFlyout ()), |
fe83e1ea |
756 | theMode); |
d7bffd44 |
757 | } |
7fd59977 |
758 | |
d7bffd44 |
759 | // arrows and arrow extensions |
fe83e1ea |
760 | if (theMode == ComputeMode_All || theMode == ComputeMode_Line) |
d7bffd44 |
761 | { |
762 | Prs3d_Root::NewGroup (thePresentation); |
763 | |
60bf98ae |
764 | DrawArrow (thePresentation, aFirstArrowBegin, gp_Dir (aFirstArrowVec)); |
765 | DrawArrow (thePresentation, aSecondArrowBegin, gp_Dir (aSecondArrowVec)); |
d7bffd44 |
766 | } |
767 | |
fe83e1ea |
768 | if ((theMode == ComputeMode_All || theMode == ComputeMode_Line) && isArrowsExternal) |
d7bffd44 |
769 | { |
770 | Prs3d_Root::NewGroup (thePresentation); |
771 | |
772 | if (aHPosition != LabelPosition_Left) |
773 | { |
60bf98ae |
774 | DrawExtension (thePresentation, |
af203d54 |
775 | aDimensionAspect->ArrowTailSize(), |
d7bffd44 |
776 | aFirstArrowEnd, |
777 | aFirstExtensionDir, |
fe83e1ea |
778 | THE_EMPTY_LABEL_STRING, |
779 | THE_EMPTY_LABEL_WIDTH, |
780 | theMode, |
d7bffd44 |
781 | LabelPosition_None); |
782 | } |
783 | |
784 | if (aHPosition != LabelPosition_Right) |
a6eb515f |
785 | { |
60bf98ae |
786 | DrawExtension (thePresentation, |
af203d54 |
787 | aDimensionAspect->ArrowTailSize(), |
d7bffd44 |
788 | aSecondArrowEnd, |
789 | aSecondExtensionDir, |
fe83e1ea |
790 | THE_EMPTY_LABEL_STRING, |
791 | THE_EMPTY_LABEL_WIDTH, |
792 | theMode, |
d7bffd44 |
793 | LabelPosition_None); |
a6eb515f |
794 | } |
795 | } |
7fd59977 |
796 | |
d7bffd44 |
797 | // flyouts |
60bf98ae |
798 | if (theMode == ComputeMode_All) |
a6eb515f |
799 | { |
d7bffd44 |
800 | Prs3d_Root::NewGroup (thePresentation); |
801 | |
802 | Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (4); |
60bf98ae |
803 | aPrimSegments->AddVertex (myCenterPoint); |
a6eb515f |
804 | aPrimSegments->AddVertex (aFirstAttach); |
60bf98ae |
805 | aPrimSegments->AddVertex (myCenterPoint); |
a6eb515f |
806 | aPrimSegments->AddVertex (aSecondAttach); |
d7bffd44 |
807 | |
808 | Handle(Graphic3d_AspectLine3d) aFlyoutStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect(); |
809 | Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aFlyoutStyle); |
a6eb515f |
810 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments); |
7fd59977 |
811 | } |
812 | |
60bf98ae |
813 | myIsComputed = Standard_True; |
7fd59977 |
814 | } |
62b6361a |
815 | |
816 | //======================================================================= |
60bf98ae |
817 | //function : ComputeFlyoutSelection |
62b6361a |
818 | //purpose : computes selection for flyouts |
819 | //======================================================================= |
60bf98ae |
820 | void AIS_AngleDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection, |
fe83e1ea |
821 | const Handle(SelectMgr_EntityOwner)& theOwner) |
62b6361a |
822 | { |
60bf98ae |
823 | gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * GetFlyout()); |
824 | gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * GetFlyout()); |
825 | |
826 | Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (theOwner); |
827 | aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aFirstAttach)); |
828 | aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myCenterPoint, aSecondAttach)); |
829 | |
830 | theSelection->Add (aSensitiveEntity); |
831 | } |
832 | |
833 | //======================================================================= |
834 | //function : InitTwoEdgesAngle |
835 | //purpose : |
836 | //======================================================================= |
837 | Standard_Boolean AIS_AngleDimension::InitTwoEdgesAngle (gp_Pln& theComputedPlane) |
838 | { |
839 | TopoDS_Edge aFirstEdge = TopoDS::Edge (myFirstShape); |
840 | TopoDS_Edge aSecondEdge = TopoDS::Edge (mySecondShape); |
841 | |
842 | BRepAdaptor_Curve aMakeFirstLine (aFirstEdge); |
843 | BRepAdaptor_Curve aMakeSecondLine (aSecondEdge); |
844 | |
845 | if (aMakeFirstLine.GetType() != GeomAbs_Line || aMakeSecondLine.GetType() != GeomAbs_Line) |
fe83e1ea |
846 | { |
60bf98ae |
847 | return Standard_False; |
fe83e1ea |
848 | } |
849 | |
60bf98ae |
850 | Handle(Geom_Line) aFirstLine = new Geom_Line (aMakeFirstLine.Line()); |
851 | Handle(Geom_Line) aSecondLine = new Geom_Line (aMakeSecondLine.Line()); |
fe83e1ea |
852 | |
60bf98ae |
853 | gp_Lin aFirstLin = aFirstLine->Lin(); |
854 | gp_Lin aSecondLin = aSecondLine->Lin(); |
fe83e1ea |
855 | |
60bf98ae |
856 | Standard_Boolean isParallelLines = Abs (aFirstLin.Angle (aSecondLin) - M_PI) <= Precision::Angular(); |
857 | |
858 | gp_Pnt aPoint = aFirstLine->Value (0.0); |
859 | gp_Dir aNormal = isParallelLines |
860 | ? gp_Vec (aSecondLin.Normal (aPoint).Direction()) ^ gp_Vec (aSecondLin.Direction()) |
861 | : gp_Vec (aFirstLin.Direction()) ^ gp_Vec (aSecondLin.Direction()); |
862 | |
863 | theComputedPlane = gp_Pln (aPoint, aNormal); |
864 | |
865 | // Compute geometry for this plane and edges |
866 | Standard_Boolean isInfinite1,isInfinite2; |
867 | gp_Pnt aFirstPoint1, aLastPoint1, aFirstPoint2, aLastPoint2; |
868 | gp_Lin2d aFirstLin2d, aSecondLin2d; |
869 | |
870 | if (!AIS::ComputeGeometry (aFirstEdge, aSecondEdge, |
871 | aFirstLine, aSecondLine, |
872 | aFirstPoint1, aLastPoint1, |
873 | aFirstPoint2, aLastPoint2, |
874 | isInfinite1, isInfinite2)) |
875 | { |
876 | return Standard_False; |
877 | } |
878 | |
879 | if (aFirstLin.Direction().IsParallel (aSecondLin.Direction(), Precision::Angular())) |
880 | { |
881 | myFirstPoint = aFirstLin.Location(); |
882 | mySecondPoint = ElCLib::Value (ElCLib::Parameter (aFirstLin, myFirstPoint), aSecondLin); |
883 | |
884 | if (mySecondPoint.Distance (myFirstPoint) <= Precision::Confusion()) |
885 | { |
886 | mySecondPoint.Translate (gp_Vec (aSecondLin.Direction()) * Abs (GetFlyout())); |
887 | } |
888 | |
889 | myCenterPoint.SetXYZ ((myFirstPoint.XYZ() + mySecondPoint.XYZ()) / 2.0); |
890 | } |
891 | else |
892 | { |
893 | // Find intersection |
894 | gp_Lin2d aFirstLin2d = ProjLib::Project (theComputedPlane, aFirstLin); |
895 | gp_Lin2d aSecondLin2d = ProjLib::Project (theComputedPlane, aSecondLin); |
896 | |
897 | IntAna2d_AnaIntersection anInt2d (aFirstLin2d, aSecondLin2d); |
898 | gp_Pnt2d anIntersectPoint; |
899 | if (!anInt2d.IsDone() || anInt2d.IsEmpty()) |
900 | { |
901 | return Standard_False; |
902 | } |
903 | |
904 | anIntersectPoint = gp_Pnt2d (anInt2d.Point(1).Value()); |
905 | myCenterPoint = ElCLib::To3d (theComputedPlane.Position().Ax2(), anIntersectPoint); |
906 | |
907 | if (isInfinite1 || isInfinite2) |
908 | { |
909 | myFirstPoint = myCenterPoint.Translated (gp_Vec (aFirstLin.Direction()) * Abs (GetFlyout())); |
910 | mySecondPoint = myCenterPoint.Translated (gp_Vec (aSecondLin.Direction()) * Abs (GetFlyout())); |
911 | |
912 | return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint); |
913 | } |
914 | |
915 | // | |
916 | // | <- dimension should be here |
917 | // *---- |
918 | myFirstPoint = myCenterPoint.Distance (aFirstPoint1) > myCenterPoint.Distance (aLastPoint1) |
919 | ? aFirstPoint1 |
920 | : aLastPoint1; |
921 | |
922 | mySecondPoint = myCenterPoint.Distance (aFirstPoint2) > myCenterPoint.Distance (aLastPoint2) |
923 | ? aFirstPoint2 |
924 | : aLastPoint2; |
925 | } |
926 | |
927 | return IsValidPoints (myFirstPoint, myCenterPoint, mySecondPoint); |
928 | } |
929 | |
930 | //======================================================================= |
931 | //function : InitTwoFacesAngle |
932 | //purpose : initialization of angle dimension between two faces |
933 | //======================================================================= |
934 | Standard_Boolean AIS_AngleDimension::InitTwoFacesAngle() |
935 | { |
936 | TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape); |
937 | TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape); |
938 | |
939 | gp_Dir aFirstDir, aSecondDir; |
940 | gp_Pln aFirstPlane, aSecondPlane; |
941 | Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf; |
942 | AIS_KindOfSurface aFirstSurfType, aSecondSurfType; |
943 | Standard_Real aFirstOffset, aSecondOffset; |
944 | |
945 | AIS::GetPlaneFromFace (aFirstFace, aFirstPlane, |
946 | aFirstBasisSurf,aFirstSurfType,aFirstOffset); |
947 | |
948 | AIS::GetPlaneFromFace (aSecondFace, aSecondPlane, |
949 | aSecondBasisSurf, aSecondSurfType, aSecondOffset); |
950 | |
951 | if (aFirstSurfType == AIS_KOS_Plane && aSecondSurfType == AIS_KOS_Plane) |
952 | { |
953 | //Planar faces angle |
954 | Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf); |
955 | Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf); |
956 | return AIS::InitAngleBetweenPlanarFaces (aFirstFace, |
957 | aSecondFace, |
958 | myCenterPoint, |
959 | myFirstPoint, |
960 | mySecondPoint) |
961 | && IsValidPoints (myFirstPoint, |
962 | myCenterPoint, |
963 | mySecondPoint); |
964 | } |
965 | else |
966 | { |
967 | // Curvilinear faces angle |
968 | return AIS::InitAngleBetweenCurvilinearFaces (aFirstFace, |
969 | aSecondFace, |
970 | aFirstSurfType, |
971 | aSecondSurfType, |
972 | myCenterPoint, |
973 | myFirstPoint, |
974 | mySecondPoint) |
975 | && IsValidPoints (myFirstPoint, |
976 | myCenterPoint, |
977 | mySecondPoint); |
978 | } |
979 | } |
980 | |
981 | //======================================================================= |
982 | //function : InitTwoFacesAngle |
983 | //purpose : initialization of angle dimension between two faces |
984 | //======================================================================= |
985 | Standard_Boolean AIS_AngleDimension::InitTwoFacesAngle (const gp_Pnt thePointOnFirstFace) |
986 | { |
987 | TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape); |
988 | TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape); |
989 | |
990 | gp_Dir aFirstDir, aSecondDir; |
991 | gp_Pln aFirstPlane, aSecondPlane; |
992 | Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf; |
993 | AIS_KindOfSurface aFirstSurfType, aSecondSurfType; |
994 | Standard_Real aFirstOffset, aSecondOffset; |
995 | |
996 | AIS::GetPlaneFromFace (aFirstFace, aFirstPlane, |
997 | aFirstBasisSurf,aFirstSurfType,aFirstOffset); |
998 | |
999 | AIS::GetPlaneFromFace (aSecondFace, aSecondPlane, |
1000 | aSecondBasisSurf, aSecondSurfType, aSecondOffset); |
1001 | |
1002 | myFirstPoint = thePointOnFirstFace; |
1003 | if (aFirstSurfType == AIS_KOS_Plane && aSecondSurfType == AIS_KOS_Plane) |
1004 | { |
1005 | //Planar faces angle |
1006 | Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (aFirstBasisSurf); |
1007 | Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (aSecondBasisSurf); |
1008 | return AIS::InitAngleBetweenPlanarFaces (aFirstFace, |
1009 | aSecondFace, |
1010 | myCenterPoint, |
1011 | myFirstPoint, |
1012 | mySecondPoint, |
1013 | Standard_True) |
1014 | && IsValidPoints (myFirstPoint, |
1015 | myCenterPoint, |
1016 | mySecondPoint); |
1017 | } |
1018 | else |
1019 | { |
1020 | // Curvilinear faces angle |
1021 | return AIS::InitAngleBetweenCurvilinearFaces (aFirstFace, |
1022 | aSecondFace, |
1023 | aFirstSurfType, |
1024 | aSecondSurfType, |
1025 | myCenterPoint, |
1026 | myFirstPoint, |
1027 | mySecondPoint, |
1028 | Standard_True) |
1029 | && IsValidPoints (myFirstPoint, |
1030 | myCenterPoint, |
1031 | mySecondPoint); |
1032 | } |
1033 | } |
1034 | |
1035 | //======================================================================= |
1036 | //function : InitConeAngle |
1037 | //purpose : initialization of the cone angle |
1038 | //======================================================================= |
1039 | Standard_Boolean AIS_AngleDimension::InitConeAngle() |
1040 | { |
1041 | if (myFirstShape.IsNull()) |
1042 | { |
1043 | return Standard_False; |
1044 | } |
1045 | |
1046 | TopoDS_Face aConeShape = TopoDS::Face (myFirstShape); |
1047 | gp_Pln aPln; |
1048 | gp_Cone aCone; |
1049 | gp_Circ aCircle; |
1050 | // A surface from the Face |
1051 | Handle(Geom_Surface) aSurf; |
1052 | Handle(Geom_OffsetSurface) aOffsetSurf; |
1053 | Handle(Geom_ConicalSurface) aConicalSurf; |
1054 | Handle(Geom_SurfaceOfRevolution) aRevSurf; |
1055 | Handle(Geom_Line) aLine; |
1056 | BRepAdaptor_Surface aConeAdaptor (aConeShape); |
1057 | TopoDS_Face aFace; |
1058 | AIS_KindOfSurface aSurfType; |
1059 | Standard_Real anOffset = 0.; |
1060 | Handle(Standard_Type) aType; |
1061 | |
1062 | Standard_Real aMaxV = aConeAdaptor.FirstVParameter(); |
1063 | Standard_Real aMinV = aConeAdaptor.LastVParameter(); |
1064 | |
1065 | AIS::GetPlaneFromFace (aConeShape, aPln, aSurf, aSurfType, anOffset); |
1066 | |
1067 | if (aSurfType == AIS_KOS_Revolution) |
1068 | { |
1069 | // Surface of revolution |
1070 | aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aSurf); |
1071 | gp_Lin aLin (aRevSurf->Axis()); |
1072 | Handle(Geom_Curve) aBasisCurve = aRevSurf->BasisCurve(); |
1073 | //Must be a part of line (basis curve should be linear) |
1074 | if (aBasisCurve ->DynamicType() != STANDARD_TYPE(Geom_Line)) |
1075 | return Standard_False; |
1076 | |
1077 | gp_Pnt aFirst1 = aConeAdaptor.Value (0., aMinV); |
1078 | gp_Pnt aLast1 = aConeAdaptor.Value (0., aMaxV); |
1079 | gp_Vec aVec1 (aFirst1, aLast1); |
1080 | |
1081 | //Projection <aFirst> on <aLin> |
1082 | gp_Pnt aFirst2 = ElCLib::Value (ElCLib::Parameter (aLin, aFirst1), aLin); |
1083 | // Projection <aLast> on <aLin> |
1084 | gp_Pnt aLast2 = ElCLib::Value (ElCLib::Parameter (aLin, aLast1), aLin); |
1085 | |
1086 | gp_Vec aVec2 (aFirst2, aLast2); |
1087 | |
1088 | // Check if two parts of revolution are parallel (it's a cylinder) or normal (it's a circle). |
1089 | if (aVec1.IsParallel (aVec2, Precision::Angular()) |
1090 | || aVec1.IsNormal (aVec2,Precision::Angular())) |
1091 | return Standard_False; |
1092 | |
1093 | gce_MakeCone aMkCone (aRevSurf->Axis(), aFirst1, aLast1); |
1094 | aCone = aMkCone.Value(); |
1095 | myCenterPoint = aCone.Apex(); |
1096 | } |
1097 | else |
1098 | { |
1099 | aType = aSurf->DynamicType(); |
1100 | if (aType == STANDARD_TYPE(Geom_OffsetSurface) || anOffset > 0.01) |
1101 | { |
1102 | // Offset surface |
1103 | aOffsetSurf = new Geom_OffsetSurface (aSurf, anOffset); |
1104 | aSurf = aOffsetSurf->Surface(); |
1105 | BRepBuilderAPI_MakeFace aMkFace(aSurf, Precision::Confusion()); |
1106 | aMkFace.Build(); |
1107 | if (!aMkFace.IsDone()) |
1108 | return Standard_False; |
1109 | aConeAdaptor.Initialize (aMkFace.Face()); |
1110 | } |
1111 | aCone = aConeAdaptor.Cone(); |
1112 | aConicalSurf = Handle(Geom_ConicalSurface)::DownCast (aSurf); |
1113 | myCenterPoint = aConicalSurf->Apex(); |
1114 | } |
1115 | |
1116 | // A circle where the angle is drawn |
1117 | Handle(Geom_Curve) aCurve; |
1118 | Standard_Real aMidV = ( aMinV + aMaxV ) / 2.5; |
1119 | aCurve = aSurf->VIso (aMidV); |
1120 | aCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ(); |
1121 | |
1122 | aCurve = aSurf->VIso(aMaxV); |
1123 | gp_Circ aCircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ(); |
1124 | aCurve = aSurf->VIso(aMinV); |
1125 | gp_Circ aCircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ(); |
1126 | |
1127 | if (aCircVmax.Radius() < aCircVmin.Radius()) |
1128 | { |
1129 | gp_Circ aTmpCirc = aCircVmax; |
1130 | aCircVmax = aCircVmin; |
1131 | aCircVmin = aTmpCirc; |
1132 | } |
1133 | |
1134 | myFirstPoint = ElCLib::Value (0, aCircle); |
1135 | mySecondPoint = ElCLib::Value (M_PI, aCircle); |
1136 | return Standard_True; |
1137 | } |
1138 | |
1139 | //======================================================================= |
1140 | //function : IsValidPoints |
1141 | //purpose : |
1142 | //======================================================================= |
1143 | Standard_Boolean AIS_AngleDimension::IsValidPoints (const gp_Pnt& theFirstPoint, |
1144 | const gp_Pnt& theCenterPoint, |
1145 | const gp_Pnt& theSecondPoint) const |
1146 | { |
1147 | return theFirstPoint.Distance (theCenterPoint) > Precision::Confusion() |
1148 | && theSecondPoint.Distance (theCenterPoint) > Precision::Confusion() |
1149 | && gp_Vec (theCenterPoint, theFirstPoint).Angle ( |
1150 | gp_Vec (theCenterPoint, theSecondPoint)) > Precision::Angular(); |
d7bffd44 |
1151 | } |
af203d54 |
1152 | |
1153 | //======================================================================= |
1154 | //function : GetTextPosition |
1155 | //purpose : |
1156 | //======================================================================= |
1157 | const gp_Pnt AIS_AngleDimension::GetTextPosition() const |
1158 | { |
1159 | if (!IsValid()) |
1160 | { |
1161 | return gp::Origin(); |
1162 | } |
1163 | |
1164 | if (IsTextPositionCustom()) |
1165 | { |
1166 | return myFixedTextPosition; |
1167 | } |
1168 | |
1169 | // Counts text position according to the dimension parameters |
1170 | gp_Pnt aTextPosition (gp::Origin()); |
1171 | |
1172 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
1173 | |
1174 | // Prepare label string and compute its geometrical width |
1175 | Standard_Real aLabelWidth; |
1176 | TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth); |
1177 | |
1178 | gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, myFirstPoint).Normalized() * GetFlyout()); |
1179 | gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec(myCenterPoint, mySecondPoint).Normalized() * GetFlyout()); |
1180 | |
1181 | // Handle user-defined and automatic arrow placement |
1182 | Standard_Boolean isArrowsExternal = Standard_False; |
1183 | Standard_Integer aLabelPosition = LabelPosition_None; |
1184 | FitTextAlignment (aDimensionAspect->TextHorizontalPosition(), |
1185 | aLabelPosition, isArrowsExternal); |
1186 | |
1187 | // Get text position |
1188 | switch (aLabelPosition & LabelPosition_HMask) |
1189 | { |
1190 | case LabelPosition_HCenter: |
1191 | { |
1192 | aTextPosition = GetCenterOnArc (aFirstAttach, aSecondAttach, myCenterPoint); |
1193 | } |
1194 | break; |
1195 | case LabelPosition_Left: |
1196 | { |
1197 | gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach); |
1198 | gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aFirstAttach); |
1199 | Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize(); |
1200 | Standard_Real anOffset = isArrowsExternal |
1201 | ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length() |
1202 | : anExtensionSize; |
1203 | gp_Vec anExtensionVec = gp_Vec (anExtensionDir) * -anOffset; |
1204 | aTextPosition = aFirstAttach.Translated (anExtensionVec); |
1205 | } |
1206 | break; |
1207 | case LabelPosition_Right: |
1208 | { |
1209 | gp_Dir aPlaneNormal = gp_Vec (aFirstAttach, aSecondAttach) ^ gp_Vec (myCenterPoint, aFirstAttach); |
1210 | gp_Dir anExtensionDir = aPlaneNormal ^ gp_Vec (myCenterPoint, aSecondAttach); |
1211 | Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize(); |
1212 | Standard_Real anOffset = isArrowsExternal |
1213 | ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length() |
1214 | : anExtensionSize; |
1215 | gp_Vec anExtensionVec = gp_Vec (anExtensionDir) * anOffset; |
1216 | aTextPosition = aSecondAttach.Translated (anExtensionVec); |
1217 | } |
1218 | break; |
1219 | } |
1220 | |
1221 | return aTextPosition; |
1222 | } |
1223 | |
1224 | //======================================================================= |
1225 | //function : SetTextPosition |
1226 | //purpose : |
1227 | //======================================================================= |
1228 | void AIS_AngleDimension::SetTextPosition (const gp_Pnt& theTextPos) |
1229 | { |
1230 | if (!IsValid()) |
1231 | { |
1232 | return; |
1233 | } |
1234 | |
1235 | // The text position point for angle dimension should belong to the working plane. |
1236 | if (!GetPlane().Contains (theTextPos, Precision::Confusion())) |
1237 | { |
1238 | Standard_ProgramError::Raise ("The text position point for angle dimension doesn't belong to the working plane."); |
1239 | } |
1240 | |
1241 | myIsTextPositionFixed = Standard_True; |
1242 | myFixedTextPosition = theTextPos; |
1243 | } |
1244 | |
1245 | //======================================================================= |
1246 | //function : AdjustAspectParameters |
1247 | //purpose : |
1248 | //======================================================================= |
1249 | void AIS_AngleDimension::AdjustParameters (const gp_Pnt& theTextPos, |
1250 | Standard_Real& theExtensionSize, |
1251 | Prs3d_DimensionTextHorizontalPosition& theAlignment) |
1252 | { |
1253 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
1254 | Standard_Real anArrowLength = aDimensionAspect->ArrowAspect()->Length(); |
1255 | |
1256 | // Compute flyout direction vector. |
1257 | gp_Dir aPlaneNormal = GetPlane().Axis().Direction(); |
1258 | gp_Dir aTargetPointsDir = gce_MakeDir (myFirstPoint, mySecondPoint); |
1259 | |
1260 | // Build circle with radius that is equal to distance from text position to the center point. |
1261 | Standard_Real aRadius = gp_Vec (myCenterPoint, theTextPos).Magnitude(); |
1262 | |
1263 | // Set attach points in positive direction of the flyout. |
1264 | gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * aRadius); |
1265 | gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * aRadius); |
1266 | |
1267 | gce_MakeCirc aConstructCircle (myCenterPoint, GetPlane(), aRadius); |
1268 | if (!aConstructCircle.IsDone()) |
1269 | { |
1270 | return; |
1271 | } |
1272 | gp_Circ aCircle = aConstructCircle.Value(); |
1273 | |
1274 | // Default values |
1275 | theExtensionSize = aDimensionAspect->ArrowAspect()->Length(); |
1276 | theAlignment = Prs3d_DTHP_Center; |
1277 | |
1278 | Standard_Real aParamBeg = ElCLib::Parameter (aCircle, aFirstAttach); |
1279 | Standard_Real aParamEnd = ElCLib::Parameter (aCircle, aSecondAttach); |
1280 | if (aParamEnd < aParamBeg) |
1281 | { |
1282 | Standard_Real aParam = aParamEnd; |
1283 | aParamEnd = aParamBeg; |
1284 | aParamBeg = aParam; |
1285 | } |
1286 | |
1287 | ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd); |
1288 | Standard_Real aTextPar = ElCLib::Parameter (aCircle , theTextPos); |
1289 | |
1290 | // Horizontal center |
1291 | if (aTextPar > aParamBeg && aTextPar < aParamEnd) |
1292 | { |
1293 | myFlyout = aRadius; |
1294 | |
1295 | SetToUpdate(); |
1296 | return; |
1297 | } |
1298 | |
1299 | aParamBeg += M_PI; |
1300 | aParamEnd += M_PI; |
1301 | ElCLib::AdjustPeriodic (0.0, M_PI * 2, Precision::PConfusion(), aParamBeg, aParamEnd); |
1302 | |
1303 | if (aTextPar > aParamBeg && aTextPar < aParamEnd) |
1304 | { |
1305 | myFlyout = -aRadius; |
1306 | |
1307 | SetToUpdate(); |
1308 | return; |
1309 | } |
1310 | |
1311 | // Text on the extensions |
1312 | gp_Lin aFirstLine = gce_MakeLin (myCenterPoint, myFirstPoint); |
1313 | gp_Lin aSecondLine = gce_MakeLin (myCenterPoint, mySecondPoint); |
1314 | gp_Pnt aFirstTextProj = AIS::Nearest (aFirstLine, theTextPos); |
1315 | gp_Pnt aSecondTextProj = AIS::Nearest (aSecondLine, theTextPos); |
1316 | Standard_Real aFirstDist = aFirstTextProj.Distance (theTextPos); |
1317 | Standard_Real aSecondDist = aSecondTextProj.Distance (theTextPos); |
1318 | |
1319 | if (aFirstDist <= aSecondDist) |
1320 | { |
1321 | aRadius = myCenterPoint.Distance (aFirstTextProj); |
1322 | Standard_Real aNewExtensionSize = aFirstDist - anArrowLength; |
1323 | theExtensionSize = aNewExtensionSize < 0.0 ? 0.0 : aNewExtensionSize; |
1324 | |
1325 | theAlignment = Prs3d_DTHP_Left; |
1326 | |
1327 | gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, myFirstPoint).Normalized().Scaled (aRadius); |
1328 | |
1329 | myFlyout = aFirstTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion() |
1330 | ? -aRadius : aRadius; |
1331 | } |
1332 | else |
1333 | { |
1334 | aRadius = myCenterPoint.Distance (aSecondTextProj); |
1335 | |
1336 | Standard_Real aNewExtensionSize = aSecondDist - anArrowLength; |
1337 | |
1338 | theExtensionSize = aNewExtensionSize < 0.0 ? 0.0 : aNewExtensionSize; |
1339 | |
1340 | theAlignment = Prs3d_DTHP_Right; |
1341 | |
1342 | gp_Vec aPosFlyoutDir = gp_Vec (myCenterPoint, mySecondPoint).Normalized().Scaled (aRadius); |
1343 | |
1344 | myFlyout = aSecondTextProj.Distance (myCenterPoint.Translated (aPosFlyoutDir)) > Precision::Confusion() |
1345 | ? -aRadius : aRadius; |
1346 | } |
1347 | } |
1348 | |
1349 | //======================================================================= |
1350 | //function : FitTextAlignment |
1351 | //purpose : |
1352 | //======================================================================= |
1353 | void AIS_AngleDimension::FitTextAlignment (const Prs3d_DimensionTextHorizontalPosition& theHorizontalTextPos, |
1354 | Standard_Integer& theLabelPosition, |
1355 | Standard_Boolean& theIsArrowsExternal) const |
1356 | { |
1357 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
1358 | |
1359 | Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length(); |
1360 | |
1361 | // Prepare label string and compute its geometrical width |
1362 | Standard_Real aLabelWidth; |
1363 | TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth); |
1364 | |
1365 | // add margins to label width |
1366 | if (aDimensionAspect->IsText3d()) |
1367 | { |
1368 | aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0; |
1369 | } |
1370 | |
1371 | gp_Pnt aFirstAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, myFirstPoint).Normalized() * GetFlyout()); |
1372 | gp_Pnt aSecondAttach = myCenterPoint.Translated (gp_Vec (myCenterPoint, mySecondPoint).Normalized() * GetFlyout()); |
1373 | |
1374 | // Handle user-defined and automatic arrow placement |
1375 | switch (aDimensionAspect->ArrowOrientation()) |
1376 | { |
1377 | case Prs3d_DAO_External: theIsArrowsExternal = true; break; |
1378 | case Prs3d_DAO_Internal: theIsArrowsExternal = false; break; |
1379 | case Prs3d_DAO_Fit: |
1380 | { |
1381 | gp_Vec anAttachVector (aFirstAttach, aSecondAttach); |
1382 | Standard_Real aDimensionWidth = anAttachVector.Magnitude(); |
1383 | |
1384 | // Add margin to ensure a small tail between text and arrow |
1385 | Standard_Real anArrowMargin = aDimensionAspect->IsText3d() |
1386 | ? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN |
1387 | : 0.0; |
1388 | |
1389 | Standard_Real anArrowsWidth = (anArrowLength + anArrowMargin) * 2.0; |
1390 | |
1391 | theIsArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth; |
1392 | break; |
1393 | } |
1394 | } |
1395 | |
1396 | // Handle user-defined and automatic text placement |
1397 | switch (theHorizontalTextPos) |
1398 | { |
1399 | case Prs3d_DTHP_Left : theLabelPosition |= LabelPosition_Left; break; |
1400 | case Prs3d_DTHP_Right : theLabelPosition |= LabelPosition_Right; break; |
1401 | case Prs3d_DTHP_Center: theLabelPosition |= LabelPosition_HCenter; break; |
1402 | case Prs3d_DTHP_Fit: |
1403 | { |
1404 | gp_Vec anAttachVector (aFirstAttach, aSecondAttach); |
1405 | Standard_Real aDimensionWidth = anAttachVector.Magnitude(); |
1406 | Standard_Real anArrowsWidth = anArrowLength * 2.0; |
1407 | Standard_Real aContentWidth = theIsArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth; |
1408 | |
1409 | theLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter; |
1410 | break; |
1411 | } |
1412 | } |
1413 | |
1414 | switch (aDimensionAspect->TextVerticalPosition()) |
1415 | { |
1416 | case Prs3d_DTVP_Above : theLabelPosition |= LabelPosition_Above; break; |
1417 | case Prs3d_DTVP_Below : theLabelPosition |= LabelPosition_Below; break; |
1418 | case Prs3d_DTVP_Center : theLabelPosition |= LabelPosition_VCenter; break; |
1419 | } |
1420 | } |