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