b311480e |
1 | // Created on: 1996-12-05 |
2 | // Created by: Arnaud BOUZY/Odile Olivier |
3 | // Copyright (c) 1996-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
a6eb515f |
21 | #include <AIS_AngleDimension.hxx> |
7fd59977 |
22 | |
23 | #include <AIS.hxx> |
a6eb515f |
24 | #include <AIS_Dimension.hxx> |
7fd59977 |
25 | #include <AIS_DimensionOwner.hxx> |
26 | #include <AIS_Drawer.hxx> |
a6eb515f |
27 | #include <BRep_Tool.hxx> |
7fd59977 |
28 | #include <BRepBuilderAPI_MakeFace.hxx> |
29 | #include <BRepAdaptor_Curve.hxx> |
30 | #include <BRepAdaptor_Surface.hxx> |
a6eb515f |
31 | #include <BRepLib_MakeVertex.hxx> |
7fd59977 |
32 | |
33 | #include <DsgPrs.hxx> |
34 | #include <DsgPrs_AnglePresentation.hxx> |
35 | |
36 | #include <ElCLib.hxx> |
37 | #include <ElSLib.hxx> |
38 | |
a6eb515f |
39 | #include <GC_MakeCircle.hxx> |
40 | #include <GC_MakeConicalSurface.hxx> |
41 | #include <gce_MakeLin.hxx> |
42 | #include <gce_MakeLin2d.hxx> |
43 | #include <gce_MakePln.hxx> |
44 | #include <gce_MakeCirc.hxx> |
45 | #include <gce_MakeCone.hxx> |
7fd59977 |
46 | #include <Geom2d_Circle.hxx> |
47 | #include <Geom2d_Curve.hxx> |
48 | #include <Geom2d_Line.hxx> |
a6eb515f |
49 | #include <Geom2dAPI_ExtremaCurveCurve.hxx> |
7fd59977 |
50 | #include <GeomAPI.hxx> |
51 | #include <Geom_Circle.hxx> |
52 | #include <Geom_Line.hxx> |
53 | #include <Geom_Plane.hxx> |
54 | #include <Geom_TrimmedCurve.hxx> |
55 | #include <Geom_Surface.hxx> |
56 | #include <Geom_CylindricalSurface.hxx> |
57 | #include <Geom_ConicalSurface.hxx> |
58 | #include <Geom_SurfaceOfRevolution.hxx> |
59 | #include <Geom_SurfaceOfLinearExtrusion.hxx> |
60 | #include <Geom_OffsetSurface.hxx> |
a6eb515f |
61 | #include <GeomAPI_ExtremaCurveCurve.hxx> |
62 | #include <Graphic3d_ArrayOfSegments.hxx> |
63 | #include <Graphic3d_AspectLine3d.hxx> |
64 | #include <gp.hxx> |
65 | #include <gp_Ax1.hxx> |
66 | #include <gp_Lin.hxx> |
67 | #include <gp_Cone.hxx> |
68 | #include <gp_Pln.hxx> |
69 | #include <gp_Pnt.hxx> |
70 | #include <gp_Pnt2d.hxx> |
71 | #include <gp_Vec.hxx> |
72 | #include <gp_XYZ.hxx> |
73 | #include <Graphic3d_Group.hxx> |
74 | #include <Graphic3d_ArrayOfPrimitives.hxx> |
75 | #include <Graphic3d_ArrayOfPolylines.hxx> |
7fd59977 |
76 | |
77 | #include <IntAna2d_AnaIntersection.hxx> |
78 | #include <IntAna2d_IntPoint.hxx> |
79 | #include <IntAna_QuadQuadGeo.hxx> |
80 | #include <IntAna_ResultType.hxx> |
a6eb515f |
81 | #include <Poly_Polygon3D.hxx> |
7fd59977 |
82 | #include <Precision.hxx> |
7fd59977 |
83 | #include <ProjLib.hxx> |
7fd59977 |
84 | #include <Prs3d_ArrowAspect.hxx> |
a6eb515f |
85 | #include <Prs3d_DimensionAspect.hxx> |
7fd59977 |
86 | #include <Prs3d_Drawer.hxx> |
a6eb515f |
87 | #include <Prs3d_Root.hxx> |
88 | #include <PrsMgr_PresentationManager3d.hxx> |
7fd59977 |
89 | #include <Select3D_SensitiveCurve.hxx> |
90 | #include <Select3D_SensitiveSegment.hxx> |
91 | #include <Select3D_SensitiveBox.hxx> |
92 | #include <SelectMgr_EntityOwner.hxx> |
a6eb515f |
93 | #include <SelectMgr_Selection.hxx> |
94 | #include <Standard_NotImplemented.hxx> |
95 | #include <Standard_Type.hxx> |
96 | #include <Standard_Macro.hxx> |
97 | #include <Standard_DefineHandle.hxx> |
7fd59977 |
98 | |
99 | #include <TColStd_Array1OfReal.hxx> |
7fd59977 |
100 | #include <TopExp.hxx> |
101 | #include <TopExp_Explorer.hxx> |
102 | #include <TopoDS.hxx> |
103 | #include <TopoDS_Shape.hxx> |
104 | #include <TopoDS_Vertex.hxx> |
7fd59977 |
105 | #include <UnitsAPI.hxx> |
106 | |
a6eb515f |
107 | IMPLEMENT_STANDARD_HANDLE (AIS_AngleDimension, AIS_Dimension) |
108 | IMPLEMENT_STANDARD_RTTIEXT (AIS_AngleDimension, AIS_Dimension) |
7fd59977 |
109 | |
110 | //======================================================================= |
a6eb515f |
111 | //function : init |
112 | //purpose : Private constructor for default initialization |
7fd59977 |
113 | //======================================================================= |
114 | |
a6eb515f |
115 | void AIS_AngleDimension::init() |
7fd59977 |
116 | { |
a6eb515f |
117 | // Default values of units |
118 | UnitsAPI::SetLocalSystem (UnitsAPI_SI); |
119 | SetUnitsQuantity ("PLANE ANGLE"); |
120 | SetModelUnits ("rad"); |
121 | SetDisplayUnits ("deg"); |
122 | SetSpecialSymbol (0x00B0); |
123 | SetDisplaySpecialSymbol (AIS_DSS_After); |
124 | MakeUnitsDisplayed (Standard_False); |
7fd59977 |
125 | } |
126 | |
127 | //======================================================================= |
128 | //function : Constructor |
a6eb515f |
129 | //purpose : Two edges dimension |
7fd59977 |
130 | //======================================================================= |
131 | |
a6eb515f |
132 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge, |
133 | const TopoDS_Edge& theSecondEdge) |
134 | : AIS_Dimension(), |
135 | myIsFlyoutLines (Standard_True), |
136 | myFlyout (15.0) |
7fd59977 |
137 | { |
a6eb515f |
138 | init(); |
139 | myShapesNumber = 2; |
140 | SetKindOfDimension (AIS_KOD_PLANEANGLE); |
141 | myFirstShape = theFirstEdge; |
142 | mySecondShape = theSecondEdge; |
7fd59977 |
143 | } |
144 | |
7fd59977 |
145 | //======================================================================= |
146 | //function : Constructor |
a6eb515f |
147 | //purpose : Two edges dimension |
148 | // <thePlane> is used in case of Angle=PI |
7fd59977 |
149 | //======================================================================= |
150 | |
a6eb515f |
151 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge, |
152 | const TopoDS_Edge& theSecondEdge, |
153 | const gp_Pln& thePlane) |
154 | : AIS_Dimension(), |
155 | myIsFlyoutLines (Standard_True), |
156 | myFlyout (15.0) |
7fd59977 |
157 | { |
a6eb515f |
158 | init(); |
159 | myShapesNumber = 2; |
160 | SetKindOfDimension (AIS_KOD_PLANEANGLE); |
161 | myFirstShape = theFirstEdge; |
162 | mySecondShape = theSecondEdge; |
163 | SetWorkingPlane (thePlane); |
7fd59977 |
164 | } |
165 | |
166 | //======================================================================= |
167 | //function : Constructor |
a6eb515f |
168 | //purpose : Two edges dimension with aspect |
169 | // <thePlane> is used in case of Angle=PI |
7fd59977 |
170 | //======================================================================= |
171 | |
a6eb515f |
172 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Edge& theFirstEdge, |
173 | const TopoDS_Edge& theSecondEdge, |
174 | const gp_Pln& thePlane, |
175 | const Handle(Prs3d_DimensionAspect)& theDimensionAspect, |
176 | const Standard_Real theExtensionSize) |
177 | : AIS_Dimension (theDimensionAspect,theExtensionSize), |
178 | myIsFlyoutLines (Standard_True), |
179 | myFlyout (15.0) |
7fd59977 |
180 | { |
a6eb515f |
181 | myShapesNumber = 2; |
182 | SetKindOfDimension (AIS_KOD_PLANEANGLE); |
183 | myFirstShape = theFirstEdge; |
184 | mySecondShape = theSecondEdge; |
185 | SetWorkingPlane (thePlane); |
7fd59977 |
186 | } |
187 | |
188 | //======================================================================= |
189 | //function : Constructor |
a6eb515f |
190 | //purpose : Three points dimension |
7fd59977 |
191 | //======================================================================= |
192 | |
a6eb515f |
193 | AIS_AngleDimension::AIS_AngleDimension (const gp_Pnt& theFirstPoint, |
194 | const gp_Pnt& theSecondPoint, |
195 | const gp_Pnt& theThirdPoint) |
196 | : AIS_Dimension(), |
197 | myIsFlyoutLines (Standard_True), |
198 | myFlyout (15.0) |
7fd59977 |
199 | { |
a6eb515f |
200 | init(); |
201 | myIsInitialized = Standard_True; |
202 | SetKindOfDimension (AIS_KOD_PLANEANGLE); |
203 | myFirstPoint = theFirstPoint; |
204 | myCenter = theSecondPoint; |
205 | mySecondPoint = theThirdPoint; |
206 | myShapesNumber = 3; |
7fd59977 |
207 | } |
208 | |
209 | //======================================================================= |
210 | //function : Constructor |
a6eb515f |
211 | //purpose : Three points dimension |
7fd59977 |
212 | //======================================================================= |
213 | |
a6eb515f |
214 | AIS_AngleDimension::AIS_AngleDimension (const gp_Pnt& theFirstPoint, |
215 | const gp_Pnt& theSecondPoint, |
216 | const gp_Pnt& theThirdPoint, |
217 | const Handle(Prs3d_DimensionAspect)& theDimensionAspect, |
218 | const Standard_Real theExtensionSize) |
219 | : AIS_Dimension (theDimensionAspect,theExtensionSize), |
220 | myIsFlyoutLines (Standard_True), |
221 | myFlyout (15.0) |
7fd59977 |
222 | { |
a6eb515f |
223 | myIsInitialized = Standard_True; |
224 | SetKindOfDimension (AIS_KOD_PLANEANGLE); |
225 | myFirstPoint = theFirstPoint; |
226 | myCenter = theSecondPoint; |
227 | mySecondPoint = theThirdPoint; |
228 | myShapesNumber =3; |
7fd59977 |
229 | } |
230 | |
7fd59977 |
231 | //======================================================================= |
a6eb515f |
232 | //function : Constructor |
233 | //purpose : Cone dimension |
7fd59977 |
234 | //======================================================================= |
235 | |
a6eb515f |
236 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theCone) |
237 | : AIS_Dimension(), |
238 | myIsFlyoutLines (Standard_True), |
239 | myFlyout (15.0) |
7fd59977 |
240 | { |
a6eb515f |
241 | init(); |
242 | myIsInitialized = Standard_False; |
243 | SetKindOfDimension (AIS_KOD_PLANEANGLE); |
244 | myFirstShape = theCone; |
245 | myShapesNumber = 1; |
7fd59977 |
246 | } |
247 | |
248 | //======================================================================= |
a6eb515f |
249 | //function : Constructor |
250 | //purpose : Two faces dimension |
7fd59977 |
251 | //======================================================================= |
252 | |
a6eb515f |
253 | AIS_AngleDimension::AIS_AngleDimension (const TopoDS_Face& theFirstFace, |
254 | const TopoDS_Face& theSecondFace, |
255 | const gp_Ax1& theAxis) |
256 | : AIS_Dimension(), |
257 | myIsFlyoutLines (Standard_True), |
258 | myFlyout (15.0) |
7fd59977 |
259 | { |
a6eb515f |
260 | init(); |
261 | myIsInitialized = Standard_False; |
262 | SetKindOfDimension (AIS_KOD_PLANEANGLE); |
263 | myFirstShape = theFirstFace; |
264 | mySecondShape = theSecondFace; |
265 | myShapesNumber = 2; |
266 | gp_Pln aPlane; |
267 | aPlane.SetAxis (theAxis); |
268 | SetWorkingPlane (aPlane); |
7fd59977 |
269 | } |
270 | |
7fd59977 |
271 | //======================================================================= |
a6eb515f |
272 | //function : SetFirstShape |
7fd59977 |
273 | //purpose : |
274 | //======================================================================= |
275 | |
a6eb515f |
276 | void AIS_AngleDimension::SetFirstShape (const TopoDS_Shape& theShape, |
277 | const Standard_Boolean isSingleShape /*= Standard_False*/) |
7fd59977 |
278 | { |
a6eb515f |
279 | AIS_Dimension::SetFirstShape (theShape); |
280 | if (isSingleShape) |
281 | myShapesNumber = 1; |
7fd59977 |
282 | } |
283 | |
7fd59977 |
284 | //======================================================================= |
a6eb515f |
285 | //function : aboveInBelowCone |
286 | //purpose : Returns 1 if <theC> center is above of <theCMin> center; |
287 | // 0 if <theC> center is between <theCMin> and |
288 | // <theCMax> centers; |
289 | // -1 if <theC> center is below <theCMax> center. |
7fd59977 |
290 | //======================================================================= |
291 | |
a6eb515f |
292 | Standard_Integer AIS_AngleDimension::aboveInBelowCone (const gp_Circ &theCMax, |
293 | const gp_Circ &theCMin, |
294 | const gp_Circ &theC) |
7fd59977 |
295 | { |
a6eb515f |
296 | const Standard_Real aD = theCMax.Location().Distance (theCMin.Location()); |
297 | const Standard_Real aD1 = theCMax.Location().Distance (theC.Location()); |
298 | const Standard_Real aD2 = theCMin.Location().Distance (theC.Location()); |
299 | |
300 | if (aD >= aD1 && aD >= aD2) return 0; |
301 | if (aD < aD2 && aD1 < aD2) return -1; |
302 | if (aD < aD1 && aD2 < aD1) return 1; |
303 | return 0; |
7fd59977 |
304 | } |
305 | |
306 | //======================================================================= |
a6eb515f |
307 | //function : initConeAngle |
308 | //purpose : initialization of the cone angle |
7fd59977 |
309 | //======================================================================= |
310 | |
a6eb515f |
311 | Standard_Boolean AIS_AngleDimension::initConeAngle (const TopoDS_Face& theCone) |
7fd59977 |
312 | { |
a6eb515f |
313 | if (theCone.IsNull ()) |
314 | return Standard_False; |
7fd59977 |
315 | |
a6eb515f |
316 | gp_Pln aPln; |
317 | gp_Cone aCone; |
318 | gp_Circ aCircle; |
319 | // A surface from the Face |
320 | Handle(Geom_Surface) aSurf; |
321 | Handle(Geom_OffsetSurface) aOffsetSurf; |
322 | Handle(Geom_ConicalSurface) aConicalSurf; |
323 | Handle(Geom_SurfaceOfRevolution) aRevSurf; |
324 | Handle(Geom_Line) aLine; |
325 | BRepAdaptor_Surface aConeAdaptor (theCone); |
326 | TopoDS_Face aFace; |
327 | AIS_KindOfSurface aSurfType; |
328 | Standard_Real anOffset = 0.; |
329 | Handle(Standard_Type) aType; |
7fd59977 |
330 | |
a6eb515f |
331 | Standard_Real aMaxV = aConeAdaptor.FirstVParameter(); |
332 | Standard_Real aMinV = aConeAdaptor.LastVParameter(); |
7fd59977 |
333 | |
a6eb515f |
334 | AIS::GetPlaneFromFace(theCone, aPln, aSurf, aSurfType, anOffset); |
7fd59977 |
335 | |
a6eb515f |
336 | if (aSurfType == AIS_KOS_Revolution) |
337 | { |
338 | // Surface of revolution |
339 | aRevSurf = Handle(Geom_SurfaceOfRevolution)::DownCast(aSurf); |
340 | gp_Lin aLin (aRevSurf->Axis()); |
341 | Handle(Geom_Curve) aBasisCurve = aRevSurf->BasisCurve(); |
342 | //Must be a part of line (basis curve should be linear) |
343 | if (aBasisCurve ->DynamicType() != STANDARD_TYPE(Geom_Line)) |
344 | return Standard_False; |
345 | |
346 | gp_Pnt aFirst1 = aConeAdaptor.Value (0., aMinV); |
347 | gp_Pnt aLast1 = aConeAdaptor.Value (0., aMaxV); |
348 | gp_Vec aVec1 (aFirst1, aLast1); |
349 | |
350 | //Projection <aFirst> on <aLin> |
351 | gp_Pnt aFirst2 = ElCLib::Value (ElCLib::Parameter (aLin, aFirst1), aLin); |
352 | // Projection <aLast> on <aLin> |
353 | gp_Pnt aLast2 = ElCLib::Value (ElCLib::Parameter (aLin, aLast1), aLin); |
354 | |
355 | gp_Vec aVec2 (aFirst2, aLast2); |
356 | |
357 | // Check if two parts of revolution are parallel (it's a cylinder) or normal (it's a circle). |
358 | if (aVec1.IsParallel (aVec2, Precision::Angular()) |
359 | || aVec1.IsNormal (aVec2,Precision::Angular())) |
360 | return Standard_False; |
361 | |
362 | gce_MakeCone aMkCone (aRevSurf->Axis(), aFirst1, aLast1); |
363 | aCone = aMkCone.Value(); |
364 | myCenter = aCone.Apex(); |
365 | } |
366 | else |
367 | { |
368 | aType = aSurf->DynamicType(); |
369 | if (aType == STANDARD_TYPE(Geom_OffsetSurface) || anOffset > 0.01) |
7fd59977 |
370 | { |
a6eb515f |
371 | // Offset surface |
372 | aOffsetSurf = new Geom_OffsetSurface (aSurf, anOffset); |
373 | aSurf = aOffsetSurf->Surface(); |
374 | BRepBuilderAPI_MakeFace aMkFace(aSurf, Precision::Confusion()); |
375 | aMkFace.Build(); |
376 | if (!aMkFace.IsDone()) |
377 | return Standard_False; |
378 | aConeAdaptor.Initialize (aMkFace.Face()); |
7fd59977 |
379 | } |
a6eb515f |
380 | aCone = aConeAdaptor.Cone(); |
381 | aConicalSurf = Handle(Geom_ConicalSurface)::DownCast (aSurf); |
382 | myCenter = aConicalSurf->Apex(); |
7fd59977 |
383 | } |
7fd59977 |
384 | |
a6eb515f |
385 | // A circle where the angle is drawn |
386 | Handle(Geom_Curve) aCurve; |
387 | Standard_Real aMidV = ( aMinV + aMaxV ) / 2.5; |
388 | aCurve = aSurf->VIso (aMidV); |
389 | aCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ(); |
7fd59977 |
390 | |
a6eb515f |
391 | aCurve = aSurf->VIso(aMaxV); |
392 | gp_Circ aCircVmax = Handle(Geom_Circle)::DownCast(aCurve)->Circ(); |
393 | aCurve = aSurf->VIso(aMinV); |
394 | gp_Circ aCircVmin = Handle(Geom_Circle)::DownCast(aCurve)->Circ(); |
7fd59977 |
395 | |
7fd59977 |
396 | |
a6eb515f |
397 | if (aCircVmax.Radius() < aCircVmin.Radius()) |
398 | { |
399 | gp_Circ aTmpCirc = aCircVmax; |
400 | aCircVmax = aCircVmin; |
401 | aCircVmin = aTmpCirc; |
402 | } |
7fd59977 |
403 | |
a6eb515f |
404 | myFirstPoint = ElCLib::Value (0, aCircle); |
405 | mySecondPoint = ElCLib::Value (M_PI, aCircle); |
406 | return Standard_True; |
7fd59977 |
407 | } |
408 | |
409 | //======================================================================= |
a6eb515f |
410 | //function : initTwoFacesAngle |
411 | //purpose : initialization of angle dimension between two faces |
7fd59977 |
412 | //======================================================================= |
413 | |
a6eb515f |
414 | Standard_Boolean AIS_AngleDimension::initTwoFacesAngle () |
7fd59977 |
415 | { |
a6eb515f |
416 | TopoDS_Face aFirstFace = TopoDS::Face (myFirstShape); |
417 | TopoDS_Face aSecondFace = TopoDS::Face (mySecondShape); |
418 | gp_Dir aFirstDir, aSecondDir; |
419 | gp_Pln aFirstPlane, aSecondPlane; |
420 | Handle(Geom_Surface) aFirstBasisSurf, aSecondBasisSurf; |
421 | AIS_KindOfSurface aFirstSurfType, aSecondSurfType; |
422 | Standard_Real aFirstOffset, aSecondOffset; |
7fd59977 |
423 | |
a6eb515f |
424 | AIS::GetPlaneFromFace (aFirstFace, aFirstPlane, |
425 | aFirstBasisSurf,aFirstSurfType,aFirstOffset); |
426 | AIS::GetPlaneFromFace (aSecondFace, aSecondPlane, |
427 | aSecondBasisSurf, aSecondSurfType, aSecondOffset); |
428 | |
429 | if (aFirstSurfType == AIS_KOS_Plane) |
430 | { |
431 | //Planar faces angle |
432 | AIS::ComputeAngleBetweenPlanarFaces (aFirstFace, |
433 | aSecondFace, |
434 | aSecondBasisSurf, |
435 | GetWorkingPlane().Axis(), |
436 | myValue, |
437 | Standard_True, |
438 | myGeom.myTextPosition, |
439 | myCenter, |
440 | myFirstPoint, |
441 | mySecondPoint, |
442 | aFirstDir, |
443 | aSecondDir); |
7fd59977 |
444 | } |
a6eb515f |
445 | else |
446 | { |
447 | // Curvilinear faces angle |
448 | Handle(Geom_Plane) aPlane = new Geom_Plane (GetWorkingPlane()); |
449 | AIS::ComputeAngleBetweenCurvilinearFaces (aFirstFace, |
450 | aSecondFace, |
451 | aFirstBasisSurf, |
452 | aSecondBasisSurf, |
453 | aFirstSurfType, |
454 | aSecondSurfType, |
455 | GetWorkingPlane().Axis(), |
456 | myValue, |
457 | Standard_True, |
458 | myGeom.myTextPosition, |
459 | myCenter, |
460 | myFirstPoint, |
461 | mySecondPoint, |
462 | aFirstDir, |
463 | aSecondDir, |
464 | aPlane); |
465 | SetWorkingPlane (aPlane->Pln()); |
7fd59977 |
466 | } |
a6eb515f |
467 | return Standard_True; |
7fd59977 |
468 | } |
469 | |
7fd59977 |
470 | //======================================================================= |
a6eb515f |
471 | //function : SetFlyout |
7fd59977 |
472 | //purpose : |
473 | //======================================================================= |
474 | |
a6eb515f |
475 | void AIS_AngleDimension::SetFlyout (const Standard_Real theFlyout) |
7fd59977 |
476 | { |
a6eb515f |
477 | myFlyout = theFlyout; |
7fd59977 |
478 | } |
479 | |
480 | //======================================================================= |
a6eb515f |
481 | //function : GetFlyout |
7fd59977 |
482 | //purpose : |
483 | //======================================================================= |
484 | |
a6eb515f |
485 | Standard_Real AIS_AngleDimension::GetFlyout () const |
7fd59977 |
486 | { |
a6eb515f |
487 | return myFlyout; |
7fd59977 |
488 | } |
489 | |
490 | //======================================================================= |
a6eb515f |
491 | //function : countDefaultPlane |
7fd59977 |
492 | //purpose : |
493 | //======================================================================= |
494 | |
a6eb515f |
495 | void AIS_AngleDimension::countDefaultPlane () |
7fd59977 |
496 | { |
a6eb515f |
497 | if (!myIsInitialized) |
498 | return; |
499 | // Compute normal of the default plane. |
500 | gp_Vec aVec1(myCenter, myFirstPoint), |
501 | aVec2(myCenter, mySecondPoint); |
502 | myDefaultPlane = gp_Pln(myCenter, aVec1^aVec2); |
503 | // Set computed value to <myWorkingPlane> |
504 | ResetWorkingPlane (); |
7fd59977 |
505 | } |
506 | |
507 | //======================================================================= |
a6eb515f |
508 | //function : computeValue |
7fd59977 |
509 | //purpose : |
510 | //======================================================================= |
511 | |
a6eb515f |
512 | void AIS_AngleDimension::computeValue () |
7fd59977 |
513 | { |
a6eb515f |
514 | gp_Vec aVec1 (myCenter, myFirstPoint), |
515 | aVec2 (myCenter, mySecondPoint); |
516 | myValue = aVec1.Angle (aVec2); |
517 | // To model units |
518 | AIS_Dimension::computeValue(); |
7fd59977 |
519 | } |
520 | |
7fd59977 |
521 | //======================================================================= |
a6eb515f |
522 | //function : initTwoEdgesAngle |
523 | //purpose : Fill gp_Pnt fields for further presentation computation |
524 | // If intersection between two edges doesn't exist |
525 | // <myIsInitialized> is set to false |
7fd59977 |
526 | //======================================================================= |
527 | |
a6eb515f |
528 | Standard_Boolean AIS_AngleDimension::initTwoEdgesAngle () |
7fd59977 |
529 | { |
a6eb515f |
530 | // Data initialization |
531 | TopoDS_Edge aFirstEdge = TopoDS::Edge (myFirstShape); |
532 | TopoDS_Edge aSecondEdge = TopoDS::Edge (mySecondShape); |
533 | BRepAdaptor_Curve aMakeFirstLine (aFirstEdge); |
534 | BRepAdaptor_Curve aMakeSecondLine (aSecondEdge); |
7fd59977 |
535 | |
a6eb515f |
536 | if (aMakeFirstLine.GetType() != GeomAbs_Line || aMakeSecondLine.GetType() != GeomAbs_Line) |
537 | { |
538 | return Standard_False; |
7fd59977 |
539 | } |
540 | |
a6eb515f |
541 | Handle(Geom_Line) aFirstLine = new Geom_Line (aMakeFirstLine.Line()); |
542 | Handle(Geom_Line) aSecondLine = new Geom_Line (aMakeSecondLine.Line()); |
7fd59977 |
543 | |
a6eb515f |
544 | gp_Lin aFirstLin = aFirstLine->Lin (); |
545 | gp_Lin aSecondLin = aSecondLine->Lin (); |
546 | gp_Lin2d aFirstLin2d, aSecondLin2d; |
547 | Standard_Boolean isParallelLines = aFirstLin.Direction().IsParallel (aSecondLin.Direction(), Precision::Angular()); |
548 | Standard_Boolean isSameLines = isParallelLines && aFirstLin.Distance (aSecondLin.Location()) <= Precision::Confusion(); |
549 | // In case where we can't compute plane automatically |
550 | if ((isParallelLines || isSameLines) && !myIsWorkingPlaneCustom) |
551 | { |
552 | return Standard_False; |
7fd59977 |
553 | } |
554 | |
a6eb515f |
555 | gp_Pln aPlane; |
7fd59977 |
556 | |
a6eb515f |
557 | /// PART 1 is for automatic plane computation from two edges if it is possible |
558 | // Build plane |
559 | if (!myIsWorkingPlaneCustom) |
560 | { |
561 | gp_Pnt aPoint = aFirstLine->Value (0.); |
562 | gp_Dir aNormal = isParallelLines |
563 | ? gp_Vec(aSecondLin.Normal (aPoint).Direction()) ^ gp_Vec (aSecondLin.Direction()) |
564 | : gp_Vec (aFirstLin.Direction()) ^ gp_Vec (aSecondLin.Direction()); |
565 | aPlane = gp_Pln (aPoint, aNormal); |
566 | resetWorkingPlane (aPlane); |
7fd59977 |
567 | } |
a6eb515f |
568 | else |
569 | { |
570 | aPlane = GetWorkingPlane(); |
7fd59977 |
571 | } |
572 | |
a6eb515f |
573 | // Compute geometry for this plane and edges |
574 | Standard_Boolean isInfinite1,isInfinite2; |
575 | gp_Pnt aFirstPoint1, aLastPoint1, aFirstPoint2, aLastPoint2; |
576 | Standard_Integer anExtIndex = -1; |
577 | Handle(Geom_Curve) anExtCurve; |
578 | Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane); |
579 | if (!AIS::ComputeGeometry (aFirstEdge, aSecondEdge, |
580 | anExtIndex, |
581 | aFirstLine, aSecondLine, |
582 | aFirstPoint1, aLastPoint1, |
583 | aFirstPoint2, aLastPoint2, |
584 | anExtCurve, |
585 | isInfinite1, isInfinite2, |
586 | aGeomPlane)) |
587 | { |
588 | return Standard_False; |
7fd59977 |
589 | } |
590 | |
a6eb515f |
591 | // Check if both edges are on this plane |
592 | if (!anExtCurve.IsNull()) |
593 | { |
594 | if (anExtIndex == 1) // First curve is out of the plane |
595 | { |
596 | // Project curve on the plane |
597 | if (myIsWorkingPlaneCustom) |
598 | { |
599 | aFirstLin2d = ProjLib::Project (aPlane, aFirstLin); |
600 | aFirstLin = ElCLib::To3d (aPlane.Position().Ax2(), aFirstLin2d); |
7fd59977 |
601 | } |
a6eb515f |
602 | else |
603 | { |
604 | aFirstLin.Translate (gp_Vec (aFirstLin.Location(), aSecondLin.Location())); |
7fd59977 |
605 | } |
7fd59977 |
606 | |
a6eb515f |
607 | aFirstLine = new Geom_Line (aFirstLin); |
7fd59977 |
608 | } |
a6eb515f |
609 | else if (anExtIndex == 2) // Second curve is out of the plane |
610 | { |
611 | if (myIsWorkingPlaneCustom) |
612 | { |
613 | aSecondLin2d = ProjLib::Project (aPlane, aSecondLin); |
614 | aSecondLin = ElCLib::To3d (aPlane.Position().Ax2(), aSecondLin2d); |
7fd59977 |
615 | } |
a6eb515f |
616 | else |
617 | { |
618 | aSecondLin.Translate (gp_Vec (aSecondLin.Location(), aFirstLin.Location())); |
7fd59977 |
619 | } |
a6eb515f |
620 | |
621 | aSecondLine = new Geom_Line (aSecondLin); |
7fd59977 |
622 | } |
623 | } |
624 | |
a6eb515f |
625 | /// PART 2 is for dimension computation using the working plane |
7fd59977 |
626 | |
a6eb515f |
627 | if (aFirstLin.Direction ().IsParallel (aSecondLin.Direction (), Precision::Angular ())) |
628 | { |
629 | // Parallel lines |
630 | isSameLines = aFirstLin.Distance(aSecondLin.Location()) <= Precision::Confusion(); |
631 | if (!isSameLines) |
632 | return Standard_False; |
633 | |
634 | myFirstPoint = aFirstLin.Location(); |
635 | mySecondPoint = ElCLib::Value (ElCLib::Parameter (aFirstLin, myFirstPoint), aSecondLin); |
636 | if (mySecondPoint.Distance (mySecondPoint) <= Precision::Confusion ()) |
637 | mySecondPoint.Translate (gp_Vec (aSecondLin.Direction ())*Abs(GetFlyout())); |
638 | myCenter.SetXYZ( (myFirstPoint.XYZ() + mySecondPoint.XYZ()) / 2. ); |
639 | } |
640 | else |
641 | { |
642 | // Find intersection |
643 | aFirstLin2d = ProjLib::Project (aPlane, aFirstLin); |
644 | aSecondLin2d = ProjLib::Project (aPlane, aSecondLin); |
7fd59977 |
645 | |
a6eb515f |
646 | IntAna2d_AnaIntersection anInt2d (aFirstLin2d, aSecondLin2d); |
647 | gp_Pnt2d anIntersectPoint; |
648 | if (!anInt2d.IsDone() || anInt2d.IsEmpty()) |
7fd59977 |
649 | { |
a6eb515f |
650 | return Standard_False; |
7fd59977 |
651 | } |
652 | |
a6eb515f |
653 | anIntersectPoint = gp_Pnt2d (anInt2d.Point(1).Value()); |
654 | myCenter = ElCLib::To3d(aPlane.Position().Ax2(), anIntersectPoint); |
7fd59977 |
655 | |
a6eb515f |
656 | if (isInfinite1 || isInfinite2) |
7fd59977 |
657 | { |
a6eb515f |
658 | myFirstPoint = myCenter.Translated (gp_Vec (aFirstLin.Direction())*Abs (GetFlyout())); |
659 | mySecondPoint = myCenter.Translated (gp_Vec (aSecondLin.Direction())*Abs (GetFlyout())); |
660 | return Standard_True; |
7fd59977 |
661 | } |
662 | |
a6eb515f |
663 | // | |
664 | // | <- dimension should be here |
665 | // *---- |
666 | myFirstPoint = myCenter.Distance (aFirstPoint1) > myCenter.Distance (aLastPoint1) ? aFirstPoint1 : aLastPoint1; |
667 | mySecondPoint = myCenter.Distance (aFirstPoint2) > myCenter.Distance (aLastPoint2) ? aFirstPoint2 : aLastPoint2; |
668 | } |
669 | return Standard_True; |
7fd59977 |
670 | } |
671 | |
672 | //======================================================================= |
a6eb515f |
673 | //function : canTextBeInCenter |
674 | //purpose : Auxiliary method to arrange text and arrows |
7fd59977 |
675 | //======================================================================= |
676 | |
a6eb515f |
677 | Standard_Boolean AIS_AngleDimension::canTextBeInCenter (const gp_Pnt& theFirstAttach, |
678 | const gp_Pnt& theSecondAttach, |
679 | const Quantity_Length& theTextLength, |
680 | const Quantity_Length& theArrowLength) |
7fd59977 |
681 | { |
a6eb515f |
682 | gp_Vec anAttachVector (theFirstAttach, theSecondAttach); |
683 | Standard_Real aValue = anAttachVector.Magnitude(); |
684 | return (aValue < theTextLength + 2.*theArrowLength) ? Standard_False : Standard_True; |
685 | } |
7fd59977 |
686 | |
a6eb515f |
687 | //======================================================================= |
688 | //function: getCenterOnArc |
689 | //purpose : |
690 | //======================================================================= |
691 | gp_Pnt AIS_AngleDimension::getCenterOnArc (const gp_Pnt& theFirstAttach, |
692 | const gp_Pnt& theSecondAttach) |
693 | { |
694 | gp_Pnt2d aCenter2d = ProjLib::Project (GetWorkingPlane(), myCenter), |
695 | aFirstAttach2d = ProjLib::Project (GetWorkingPlane(), theFirstAttach), |
696 | aSecondAttach2d = ProjLib::Project (GetWorkingPlane(), theSecondAttach); |
697 | gp_Lin2d anAttachLine2d = gce_MakeLin2d (aFirstAttach2d, aSecondAttach2d); |
698 | |
699 | // Getting text center |
700 | gp_Pnt2d aTextCenterPnt = ElCLib::Value ((ElCLib::Parameter (anAttachLine2d, aFirstAttach2d) + ElCLib::Parameter (anAttachLine2d, aSecondAttach2d)) / 2., anAttachLine2d); |
701 | gp_Lin2d aCenterToTextCenterLin = gce_MakeLin2d (aCenter2d, aTextCenterPnt); |
702 | |
703 | // Drawing circle |
704 | Standard_Real aRadius = theFirstAttach.Distance (myCenter); |
705 | gp_Circ2d aCircle (gp_Ax22d (aCenter2d, gp_Dir2d (1, 0)), aRadius); |
706 | |
707 | // Getting text position in the center of arc |
708 | IntAna2d_AnaIntersection anInt2d (aCenterToTextCenterLin, aCircle); |
709 | gp_Pnt2d aTextCenterOnArc2d; |
710 | if (anInt2d.IsDone()) |
711 | if (!anInt2d.IsEmpty()) |
712 | aTextCenterOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value()); |
713 | gp_Pnt aCenterOnArc = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextCenterOnArc2d); |
714 | return aCenterOnArc; |
7fd59977 |
715 | } |
a6eb515f |
716 | |
7fd59977 |
717 | //======================================================================= |
a6eb515f |
718 | //function: drawArcWithText |
719 | //purpose : |
7fd59977 |
720 | //======================================================================= |
721 | |
a6eb515f |
722 | void AIS_AngleDimension::drawArcWithText (const Handle(Prs3d_Presentation)& thePresentation, |
723 | const gp_Pnt& theFirstAttach, |
724 | const gp_Pnt& theSecondAttach, |
725 | const TCollection_ExtendedString& theText, |
726 | const AIS_DimensionDisplayMode theMode) |
7fd59977 |
727 | { |
a6eb515f |
728 | gp_Pnt2d aCenter2d = ProjLib::Project (GetWorkingPlane(), myCenter), |
729 | aFirstAttach2d = ProjLib::Project (GetWorkingPlane(), theFirstAttach), |
730 | aSecondAttach2d = ProjLib::Project (GetWorkingPlane(), theSecondAttach); |
731 | gp_Lin2d anAttachLine2d = gce_MakeLin2d (aFirstAttach2d, aSecondAttach2d); |
732 | |
733 | // Getting text center |
734 | gp_Pnt2d aTextCenterPnt = ElCLib::Value ((ElCLib::Parameter (anAttachLine2d, aFirstAttach2d) + ElCLib::Parameter (anAttachLine2d, aSecondAttach2d)) / 2., anAttachLine2d); |
735 | gp_Lin2d aCenterToTextCenterLin = gce_MakeLin2d (aCenter2d, aTextCenterPnt); |
736 | |
737 | // Drawing circle |
738 | Standard_Real aRadius = theFirstAttach.Distance (myCenter); |
739 | gp_Circ2d aCircle (gp_Ax22d (aCenter2d, gp_Dir2d (1, 0)), aRadius); |
740 | |
741 | // Getting text position in the center of arc |
742 | IntAna2d_AnaIntersection anInt2d (aCenterToTextCenterLin, aCircle); |
743 | gp_Pnt2d aTextCenterOnArc2d; |
744 | if (anInt2d.IsDone()) |
745 | if (!anInt2d.IsEmpty()) |
746 | aTextCenterOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value()); |
747 | myGeom.myTextPosition = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextCenterOnArc2d); |
748 | |
749 | // Drawing text |
750 | gp_Vec aVec (theFirstAttach, theSecondAttach); |
751 | Standard_Real aTextWidth = drawText (thePresentation, |
752 | myIsTextReversed ? aVec.Reversed() : aVec, |
753 | theText,theMode); |
754 | |
755 | // Getting text begin and end points |
756 | gp_Pnt2d aTextBeginPnt = ElCLib::Value ((ElCLib::Parameter (anAttachLine2d, aFirstAttach2d) + |
757 | ElCLib::Parameter (anAttachLine2d, aSecondAttach2d) - |
758 | aTextWidth) / 2., anAttachLine2d), |
759 | aTextEndPnt = ElCLib::Value (ElCLib::Parameter (anAttachLine2d,aTextBeginPnt) + aTextWidth, anAttachLine2d); |
760 | |
761 | |
762 | gp_Lin2d aCenterToTextBeginLin = gce_MakeLin2d (aCenter2d, aTextBeginPnt), |
763 | aCenterToTextEndLin = gce_MakeLin2d (aCenter2d, aTextEndPnt); |
764 | |
765 | // Text begin and end on the dimension arc |
766 | gp_Pnt2d aTextBeginOnArc2d, aTextEndOnArc2d; |
767 | anInt2d.Perform (aCenterToTextBeginLin, aCircle); |
768 | if (anInt2d.IsDone()) |
769 | if (!anInt2d.IsEmpty()) |
770 | aTextBeginOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value()); |
771 | |
772 | anInt2d.Perform (aCenterToTextEndLin, aCircle); |
773 | if (anInt2d.IsDone()) |
774 | if (!anInt2d.IsEmpty()) |
775 | aTextEndOnArc2d = gp_Pnt2d (anInt2d.Point (1).Value()); |
776 | |
777 | gp_Pnt aTextBeginOnArc = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextBeginOnArc2d); |
778 | gp_Pnt aTextEndOnArc = ElCLib::To3d (GetWorkingPlane().Position().Ax2(), aTextEndOnArc2d); |
779 | |
780 | // Drawing arcs |
781 | if (theMode != AIS_DDM_Text) |
782 | { |
783 | drawArc (thePresentation, theFirstAttach, aTextBeginOnArc, myCenter, aRadius, theMode); |
784 | drawArc (thePresentation, aTextEndOnArc, theSecondAttach, myCenter, aRadius, theMode); |
7fd59977 |
785 | } |
7fd59977 |
786 | |
a6eb515f |
787 | } |
7fd59977 |
788 | |
a6eb515f |
789 | //======================================================================= |
790 | //function : drawArc |
791 | //purpose : draws the arc between two attach points |
792 | //======================================================================= |
7fd59977 |
793 | |
a6eb515f |
794 | void AIS_AngleDimension::drawArc (const Handle(Prs3d_Presentation)& thePresentation, |
795 | const gp_Pnt& theFirstAttach, |
796 | const gp_Pnt& theSecondAttach, |
797 | const gp_Pnt& theCenter, |
798 | const Standard_Real theRadius, |
799 | const AIS_DimensionDisplayMode theMode) |
800 | { |
801 | Handle(SelectMgr_EntityOwner) anEmptyOwner; |
802 | Prs3d_Root::CurrentGroup (thePresentation)-> |
803 | SetPrimitivesAspect(myDrawer->DimensionAspect()->LineAspect()->Aspect()); |
804 | |
805 | gp_Vec aCenterToFirstVec (theCenter,theFirstAttach); |
806 | gp_Vec aCenterToSecondVec (theCenter,theSecondAttach); |
807 | gp_Dir aCenterToFirstDir (aCenterToFirstVec); |
808 | gp_Dir aPlaneNormal = GetWorkingPlane().Axis().Direction(); |
809 | gp_Dir aCenterToSecondDir = aPlaneNormal.Crossed (aCenterToFirstDir); |
810 | |
811 | const Standard_Real anAngle = aCenterToFirstVec.Angle(aCenterToSecondVec); |
812 | const Standard_Integer aPointsOnArc = Max (4 , Standard_Integer (50. * anAngle / M_PI)); |
813 | const Standard_Real anAngleStep = anAngle / (aPointsOnArc - 1); |
814 | TColgp_Array1OfPnt aPointArray (0,aPointsOnArc-1); |
815 | Handle(Graphic3d_ArrayOfPolylines) aPrimSegments = new Graphic3d_ArrayOfPolylines (aPointsOnArc,2); |
816 | aPrimSegments->AddVertex (theFirstAttach); |
817 | aPointArray.SetValue(0, theFirstAttach); |
818 | gp_Pnt aPoint = theFirstAttach; |
819 | gp_Vec aVector; |
820 | |
821 | for (Standard_Integer anI = 1; anI < aPointsOnArc - 1; ++anI) |
822 | { |
823 | aVector = (gp_Vec(aCenterToFirstDir) * Cos ( (anI - 1) * anAngleStep) + gp_Vec(aCenterToSecondDir) * Sin ( (anI - 1) * anAngleStep)) * theRadius; |
824 | aPoint = theCenter.Translated(aVector); |
825 | aPrimSegments->AddVertex(aPoint); |
826 | aPointArray.SetValue (anI,aPoint); |
7fd59977 |
827 | } |
a6eb515f |
828 | aPrimSegments->AddVertex (theSecondAttach); |
829 | aPointArray.SetValue (aPointsOnArc - 1,theSecondAttach); |
7fd59977 |
830 | |
a6eb515f |
831 | // Fill sensitive list |
832 | myGeom.mySensitiveSegments.Append(new Select3D_SensitiveCurve(anEmptyOwner,aPointArray)); |
7fd59977 |
833 | |
a6eb515f |
834 | // Fill display presentation |
835 | if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All) |
836 | { |
837 | Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True); |
7fd59977 |
838 | } |
a6eb515f |
839 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments); |
840 | if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All) |
841 | { |
842 | Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False); |
7fd59977 |
843 | } |
844 | } |
845 | |
7fd59977 |
846 | //======================================================================= |
a6eb515f |
847 | //function : Compute |
848 | //purpose : Having three gp_Pnt points compute presentation |
7fd59977 |
849 | //======================================================================= |
7fd59977 |
850 | |
a6eb515f |
851 | void AIS_AngleDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/, |
852 | const Handle(Prs3d_Presentation)& thePresentation, |
853 | const Standard_Integer theMode) |
854 | { |
855 | thePresentation->Clear(); |
856 | myGeom.mySensitiveSegments.Clear(); |
857 | Handle(SelectMgr_EntityOwner) anEmptyOwner; |
7fd59977 |
858 | |
a6eb515f |
859 | if (!myIsInitialized) |
860 | { |
861 | if (myShapesNumber == 1) |
862 | { |
863 | myIsInitialized = initConeAngle (TopoDS::Face (myFirstShape)); |
864 | } |
865 | else if (myShapesNumber == 2) |
866 | { |
867 | switch (myFirstShape.ShapeType()) |
868 | { |
869 | case TopAbs_FACE: |
870 | { |
871 | myIsInitialized = initTwoFacesAngle (); |
872 | } |
873 | break; |
874 | case TopAbs_EDGE: |
875 | { |
876 | myIsInitialized = initTwoEdgesAngle (); |
877 | } |
878 | break; |
879 | default: |
880 | return; |
881 | } |
882 | } |
883 | else |
884 | return; |
7fd59977 |
885 | } |
886 | |
a6eb515f |
887 | // If initialization failed |
888 | if (!myIsInitialized) |
889 | return; |
7fd59977 |
890 | |
a6eb515f |
891 | // Parameters for presentation |
892 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
893 | Prs3d_Root::CurrentGroup(thePresentation)-> |
894 | SetPrimitivesAspect(aDimensionAspect->LineAspect()->Aspect()); |
895 | Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length(); |
896 | if (!myIsValueCustom) |
897 | computeValue (); |
898 | TCollection_ExtendedString aValueString; |
899 | Standard_Real aTextLength; |
900 | getTextWidthAndString (aTextLength, aValueString); |
901 | if (!myIsWorkingPlaneCustom) |
902 | countDefaultPlane(); |
903 | gp_Pnt aFirstAttach = myCenter.Translated (gp_Vec(myCenter, myFirstPoint).Normalized() * GetFlyout()); |
904 | gp_Pnt aSecondAttach = myCenter.Translated (gp_Vec(myCenter, mySecondPoint).Normalized() * GetFlyout()); |
905 | // Attach points and radius |
906 | if (aDimensionAspect->HorizontalTextAlignment () == Prs3d_HTA_Center) |
907 | { |
908 | aDimensionAspect->SetArrowOrientation (Prs3d_DAO_Internal); |
7fd59977 |
909 | |
a6eb515f |
910 | if (!canTextBeInCenter (aFirstAttach, aSecondAttach, aTextLength, anArrowLength)) |
911 | { |
912 | aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External); |
913 | aDimensionAspect->SetHorizontalTextAlignment (Prs3d_HTA_Left); |
914 | } |
7fd59977 |
915 | } |
a6eb515f |
916 | else |
917 | aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External); |
7fd59977 |
918 | |
a6eb515f |
919 | //Arrows positions and directions |
920 | gp_Vec aFirstArrowVec = (gp_Vec(myCenter, aFirstAttach)^gp_Vec(GetWorkingPlane().Axis().Direction())).Normalized().Reversed()*anArrowLength; |
921 | gp_Vec aSecondArrowVec = (gp_Vec(myCenter, aSecondAttach)^gp_Vec(GetWorkingPlane().Axis().Direction())).Normalized()*anArrowLength; |
7fd59977 |
922 | |
a6eb515f |
923 | gp_Pnt aFirstArrowBegin, |
924 | aFirstArrowEnd, |
925 | aSecondArrowBegin, |
926 | aSecondArrowEnd; |
7fd59977 |
927 | |
a6eb515f |
928 | if (aDimensionAspect->GetArrowOrientation() == Prs3d_DAO_External) |
929 | { |
930 | aFirstArrowVec.Reverse(); |
931 | aSecondArrowVec.Reverse(); |
7fd59977 |
932 | |
a6eb515f |
933 | aFirstArrowBegin = aFirstAttach.Translated (aFirstArrowVec); |
934 | aFirstArrowEnd = aFirstAttach; |
935 | aSecondArrowBegin = aSecondAttach; |
936 | aSecondArrowEnd = aSecondAttach.Translated (aSecondArrowVec); |
7fd59977 |
937 | } |
a6eb515f |
938 | else |
939 | { |
940 | aFirstArrowBegin = aFirstAttach; |
941 | aFirstArrowEnd = aFirstAttach.Translated (aFirstArrowVec); |
942 | aSecondArrowBegin = aSecondAttach.Translated (aSecondArrowVec); |
943 | aSecondArrowEnd = aSecondAttach; |
7fd59977 |
944 | } |
b8ddfc2f |
945 | |
a6eb515f |
946 | // Fill presentation |
947 | Handle(Graphic3d_ArrayOfSegments) aPrimSegments; |
948 | Standard_Boolean isTextInCenter = aDimensionAspect->VerticalTextAlignment() == Prs3d_VTA_Center; |
949 | if (aDimensionAspect->HorizontalTextAlignment() == Prs3d_HTA_Center) |
b8ddfc2f |
950 | { |
a6eb515f |
951 | // Important! Current implementation doesn't draw the extensions here |
952 | aPrimSegments = new Graphic3d_ArrayOfSegments (4); |
953 | // Get text begin and end positions (text is positioned in the center between two attach points) |
954 | gp_Pnt aTextBeginOnArc, aTextEndOnArc, anArcCenter; |
955 | if (isTextInCenter && aDimensionAspect->IsText3d()) |
956 | { |
957 | drawArcWithText (thePresentation, aFirstAttach, aSecondAttach, aValueString, (AIS_DimensionDisplayMode)theMode); |
958 | } |
959 | else |
960 | { |
961 | gp_Vec aTextDir (aFirstArrowEnd, aSecondArrowBegin); |
962 | myGeom.myTextPosition = getCenterOnArc (aFirstArrowEnd, aSecondArrowBegin); |
963 | drawText (thePresentation, |
964 | myIsTextReversed ? aTextDir.Reversed() : aTextDir, |
965 | aValueString, (AIS_DimensionDisplayMode)theMode); |
966 | if (theMode != AIS_DDM_Text) |
967 | drawArc (thePresentation, aFirstArrowEnd, aSecondArrowBegin, myCenter, Abs (GetFlyout()), (AIS_DimensionDisplayMode)theMode); |
968 | } |
7fd59977 |
969 | } |
a6eb515f |
970 | else |
971 | { |
972 | // Lines for extensions |
973 | gp_Lin aLeftExtension (aFirstAttach,gp_Dir(aFirstArrowVec)); |
974 | gp_Lin aRightExtension (aSecondAttach, gp_Dir(aSecondArrowVec)); |
975 | aPrimSegments = new Graphic3d_ArrayOfSegments (6); |
976 | gp_Pnt aStartPoint; |
977 | if (aDimensionAspect->HorizontalTextAlignment() == Prs3d_HTA_Left) |
978 | { |
979 | aStartPoint = aFirstArrowBegin; |
980 | // Short extension |
981 | aPrimSegments->AddVertex (aSecondArrowEnd); |
982 | aPrimSegments->AddVertex (aSecondArrowEnd.Translated(gp_Vec(aRightExtension.Direction())*anArrowLength)); |
983 | myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment(anEmptyOwner, |
984 | aSecondArrowEnd, |
985 | aSecondArrowEnd.Translated(gp_Vec(aRightExtension.Direction())*anArrowLength))); |
986 | |
987 | // Long extension |
988 | drawExtensionWithText (thePresentation, aStartPoint, aLeftExtension, aValueString, (AIS_DimensionDisplayMode)theMode); |
989 | } |
990 | else // Prs3d_HTA_Right |
991 | { |
992 | aStartPoint = aSecondArrowEnd; |
993 | // Short extension |
994 | aPrimSegments->AddVertex (aFirstArrowBegin); |
995 | aPrimSegments->AddVertex (aFirstArrowBegin.Translated (gp_Vec (aLeftExtension.Direction()) * anArrowLength)); |
996 | myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment(anEmptyOwner, |
997 | aFirstArrowBegin, |
998 | aFirstArrowBegin.Translated (gp_Vec (aLeftExtension.Direction()) * anArrowLength))); |
999 | |
1000 | // Long extension |
1001 | drawExtensionWithText (thePresentation, aStartPoint, aRightExtension, aValueString, (AIS_DimensionDisplayMode)theMode); |
1002 | } |
7fd59977 |
1003 | |
a6eb515f |
1004 | if (theMode != AIS_DDM_Text) |
1005 | { |
1006 | // Draw main arc |
1007 | drawArc (thePresentation, aFirstArrowEnd, aSecondArrowBegin, myCenter, Abs(GetFlyout ()), (AIS_DimensionDisplayMode)theMode); |
1008 | } |
1009 | } |
7fd59977 |
1010 | |
a6eb515f |
1011 | // Draw flyout lines and arrows in new group. |
1012 | Prs3d_Root::NewGroup (thePresentation) |
1013 | ->SetPrimitivesAspect (myDrawer->DimensionAspect()->LineAspect()->Aspect()); |
1014 | if (theMode == AIS_DDM_All && myIsFlyoutLines) |
1015 | { |
1016 | aPrimSegments->AddVertex (myCenter); |
1017 | aPrimSegments->AddVertex (aFirstAttach); |
1018 | aPrimSegments->AddVertex (myCenter); |
1019 | aPrimSegments->AddVertex (aSecondAttach); |
1020 | } |
1021 | if (theMode != AIS_DDM_Text) |
b8ddfc2f |
1022 | { |
a6eb515f |
1023 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments); |
1024 | drawArrow (thePresentation, aFirstAttach, gp_Dir (aFirstArrowVec)); |
1025 | drawArrow (thePresentation, aSecondAttach, gp_Dir (aSecondArrowVec)); |
7fd59977 |
1026 | } |
1027 | |
a6eb515f |
1028 | setComputed (Standard_True); |
7fd59977 |
1029 | } |